2015-04-22 134 views
1

我想通过在折线中使用SVG路径在谷歌地图绘制贝塞尔曲线。起初我使用了一个标记,而不是类似于Curved line between two near points in google maps,这给了我后面的结果。但是,由于无法在标记下拖动地图,因此我无法使用此方法。使用谷歌地图折线绘制贝塞尔曲线

所以我切换到了折线而不是标记。现在,当我缩小时,我获得了同样的好结果,但是当我放大曲线变成“裁剪”时。

下面是代码:

function initialize() { 
    var mapOptions = { 
     mapTypeId: google.maps.MapTypeId.ROADMAP 
    }; 

    var map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions); 

    var coord1 = new google.maps.LatLng(49.165876, -123.152446); 
    var coord2 = new google.maps.LatLng(25.786328, -80.193694); 
    var bounds = new google.maps.LatLngBounds(); 
    bounds.extend(coord1); 
    bounds.extend(coord2); 
    map.fitBounds(bounds); 

    pLineOpt = { 
     path: [coord1, coord2], 
     strokeWeight: 4, 
     strokeOpacity: 0, 
     map: map, 
    } 

    pLine = new google.maps.Polyline(pLineOpt); 

    var markers = [ 
     new google.maps.Marker({ 
      position: coord1, 
      map: map 
     }), 
     new google.maps.Marker({ 
      position: coord2, 
      map: map 
     }) 
    ]; 

    google.maps.event.addListener(map, 'zoom_changed', function() { 
     //points 
     var p1 = map.getProjection().fromLatLngToPoint(coord1); 
     var p2 = map.getProjection().fromLatLngToPoint(coord2); 
     //distance between points 
     var d = new google.maps.Point(p2.x - p1.x, p2.y - p1.y); 
     var lengthSqr = d.x * d.x + d.y * d.y; 
     //middle point 
     var m = new google.maps.Point(d.x/2, d.y/2); 
     //slope of perpendicular line 
     var perpK = -d.x/d.y; 
     //distance to control point 
     var ratioDistanceControlLengthSqr = 9; 
     var controlDSqr = lengthSqr/ratioDistanceControlLengthSqr; 
     var p3dX = Math.sqrt(controlDSqr/(Math.pow(perpK, 2) + 1)); 
     var p3dY = perpK * p3dX; 
     //control point 
     var p3 = new google.maps.Point(m.x - p3dX, m.y - p3dY); 
     //curve path 
     var path = "M 0 0 q " + p3.x + " " + p3.y + " " + d.x + " " + d.y; 
     //calc scale     
     var zoom = map.getZoom(); 
     var scale = 1/(Math.pow(2, -zoom)); 

     var icon = { 
      path: path, 
      scale: scale, 
      strokeWeight: 3, 
      strokeOpacity: 1, 
     }; 

     pLineOpt.icons = [{ 
      fixedRotation: true, 
      icon: icon, 
      offset: '0' 
     }]; 
     pLine.setOptions(pLineOpt); 
    }); 
} 

google.maps.event.addDomListener(window, 'load', initialize); 

我已与代码的jsfiddle:http://jsfiddle.net/s7djLzyd/3/

有谁知道为什么折线缩放时裁剪,以及是否有办法解决?

感谢

+0

折线是在[瓦片边界]被裁剪(http://jsfiddle.net/s7djLzyd/ 4 /)。看到这发生了很多次,不知道为什么它发生在你的特定情况下,但可能是API平铺渲染折线的错误。首先,我总是提出奇怪的问题,尝试API的发布和冻结版本,[这在这种情况下不起作用](http://jsfiddle.net/s7djLzyd/5/)。 – geocodezip

回答

1

你需要修复您的折线选项:

pLineOpt = { 
    path: [coord1, coord2], 
    geodesic: true, 
    strokeColor: '#000', 
    strokeOpacity: 1.0, 
    strokeWeight: 4 
} 

请试试这个代码片段:可能这是你想要的... :)

function initialize() { 
 
    var mapOptions = { 
 
     mapTypeId: google.maps.MapTypeId.ROADMAP 
 
    }; 
 

 
    var map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions); 
 

 
    var coord1 = new google.maps.LatLng(49.165876, -123.152446); 
 
    var coord2 = new google.maps.LatLng(25.786328, -80.193694); 
 
    var bounds = new google.maps.LatLngBounds(); 
 
    bounds.extend(coord1); 
 
    bounds.extend(coord2); 
 
    map.fitBounds(bounds); 
 

 
    pLineOpt = { 
 
     path: [coord1, coord2], 
 
     geodesic: true, 
 
     strokeColor: '#000', 
 
     strokeOpacity: 1.0, 
 
     strokeWeight: 4 
 
    } 
 

 
    pLine = new google.maps.Polyline(pLineOpt); 
 

 
    var markers = [ 
 
    new google.maps.Marker({ 
 
     position: coord1, 
 
     map: map 
 
    }), 
 
    new google.maps.Marker({ 
 
     position: coord2, 
 
     map: map 
 
    })]; 
 

 
    pLine.setMap(map); 
 

 
    google.maps.event.addListener(map, 'zoom_changed', function() { 
 

 
    }); 
 
} 
 

 
google.maps.event.addDomListener(window, 'load', initialize);
html, body, #map-canvas { 
 
    height: 100%; 
 
    width: 100%; 
 
    margin: 0px; 
 
    padding: 0px 
 
}
<script src="https://maps.googleapis.com/maps/api/js?sensor=false&libraries=geometry,places&ext=.js"></script> 
 

 
<div id="map-canvas"></div>

