【问题标题】:Using google maps polyline to draw bezier curve使用谷歌地图折线绘制贝塞尔曲线
【发布时间】:2015-04-22 22:49:22
【问题描述】:

我正在尝试通过在折线中使用 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/

有谁知道为什么折线在缩放时会被裁剪,是否有办法解决这个问题?

谢谢

【问题讨论】:

  • 您的折线在tile boundary 处被裁剪。看到这种情况发生了很多次,不知道为什么会在您的特定情况下发生,但可能是折线的 API 平铺渲染中的错误。对于奇怪的问题,我总是建议的第一件事是尝试 API 的发布和冻结版本,that doesn't help in this case

标签: javascript google-maps google-maps-api-3


【解决方案1】:

您需要修复折线选项:

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

请试试这个代码 sn-p : 可能这就是你想要的... :)

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

    代码sn-p:

    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?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&libraries=geometry"></script>
    <div id="map" style="float:left;width:100%;height:100%;"></div>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-05-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-26
      • 1970-01-01
      相关资源
      最近更新 更多