gpt4 book ai didi

android - 谷歌地图用多边形模拟折线

转载 作者:行者123 更新时间:2023-11-29 00:16:09 27 4
gpt4 key购买 nike

几年前,我编写了一些代码,突出显示了 Google map 上的一条路径,其中用户输入了宽度。用户确定突出显示的路径有多宽(以米为单位),这样他们就可以看到他们所覆盖的地面(例如草坪施肥等)。我计算了距一个点的距离,并使用 Google map computeOffset 来确定多边形的角点。接下来,我使用路径中的方位信息来绘制下一个多边形。

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

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

Polygon mapping example at 50 feet wide

问题是,正如您所看到的,设备中的轴承信息非常不可靠,尤其是在设备晃动的情况下。创建的路径会产生间隙,并且多边形不会像粗折线那样平滑连接。

有没有人看到任何新的 API 可以突出显示特定宽度的路径或可调整的多段线(考虑球面距离)?我考虑过使用具有较高计数的较小多边形,但这非常耗费资源。

最佳答案

如何使用您已经创建的每个重新缠结的角围绕您的原始路径创建一个复杂的多边形?

我已经编辑了答案,但我没有您创建 4 个角的完整代码。

你计算一个点在左边 90° 和距离/2,右边的点也一样,然后你用所有这些点制作一个多边形(从第一个左边到最后一个左边,最后一个右边到第一个右边)

我已经尝试过了,看起来还不错……只是当原始路径的角度 > 90° 并且最后一点未绘制时出现一些问题。

enter image description here

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>

关于android - 谷歌地图用多边形模拟折线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45289080/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com