使用谷歌地图折线绘制贝塞尔曲线 [英] Using google maps polyline to draw bezier curve

查看:103
本文介绍了使用谷歌地图折线绘制贝塞尔曲线的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在Polyline中使用SVG路径在Google地图中绘制贝塞尔曲线。起初,我使用了一个标记,而不是类似于两条近线之间的曲线点在谷歌地图,这给了我后面的结果。但是,由于无法在地图下拖动地图,因此我无法使用此方法。



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



以下是代码:

 函数初始化(){
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 = {
路径:[coord1,coord2],
strokeWeight:4,
strokeOpacity:0,
map:map,
}

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

var marker = [
new google.maps.Marker({
position:coord1,
map:map
}),
新的google.maps.Marker({
位置:coord2,
map:map
})
];

google.maps.event.addListener(map,'zoom_changed',function(){
// points
var p1 = map.getProjection()。fromLatLngToPoint(coord1) ;
var p2 = map.getProjection()。fromLatLngToPoint(coord2);
//点之间的距离
var d = new google.maps.Point(p2.x - p1.x, p2.y - p1.y);
var lengthSqr = dx * dx + dy * dy;
//中间点
var m =新google.maps.Point(dx / 2, dy / 2);
//垂直线的斜率
var perpK = -dx / dy;
//到控制点的距离
var ratioDistanceControlLengthSqr = 9;
var controlDSqr = lengthSqr / ratioDistanceControlLengthSqr;
var p3dX = Math.sqrt(controlDSqr /(Math.pow(perpK,2)+ 1));
var p3dY = perpK * p3dX;
/ /控制点
var p3 =新的google.maps.Point(mx - p3dX,my - p3dY);
//曲线路径
var path =M 0 0 q+ p3.x ++ p3.y ++ d.x ++ d.y;
//计算比例
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/

有谁知道为什么折线在缩放时被裁剪,如果有解决方法吗?



谢谢

解决方案

从这个相关的问题:谷歌地图API: Bézier曲线折线包装

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

示例小提琴



代码段:



  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 =函数(lat1,long1,lat2,long2,lat3,long3,lat4,long4,分辨率,地图){var points = []; (it = 0; it <= 1; it + =分辨率){points.push(this.getBezier({x:lat1,y:long1},{x:lat2,y:long2},{x:lat3 ,y:long3},{x:lat4,y:long4},it)); }(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),新google.maps.LatLng(points [i + 1] .x,points [i + 1] .y,false)],geodesic:true,strokeOpacity:1,strokeColor:'black',/ *图标:[{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(地图); } //将行尾连接到第一个点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',/ *图标:[{图标:{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(地图); 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);返回pos; }};  

html,body,#map {height: 100%; margin:0px; < script src =https://

I'm trying to draw a bezier curve in google maps by using a SVG path in a Polyline. At first I used a Marker instead similar to Curved line between two near points in google maps, which gave the results that I'm after. However, since it's not possible to drag the map under the marker, I can't use this method.

So I switched to a Polyline instead of a marker. Now I get the same good results when I zoom out, but when I zoom in the curve becomes "cropped".

Here is the code:

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);

I have made a jsfiddle with the code: http://jsfiddle.net/s7djLzyd/3/

Does anyone know why the Polyline is cropped when zooming, and if there is a way around this?

Thanks

解决方案

From this related question: 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

code snippet:

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>

这篇关于使用谷歌地图折线绘制贝塞尔曲线的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