Google地图使用多边形模拟多段线 [英] Google Maps simulate polyline with polygons

查看:225
本文介绍了Google地图使用多边形模拟多段线的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

几年前,我写了一些代码,用于在宽度上键入用户的Google Map上突出显示路径。用户确定突出显示的路径以米为单位的宽度,以便他们可以看到他们覆盖的地面(如草坪施肥等)。我计算了一个点的距离,并使用Google Maps computeOffset来确定多边形的角点。

  LatLng corner1 = SphericalUtil.computeOffset(point2,widthInMeters / 2,熊+ 90); 
LatLng corner2 = SphericalUtil.computeOffset(point2,widthInMeters / 2,bear - 90);
LatLng corner3 = SphericalUtil.computeOffset(corner2,distance,bears);
LatLng corner4 = SphericalUtil.computeOffset(corner1,distance,bears);

返回新的PolygonOptions()。add(corner1,corner2,corner3,corner4);

我这样做是因为当时Google Maps SDK没有改变折线宽度的方法来显示导航路径的宽度。 (农场实现了这么多英尺宽。)到目前为止,多段线功能在不同的缩放级别具有恒定的宽度。





问题在于,您可以看到轴承信息对于某个设备来说非常不可靠,特别是如果它正在动摇。创建的路径会产生间隙,并且多边形不会像粗线那样平滑地连接。



有没有人看到有任何新的API可以突出显示具有一定宽度的路径或可调折线(与球面距离有关)?我想过使用更小的多边形数量更高,但这是非常耗费资源的。

解决方案

如何创建一个复杂的多边形你的原始路径,使用你已经创建的每个retangle的角点?

我编辑了答案,但是我没有完整的代码来创建4个角落。



您计算左侧90°和右侧距离/ 2的点,右侧点相同,然后制作一个包含所有点的多边形(从第一个左到最后一个让他们继续右移到第一个右边)



我试了一下,看起来并没有那么糟糕......当原始路径的角度> 90 °和最后一点是没有绘制。