2

从这个相关的问题:Google Maps API: Bézier curve polyline wrap

var curvedLine = new GmapsCubicBezier(
     49.165876, -123.152446, 
     33.811192,-115.032444, 
     30.820807,-123.749998, 
     25.786328, -80.193694, 
     0.01, map); 

example fiddle

代码片断:

var map; 
 
var origLoc = new google.maps.LatLng(45, -85); 
 

 
function initialize() { 
 
    var mapOptions = { 
 
    center: new google.maps.LatLng(33.811192, -115.032444), 
 
    zoom: 3 
 
    }; 
 
    map = new google.maps.Map(document.getElementById("map"), mapOptions); 
 

 
    var coord1 = new google.maps.LatLng(49.165876, -123.152446); 
 
    var coord2 = new google.maps.LatLng(25.786328, -80.193694); 
 
    var marker1 = new google.maps.Marker({ 
 
    position: coord1, 
 
    title: "marker 1", 
 
    map: map 
 
    }); 
 
    var marker2 = new google.maps.Marker({ 
 
    position: coord2, 
 
    title: "marker 2", 
 
    map: map 
 
    }); 
 

 

 
    var curvedLine = new GmapsCubicBezier(
 
    49.165876, -123.152446, 
 
    33.811192, -115.032444, 
 
    30.820807, -123.749998, 
 
    25.786328, -80.193694, 
 
    0.01, map); 
 
} 
 
google.maps.event.addDomListener(window, 'load', initialize); 
 

 
var GmapsCubicBezier = function(lat1, long1, lat2, long2, lat3, long3, lat4, long4, resolution, map) { 
 

 
    var points = []; 
 

 
    for (it = 0; it <= 1; it += resolution) { 
 
    points.push(this.getBezier({ 
 
     x: lat1, 
 
     y: long1 
 
    }, { 
 
     x: lat2, 
 
     y: long2 
 
    }, { 
 
     x: lat3, 
 
     y: long3 
 
    }, { 
 
     x: lat4, 
 
     y: long4 
 
    }, it)); 
 
    } 
 

 
    for (var i = 0; i < points.length - 1; i++) { 
 
    var Line = new google.maps.Polyline({ 
 
     path: [new google.maps.LatLng(points[i].x, points[i].y), new google.maps.LatLng(points[i + 1].x, points[i + 1].y, false)], 
 
     geodesic: true, 
 
     strokeOpacity: 1, 
 
     strokeColor: 'black', 
 
     /* icons: [{ 
 
      icon: { 
 
       path: 'M 0,-2 0,2', 
 
       strokeColor: 'violet', 
 
       strokeOpacity: 1, 
 
       strokeWeight: 4 
 
      }, 
 
      repeat: '36px' 
 
     }, { 
 
      icon: { 
 
       path: 'M -1,-2 -1,2', 
 
       strokeColor: 'black', 
 
       strokeOpacity: 1, 
 
       strokeWeight: 2 
 
      }, 
 
      repeat: '36px' 
 
     }] */ 
 
    }); 
 
    Line.setMap(map); 
 
    } 
 
    // connect end of line to first point 
 
    var Line = new google.maps.Polyline({ 
 
     path: [new google.maps.LatLng(lat1,long1),new google.maps.LatLng(points[points.length-1].x, points[points.length-1].y)], 
 
     geodesic: true, 
 
     strokeOpacity: 1, 
 
     strokeColor: 'black', 
 
     /* icons: [{ 
 
      icon: { 
 
       path: 'M 0,-2 0,2', 
 
       strokeColor: 'violet', 
 
       strokeOpacity: 1, 
 
       strokeWeight: 4 
 
      }, 
 
      repeat: '36px' 
 
     }, { 
 
      icon: { 
 
       path: 'M -1,-2 -1,2', 
 
       strokeColor: 'black', 
 
       strokeOpacity: 1, 
 
       strokeWeight: 2 
 
      }, 
 
      repeat: '36px' 
 
     }] */ 
 
    }); 
 
    Line.setMap(map); 
 
    
 
    return Line; 
 
}; 
 

 

 
GmapsCubicBezier.prototype = { 
 

 
    B1: function(t) { 
 
    return t * t * t; 
 
    }, 
 
    B2: function(t) { 
 
    return 3 * t * t * (1 - t); 
 
    }, 
 
    B3: function(t) { 
 
    return 3 * t * (1 - t) * (1 - t); 
 
    }, 
 
    B4: function(t) { 
 
    return (1 - t) * (1 - t) * (1 - t); 
 
    }, 
 
    getBezier: function(C1, C2, C3, C4, percent) { 
 
    var pos = {}; 
 
    pos.x = C1.x * this.B1(percent) + C2.x * this.B2(percent) + C3.x * this.B3(percent) + C4.x * this.B4(percent); 
 
    pos.y = C1.y * this.B1(percent) + C2.y * this.B2(percent) + C3.y * this.B3(percent) + C4.y * this.B4(percent); 
 
    return pos; 
 
    } 
 
};
html, 
 
body, 
 
#map { 
 
    height: 100%; 
 
    margin: 0px; 
 
    padding: 0px 
 
}
<script src="https://maps.googleapis.com/maps/api/js?v=3&libraries=geometry"></script> 
 
<div id="map" style="float:left;width:100%;height:100%;"></div>