var debug = false ; jQuery(document).ready(function(){var infos = []; var polyLeft = []; var polyRight = []; var strokeOpacity = 0; var widthInMeters = 20; if(debug)strokeOpacity = 0.6; // Create一个地图对象并指定要显示的DOM元素var map = new google.maps.Map(document.getElementById('map'),{center:{lat:37.772,lng:-122.214},scrollwheel:false,zoom: 2}); var path = [{lat:45.878521,lng:3.694520},{lat:45.879269,lng:3.693960},{lat:45.880539,lng:3.694340} { LAT:45.882172, LNG:3.694080},{ LAT:45.883900, LNG:3.692780},{ LAT:45.884430, LNG:3.692930},{ LAT:45.885101, LNG :3.692600},{ LAT :45.885490, LNG :3.692590},{ LAT :45.887169, LNG :3.692070},{ LAT :45.887421, LNG :3.691580},{ LAT :45.888000, LNG :3.690050},{ LAT :45.888889, LNG :3.689280},{ LAT :45.889408, LNG :3.688710},{ LAT :45.890331, LNG :3.688690},{ LAT:45.890461, LNG:3.688480},{ LAT:45 0.890511, LNG:3.687520},{ LAT:45.891251, LNG:3.687020},{ LAT:45.891769, LNG:3.686900},{ LAT:45.894039, LNG:3.687510 },{ LAT:45.896568, LNG:3.688810},{ LAT:45.897430, LNG:3.689040},{ LAT:45.898140, LNG:3.688630},{ LAT:45.898769 , LNG:3.687980},{ LAT:45.899719, LNG:3.687290},{ LAT:45.900040, LNG:3.687170},{ LAT:45.900101, LNG:3.686700}, { LAT:45.900570, LNG:3.685970},{ LAT:45.901321, LNG:3.685550},{ LAT:45.902061, LNG:3.685050},{ LAT:45.903030, LNG :3.683950},{ LAT :45.903412, LNG :3.683880},{ LAT :45.903938, LNG :3.683920},{ LAT :45.905102, LNG :3.683280},{ LAT :45.906361, LNG :3.682710},{ LAT :45.906681, LNG :3.682380},{ LAT :45.907082, LNG :3.682250},{ LAT :45.907970, LNG :3.682800},{ LAT:45.908772, LNG:3.682820},{ LAT:45.909149, LNG:3.683270},{ LAT:45.909370, LNG:3.684730},{ LAT :45.909679, LNG:3.685440},{ LAT:45.910191, LNG:3.685902},{ LAT:45.910381, LNG:3.686270},{ LAT:45.911282, LNG:3.686700 },{ LAT:45.912209, LNG:3.687900},{ LAT:45.912281,升NG :3.688140},{ LAT :45.912128, LNG :3.688280},{ LAT :45.911942, LNG :3.689290},{ LAT :45.911709, LNG :3.690250},{ LAT :45.911339, LNG :3.691200},{ LAT :45.911491, LNG :3.693050},{ LAT :45.912109, LNG :3.695400},{ LAT :45.913391, LNG :3.698570},{ LAT:45.913940, LNG:3.700200},{ LAT:45.914688, LNG:3.701790},{ LAT:45.915218, LNG:3.702120},{ LAT :45.916248, LNG:3.703170},{ LAT:45.916889, LNG:3.703440},{ LAT:45.917122, LNG:3.703860},{ LAT:45.917210, LNG:3.704280 },{ LAT:45.917770, LNG:3.704750},{ LAT:45.918739, LNG:3.704860},{ LAT:45.919571, LNG:3.704730},{ LAT:45.919861 , LNG:3.704920},{ LAT:45.920139, LNG:3.706380},{ LAT:45.920460, LNG:3.706880},{ LAT:45.920818, LNG:3.708750}, { LAT:45.921249, LNG:3.709650},{ LAT:45.921680, LNG:3.711240},{ LAT:45.921822, LNG:3.712880},{ LAT:45.921860, LNG :3.715220},{ LAT :45.921951, LNG :3.715510},{ LAT :45.922371, LNG :3.715930},{ LAT :45.922691, LNG :3.718220},{ LAT :45.922958, LNG :3.719330},{ LAT :45.923012, LNG:3.7203 30},{ LAT:45.922821, LNG:3.721420},{ LAT:45.923988, LNG:3.718530},{ LAT:45.924110, LNG:3.717490},{ LAT: 45.924030, LNG:3.716700},{ LAT:45.924389, LNG:3.715310},{ LAT:45.924671, LNG:3.714956},{ LAT:45.925072, LNG:3.714200} ,{ LAT:45.925621, LNG:3.711630},{ LAT:45.926830, LNG:3.709340},{ LAT:45.927231, LNG:3.709070},{ LAT:45.928013, LNG:3.708873},{ LAT:45.929050, LNG:3.708430},{ LAT:45.929790, LNG:3.707750},{ LAT:45.930168, LNG:3.707290},{ LAT:45.930759, LNG:3.707410},{ LAT:45.931370, LNG:3.707620},{ LAT:45.931900, LNG:3.707470},{ LAT:45.932739,LNG :3.706920},{ LAT :45.933529, LNG :3.705940},{ LAT :45.934410, LNG :3.703300},{ LAT :45.934662, LNG :3.701430},{ LAT :45.934841, LNG :3.699650},{ LAT :45.934700, LNG :3.698620},{ LAT :45.934841, LNG :3.697930},{ LAT :45.935371, LNG: 3.696900},{ LAT:45.935741, LNG:3.696590},{ LAT:45.936520, LNG:3.695530},{ LAT:45.936661, LNG:3.695120},{ LAT: 45.936729, LNG:3.694160},{ LAT:45.936600, LNG:3.693150},{ LAT :45.936710, LNG:3.692080},{ LAT:45.936699, LNG:3.691320},{ LAT:45.936989, LNG:3.690560},{ LAT:45.938160, LNG:3.689220 },{ LAT:45.939362, LNG:3.688750},{ LAT:45.940102, LNG:3.688380},{ LAT:45.940521, LNG:3.687900},{ LAT:45.940731 , LNG:3.687590},{ LAT:45.940990, LNG:3.686870},{ LAT:45.941479, LNG:3.686270},{ LAT:45.941959, LNG:3.685800}, { LAT:45.942169, LNG:3.685150},{ LAT:45.942520, LNG:3.684640},{ LAT:45.942829, LNG:3.683400},{ LAT:45.943020, LNG :3.682970},{ LAT :45.943199, LNG :3.682250},{ LAT :45.943600, LNG :3.681720},{ LAT :45.944160, LNG :3.681310},{ LAT :45.944771, LNG :3.681170},{ LAT :45.945690, LNG :3.681750},{ LAT :45.946121, LNG :3.681730},{ LAT :45.946960, LNG :3.681180},{ LAT:45.947201, LNG:3.681140},{ LAT:45.948021, LNG:3.681520},{ LAT:45.949181, LNG:3.682410},{ LAT :45.949741, LNG:3.683030},{ LAT:45.949959, LNG:3.683370},{ LAT:45.950809, LNG:3.684230},{ LAT:45.951229, LNG:3.684470 },{ LAT:45.952309, LNG:3.685560},{ LAT:45.953129 , LNG:3.685960},{ LAT:45.953758, LNG:3.686160},{ LAT:45.954319, LNG:3.685820},{ LAT:45.955429, LNG:3.685740}, { LAT:45.956108, LNG:3.685940},{ LAT:45.956200, LNG:3.686010},{ LAT:45.956619, LNG:3.686740},{ LAT:45.956860, LNG :3.687270},{ LAT :45.956921, LNG :3.687740},{ LAT :45.957260, LNG :3.688530},{ LAT :45.957809, LNG :3.689250},{ LAT :45.958401, LNG :3.689540},{ LAT :45.958851, LNG :3.689660},{ LAT :45.959599, LNG :3.690140},{ LAT :45.959789, LNG :3.690520},{ LAT:45.960258, LNG:3.690750},{ LAT:45.960571, LNG:3.691020},{ LAT:45.961521, LNG:3.692110},{ LAT :45.961761, LNG:3.692530}]; var bounds = new google.maps.LatLngBounds(); map.fitBounds(bounds); for(var i in path)bounds.extend(path [i]); var poly = new google.maps.Polyline({path:path,strokeColor:'#FF0000',strokeOpacity:1.0,strokeWeight:2})poly.setMap(map); for(var k in path){var currentLatLng = new google.maps.LatLng(path [k]); var lastLatLng = null; var nextLatLng = null; var headingRight,headingLeft; var cas = 0; if(typeof path [parseInt(k)-1]!='undefined')lastLatLng = new google.maps.LatLng(path [parseInt(k)-1]); if(typeof path [parseInt(k)+1]!='undefined')nextLatLng = new google.maps.LatLng(path [parseInt(k)+1]); var etat ='lastLatLng ='+ lastLatLng +'< br />'+'currentLatLng ='+ currentLatLng +'< br />'+'nextLaLng ='+ nextLatLng +'< br />'; if(lastLatLng === null&& nextLatLng!== null){for(var i = 0; i <= 180; i + = 10){var heading = parseFloat(google.maps.geometry.spherical。 computeHeading(currentLatLng,nextLatLng))+ 90 + i; addPoint(heading,currentLatLng,false); }} if(lastLatLng!== null){headingRight = parseFloat(google.maps.geometry.spherical.computeHeading(currentLatLng,lastLatLng)) - 90; addPoint(headingRight,currentLatLng); } if(lastLatLng!== null&& nextLatLng!== null){cas ='intermediaires'; var headingBefore = google.maps.geometry.spherical.computeHeading(currentLatLng,lastLatLng); var headingAfter = google.maps.geometry.spherical.computeHeading(currentLatLng,nextLatLng); headingBefore + = 360; headingBefore = headingBefore%360;标题+ + 360; headingAfter = headingAfter%360; headingRight = parseFloat((headingBefore + headingAfter)/ 2);如果(headingAfter> headingBefore)headingRight + = 180; headingRight + = 360; headingRight = headingRight%360; addPoint(headingRight,currentLatLng); } if(nextLatLng!== null){headingRight = parseFloat(google.maps.geometry.spherical.computeHeading(currentLatLng,nextLatLng))+ 90; addPoint(headingRight,currentLatLng); } if(lastLatLng!== null&& nextLatLng === null){for(var i = 0; i< = 180; i + = 10){var heading = parseFloat(google.maps.geometry.spherical .computeHeading(currentLatLng,lastLatLng)) - 90 - i; addPoint(heading,currentLatLng,false); }} if(debug){var content = etat +'< hr />'+'k ='+ k +'&'+'cas ='+ cas +'< 'currentLatLng ='+ currentLatLng +''''''''path [k] ='+ path [k] ['lat'] +','+ path [k] ['lng'] +'< br /> '+'headingBefore ='+ headingBefore +'< br />'+'headingAfter ='+ headingAfter +'< br />'+'headingRight ='+ headingRight +'< br />'+'headingLeft = '+ headingLeft +'< br />'; / *'pointLeft ='+ pointLeft.lat()+','+ pointLeft.lng()+'< br />'+'pointLeft ='+ pointRight.lat()+','+ pointRight.lng (); * / var marker = new google.maps.Marker({position:path [k],map:map,title:'Uluru(Ayers Rock)'}); var infowindow = new google.maps.InfoWindow(); google.maps.event.addListener(marker,'click',(function(marker,content,infowindow){return function(){closeInfos(); infowindow.setContent(content); infowindow.open(map,marker); infos [0] = infowindow;};})(marker,content,infowindow)); }} / * console.log(path); console.log(polyTop); console.log(polyBottom); * / //此时,polyTop和polyBottom应该包含一条平行于您的初始路径的遍,但是位于orig左侧的widthInMeter / 2。用于polyBottom的polyFrom和widthInMeter / 2右侧的路径。 //这是一个开始,但如果我们想绘制一个复杂的多边形,我们只需要一个坐标路径。 //我们需要做的就是将两个pattes混合成一个,颠倒bottomPath,这样创建的路径将从polyTop的第一个元素到polyTop的最后一个元素,然后是polyBottom的最后一个元素,并在polyBottom的最后一个元素上完成。它应该会导致一种巨大的多边形,在原始路径上进行巡视。 new google.maps.Polyline({path:polyLeft,geodesic:true,strokeColor:'#00FF00',strokeOpacity:strokeOpacity,strokeWeight:2})。setMap(map); new google.maps.Polyline({path:polyRight,geodesic:true,strokeColor:'#0000FF',strokeOpacity:strokeOpacity,strokeWeight:2})。setMap(map); polyRight.reverse(); var polys = polyLeft.concat(polyRight); var complexPoly = new google.maps.Polygon({paths:polys,strokeOpacity:0,strokeWeight:0,fillColor:'#FF0000',fillOpacity:0.35,}); complexPoly.setMap(地图);函数closeInfos(){if(infos.length> 0){/ *从标记中分离信息窗口......未在API文档中记录* / infos [0] .set(marker,null); / *并关闭它* / infos [0] .close(); / *空白数组* / infos.length = 0; }} function addPoint(hRight,currentLatLng,both = true){hLeft = hRight + 180; if(hLeft> 360)hLeft - = 360;如果(hRight> 360)hRight - = 360; var pointRight = google.maps.geometry.spherical.computeOffset(currentLatLng,widthInMeters / 2,hRight); var pointLeft = google.maps.geometry.spherical.computeOffset(currentLatLng,widthInMeters / 2,hLeft);如果(!isNaN(pointLeft.lat())&&!isNaN(pointRight.lat())){if(both)polyLeft.push({'lat':pointLeft.lat(),'lng':pointLeft .lng()}); polyRight.push({'lat':pointRight.lat(),'lng':pointRight.lng()}); }}});

#map {width:400px; height:200px;}

< script src =https ://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js>< / script>< script src =https://maps.googleapis.com/maps/ API / JS库=几何>?< /脚本> < div id =map>< / div>

I wrote a few years ago some code that highlighted a path on a Google Map with a user typed in width. The user determines how wide the highlighted path is in meters that way they can see the ground they have covered (ex lawn fertilizing etc). I calculated the distance from a point and used the Google Maps computeOffset to determine the corners of the polygon. Next I used the bearing information from the path to plot the next polygon.

LatLng corner1 = SphericalUtil.computeOffset(point2, widthInMeters / 2, bears + 90);
LatLng corner2 = SphericalUtil.computeOffset(point2, widthInMeters / 2, bears - 90);
LatLng corner3 = SphericalUtil.computeOffset(corner2, distance, bears);
LatLng corner4 = SphericalUtil.computeOffset(corner1, distance, bears);

return new PolygonOptions().add(corner1, corner2, corner3, corner4);

I did this because at the time the Google Maps SDK had no method of varying a polyline's width to show the width of navigated path. (ex farm implement so many feet wide.) The polyline feature to this day has constant width at different zoom levels.

The problem is as you can see bearing information is very unreliable from a device especially if it is being shaken around. The path that is created makes gaps and the polygons don't smoothly connect like a thick polyline would.

Has anyone seen any new APIs out there that have a way to highlight a path of certain width or an adjustable polyline (with spherical distance accounted for)? I thought about using smaller polygons with a higher count, but that is very resource intensive.

解决方案

What about creating a complex polygon around your oiginal path, using the corners of each retangle you already created ?

I've edited the answer, but i don't have your complete code to create the 4 corners.

You calculate a point at 90° left and distance/2, same for point on right, then you make a polygon with all thoses points (from first left to last left them last right to first right)

I've made a try and it looks not that bad... just some issues when the original path make an angle > 90° and the last point is not drawn.

var debug = false ;

    jQuery(document).ready(function(){

        var infos = [] ;
        var polyLeft = [] ;
        var polyRight = [] ;
        var strokeOpacity = 0 ;
        var widthInMeters = 20 ;
        if ( debug ) strokeOpacity = 0.6 ;

        // Create a map object and specify the DOM element for display.
        var map = new google.maps.Map(document.getElementById('map'), {
          center: {lat: 37.772, lng: -122.214},
          scrollwheel: false,
          zoom: 2
        });
        
        var path = [{"lat":45.878521,"lng":3.694520},{"lat":45.879269,"lng":3.693960},{"lat":45.880539,"lng":3.694340},{"lat":45.882172,"lng":3.694080},{"lat":45.883900,"lng":3.692780},{"lat":45.884430,"lng":3.692930},{"lat":45.885101,"lng":3.692600},{"lat":45.885490,"lng":3.692590},{"lat":45.887169,"lng":3.692070},{"lat":45.887421,"lng":3.691580},{"lat":45.888000,"lng":3.690050},{"lat":45.888889,"lng":3.689280},{"lat":45.889408,"lng":3.688710},{"lat":45.890331,"lng":3.688690},{"lat":45.890461,"lng":3.688480},{"lat":45.890511,"lng":3.687520},{"lat":45.891251,"lng":3.687020},{"lat":45.891769,"lng":3.686900},{"lat":45.894039,"lng":3.687510},{"lat":45.896568,"lng":3.688810},{"lat":45.897430,"lng":3.689040},{"lat":45.898140,"lng":3.688630},{"lat":45.898769,"lng":3.687980},{"lat":45.899719,"lng":3.687290},{"lat":45.900040,"lng":3.687170},{"lat":45.900101,"lng":3.686700},{"lat":45.900570,"lng":3.685970},{"lat":45.901321,"lng":3.685550},{"lat":45.902061,"lng":3.685050},{"lat":45.903030,"lng":3.683950},{"lat":45.903412,"lng":3.683880},{"lat":45.903938,"lng":3.683920},{"lat":45.905102,"lng":3.683280},{"lat":45.906361,"lng":3.682710},{"lat":45.906681,"lng":3.682380},{"lat":45.907082,"lng":3.682250},{"lat":45.907970,"lng":3.682800},{"lat":45.908772,"lng":3.682820},{"lat":45.909149,"lng":3.683270},{"lat":45.909370,"lng":3.684730},{"lat":45.909679,"lng":3.685440},{"lat":45.910191,"lng":3.685902},{"lat":45.910381,"lng":3.686270},{"lat":45.911282,"lng":3.686700},{"lat":45.912209,"lng":3.687900},{"lat":45.912281,"lng":3.688140},{"lat":45.912128,"lng":3.688280},{"lat":45.911942,"lng":3.689290},{"lat":45.911709,"lng":3.690250},{"lat":45.911339,"lng":3.691200},{"lat":45.911491,"lng":3.693050},{"lat":45.912109,"lng":3.695400},{"lat":45.913391,"lng":3.698570},{"lat":45.913940,"lng":3.700200},{"lat":45.914688,"lng":3.701790},{"lat":45.915218,"lng":3.702120},{"lat":45.916248,"lng":3.703170},{"lat":45.916889,"lng":3.703440},{"lat":45.917122,"lng":3.703860},{"lat":45.917210,"lng":3.704280},{"lat":45.917770,"lng":3.704750},{"lat":45.918739,"lng":3.704860},{"lat":45.919571,"lng":3.704730},{"lat":45.919861,"lng":3.704920},{"lat":45.920139,"lng":3.706380},{"lat":45.920460,"lng":3.706880},{"lat":45.920818,"lng":3.708750},{"lat":45.921249,"lng":3.709650},{"lat":45.921680,"lng":3.711240},{"lat":45.921822,"lng":3.712880},{"lat":45.921860,"lng":3.715220},{"lat":45.921951,"lng":3.715510},{"lat":45.922371,"lng":3.715930},{"lat":45.922691,"lng":3.718220},{"lat":45.922958,"lng":3.719330},{"lat":45.923012,"lng":3.720330},{"lat":45.922821,"lng":3.721420},{"lat":45.923988,"lng":3.718530},{"lat":45.924110,"lng":3.717490},{"lat":45.924030,"lng":3.716700},{"lat":45.924389,"lng":3.715310},{"lat":45.924671,"lng":3.714956},{"lat":45.925072,"lng":3.714200},{"lat":45.925621,"lng":3.711630},{"lat":45.926830,"lng":3.709340},{"lat":45.927231,"lng":3.709070},{"lat":45.928013,"lng":3.708873},{"lat":45.929050,"lng":3.708430},{"lat":45.929790,"lng":3.707750},{"lat":45.930168,"lng":3.707290},{"lat":45.930759,"lng":3.707410},{"lat":45.931370,"lng":3.707620},{"lat":45.931900,"lng":3.707470},{"lat":45.932739,"lng":3.706920},{"lat":45.933529,"lng":3.705940},{"lat":45.934410,"lng":3.703300},{"lat":45.934662,"lng":3.701430},{"lat":45.934841,"lng":3.699650},{"lat":45.934700,"lng":3.698620},{"lat":45.934841,"lng":3.697930},{"lat":45.935371,"lng":3.696900},{"lat":45.935741,"lng":3.696590},{"lat":45.936520,"lng":3.695530},{"lat":45.936661,"lng":3.695120},{"lat":45.936729,"lng":3.694160},{"lat":45.936600,"lng":3.693150},{"lat":45.936710,"lng":3.692080},{"lat":45.936699,"lng":3.691320},{"lat":45.936989,"lng":3.690560},{"lat":45.938160,"lng":3.689220},{"lat":45.939362,"lng":3.688750},{"lat":45.940102,"lng":3.688380},{"lat":45.940521,"lng":3.687900},{"lat":45.940731,"lng":3.687590},{"lat":45.940990,"lng":3.686870},{"lat":45.941479,"lng":3.686270},{"lat":45.941959,"lng":3.685800},{"lat":45.942169,"lng":3.685150},{"lat":45.942520,"lng":3.684640},{"lat":45.942829,"lng":3.683400},{"lat":45.943020,"lng":3.682970},{"lat":45.943199,"lng":3.682250},{"lat":45.943600,"lng":3.681720},{"lat":45.944160,"lng":3.681310},{"lat":45.944771,"lng":3.681170},{"lat":45.945690,"lng":3.681750},{"lat":45.946121,"lng":3.681730},{"lat":45.946960,"lng":3.681180},{"lat":45.947201,"lng":3.681140},{"lat":45.948021,"lng":3.681520},{"lat":45.949181,"lng":3.682410},{"lat":45.949741,"lng":3.683030},{"lat":45.949959,"lng":3.683370},{"lat":45.950809,"lng":3.684230},{"lat":45.951229,"lng":3.684470},{"lat":45.952309,"lng":3.685560},{"lat":45.953129,"lng":3.685960},{"lat":45.953758,"lng":3.686160},{"lat":45.954319,"lng":3.685820},{"lat":45.955429,"lng":3.685740},{"lat":45.956108,"lng":3.685940},{"lat":45.956200,"lng":3.686010},{"lat":45.956619,"lng":3.686740},{"lat":45.956860,"lng":3.687270},{"lat":45.956921,"lng":3.687740},{"lat":45.957260,"lng":3.688530},{"lat":45.957809,"lng":3.689250},{"lat":45.958401,"lng":3.689540},{"lat":45.958851,"lng":3.689660},{"lat":45.959599,"lng":3.690140},{"lat":45.959789,"lng":3.690520},{"lat":45.960258,"lng":3.690750},{"lat":45.960571,"lng":3.691020},{"lat":45.961521,"lng":3.692110},{"lat":45.961761,"lng":3.692530}];

        var bounds = new google.maps.LatLngBounds() ;
        map.fitBounds(bounds)  ;

        for ( var i in path )
            bounds.extend(path[i]) ;

       var poly = new google.maps.Polyline({
          path: path,
          strokeColor: '#FF0000',
          strokeOpacity: 1.0,
          strokeWeight: 2
        })
       poly.setMap(map) ;
       
        for ( var k in path )
        {
            var currentLatLng = new google.maps.LatLng(path[k]) ;
            var lastLatLng = null ;
            var nextLatLng = null ;
            var headingRight, headingLeft ;
            var cas = 0 ;

            if ( typeof path[parseInt(k)-1] != 'undefined' ) lastLatLng = new google.maps.LatLng(path[parseInt(k)-1]) ;
            if ( typeof path[parseInt(k)+1] != 'undefined' ) nextLatLng = new google.maps.LatLng(path[parseInt(k)+1]) ;

            var etat = 'lastLatLng='+lastLatLng + '<br />' +
                       'currentLatLng='+currentLatLng+'<br />' +
                       'nextLaLng='+nextLatLng+'<br />' ;

            if ( lastLatLng === null && nextLatLng !== null )
            {
              for ( var i = 0 ; i <= 180 ; i += 10 )
              {
                var heading = parseFloat(google.maps.geometry.spherical.computeHeading(currentLatLng,nextLatLng)) + 90 + i ;
                addPoint(heading,currentLatLng,false) ;
              }
            }

            if ( lastLatLng !== null )
            {
              headingRight = parseFloat(google.maps.geometry.spherical.computeHeading(currentLatLng,lastLatLng)) - 90 ;
              addPoint(headingRight,currentLatLng) ;
            }

            if ( lastLatLng !== null && nextLatLng !== null )
            {
                cas = 'intermediaires' ;
                var headingBefore = google.maps.geometry.spherical.computeHeading(currentLatLng,lastLatLng) ;
                var headingAfter = google.maps.geometry.spherical.computeHeading(currentLatLng,nextLatLng) ;
                headingBefore += 360 ; headingBefore = headingBefore % 360 ;
                headingAfter += 360 ; headingAfter = headingAfter % 360 ;
                
                headingRight = parseFloat( ( headingBefore + headingAfter ) / 2 ) ;
                if ( headingAfter > headingBefore ) headingRight += 180 ;
                headingRight += 360 ;
                
                headingRight = headingRight % 360 ;

                addPoint(headingRight,currentLatLng) ;
            }

            if ( nextLatLng !== null )
            {
              headingRight = parseFloat(google.maps.geometry.spherical.computeHeading(currentLatLng,nextLatLng)) + 90 ;
              addPoint(headingRight,currentLatLng) ;
            }

            if ( lastLatLng !== null && nextLatLng === null )
            {
              for ( var i = 0 ; i <= 180 ; i += 10 )
              {
                var heading = parseFloat(google.maps.geometry.spherical.computeHeading(currentLatLng,lastLatLng)) - 90 - i ;
                addPoint(heading,currentLatLng,false) ;
              }
            }

            
            if ( debug )
            {
              var content = etat+'<hr />'+
                'k='+k+'<br />'+
                'cas='+cas+'<br />'+
                'currentLatLng='+currentLatLng+'<br />'+
                'path[k]='+path[k]['lat']+','+path[k]['lng']+' <br /> '+
                'headingBefore='+headingBefore+'<br />'+
                'headingAfter='+headingAfter+'<br />'+
                'headingRight='+headingRight+'<br />'+
                'headingLeft='+headingLeft+'<br />' ;
                /*
                'pointLeft='+pointLeft.lat()+','+pointLeft.lng()+'<br />'+
                'pointLeft='+pointRight.lat()+','+pointRight.lng() ;
                */

              var marker = new google.maps.Marker({
                position: path[k],
                map: map,
                title: 'Uluru (Ayers Rock)'
              });
              var infowindow = new google.maps.InfoWindow() ;
              
              google.maps.event.addListener(marker,'click', (function(marker,content,infowindow){ 
                return function() {
                  closeInfos();
                  infowindow.setContent(content);
                  infowindow.open(map,marker);
                  
                  infos[0]=infowindow;
                  
                  };
              })(marker,content,infowindow));
            }
            
        }
        
        /*
        console.log(path) ;
        console.log(polyTop) ;
        console.log(polyBottom) ;
        */
        // At this point, polyTop and polyBottom should contain a pass parrallel as your initial path, but from widthInMeter/2 on left of the orig. path for polyFrom and  widthInMeter/2 on right for polyBottom.
        
       // It's a start, but if we want to draw a complex polygon, we need only one path of coordinates.
       // What we need to do know is "mix" the 2 pathes into one, reversing bottomPath so the path created will go from first element of polyTop, to last element of polyTop, then last element of polyBottom and finish on last element of polyBottom. It should result in a sort a huge polygon making a "tour" around your original path.
       
       new google.maps.Polyline({
          path: polyLeft,
          geodesic: true,
          strokeColor: '#00FF00',
          strokeOpacity: strokeOpacity,
          strokeWeight: 2
        }).setMap(map) ;

       new google.maps.Polyline({
          path: polyRight,
          geodesic: true,
          strokeColor: '#0000FF',
          strokeOpacity: strokeOpacity,
          strokeWeight: 2
        }).setMap(map) ;

        polyRight.reverse() ;
        var polys = polyLeft.concat(polyRight) ;
       
        var complexPoly = new google.maps.Polygon({
            paths: polys,
            strokeOpacity: 0,
            strokeWeight: 0,
            fillColor: '#FF0000',
            fillOpacity: 0.35,
        });
        complexPoly.setMap(map); 
        
        function closeInfos(){
         
           if(infos.length > 0){
         
              /* detach the info-window from the marker ... undocumented in the API docs */
              infos[0].set("marker", null);
         
              /* and close it */
              infos[0].close();
         
              /* blank the array */
              infos.length = 0;
           }
        }

        function addPoint(hRight,currentLatLng,both=true)
        {
          hLeft = hRight + 180 ;
          if ( hLeft > 360 ) hLeft -= 360 ;
          if ( hRight > 360 ) hRight -= 360 ;

          var pointRight = google.maps.geometry.spherical.computeOffset(currentLatLng,widthInMeters/2,hRight) ;
          var pointLeft  = google.maps.geometry.spherical.computeOffset(currentLatLng,widthInMeters/2,hLeft) ;

          if ( ! isNaN(pointLeft.lat()) && ! isNaN(pointRight.lat()) )
          {
              if ( both ) polyLeft.push({'lat':pointLeft.lat(),'lng':pointLeft.lng()}) ;
              polyRight.push({'lat':pointRight.lat(),'lng':pointRight.lng()}) ;    
          }
        }

    }) ;

#map {

  width:400px ;
  height:200px ;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maps.googleapis.com/maps/api/js?libraries=geometry"></script>
    <div id="map"></div>

这篇关于Google地图使用多边形模拟多段线的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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