- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
几年前,我编写了一些代码,突出显示了 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 没有方法改变折线的宽度来显示导航路径的宽度。 (前农具有这么多英尺宽。)迄今为止,折线功能在不同的缩放级别下具有恒定的宽度。
问题是,正如您所看到的,设备中的轴承信息非常不可靠,尤其是在设备晃动的情况下。创建的路径会产生间隙,并且多边形不会像粗折线那样平滑连接。
有没有人看到任何新的 API 可以突出显示特定宽度的路径或可调整的多段线(考虑球面距离)?我考虑过使用具有较高计数的较小多边形,但这非常耗费资源。
最佳答案
如何使用您已经创建的每个重新缠结的角围绕您的原始路径创建一个复杂的多边形?
我已经编辑了答案,但我没有您创建 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 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/
我已经实现了 Bentley-Ottmann-algorithm检测多边形-多边形交叉点。这通常非常有效:由于多边形不自相交,因此两个多边形的线段并集中的任何线段相交表明两个多边形相交。 但是如果我看
我在 Silverlight 中有一个多边形(棋盘游戏的十六进制),例如; public class GridHex : IGridShape { ..... public IList
我创建了一个简单的 DirectX 应用程序来渲染一个顶点场。顶点呈现如下(如果从顶部查看): |\|\|\|\| |\|\|\|\| 每个三角形都是这样渲染的: 1 |\ 2 3 这应该意味着多边形
我的代码的某些部分here : var stage = new Kinetic.Stage({ container: "canvas", width: 300,
我正在尝试从 map 数据构造导航网格物体。步骤之一涉及将二进制图像(其中0表示占用空间,1表示自由空间)转换成平面直线图。 我正在尝试找到一种可靠的方法。我目前的想法是使用Canny边缘检测器,然后
我的任务是编写 MATLAB 代码来生成一个由 4 部分组成的 Logo ,如屏幕截图所示。左上角应为黑色,右下角应为白色。另一个程序应随机选择两种颜色。 我采取了以下方法: clear all cl
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
如何向 google.maps.Rectangle 和 google.maps.Polygon 添加标题? title 属性在 RectangleOptions 中不可用.我试过了,但没用(对于 go
我有一个表,用于将表上的段存储为多边形。然后我想获取所有被另一个多边形接触的线段,例如正方形或圆形。图片上:http://img.acianetmedia.com/GJ3 我将灰色小框表示为段和 bi
我正在我的网站上使用 CSS 来制作形状。它在 chrome 中运行良好,但在 mozilla、internet explorer 中打开时,它无法运行。 有人知道怎么解决吗? 这是 fiddle h
我使用 DrawingManager 在 Google map 上绘制圆形和多边形。我尝试使用下面的代码删除圆形/多边形。 selectedShape.setMap(null); 这里selected
我看到了很多如何检测碰撞的教程,但没有看到如何解决它。我正在制作一个自上而下的游戏,玩家具有圆形碰撞形状,而墙壁是各种多边形。 我正在使用 slick2d。我应该做的是,如果玩家与角落碰撞,我会按法线
我对 tkinter 比较陌生,我正在制作一个只使用正方形的游戏。我正在抄写的书只显示三角形。这是代码: # The tkinter launcher (Already complete) from
我在 OpenCV/Python 中工作,我遇到了这个问题。我已经使用 cv2.minAreaRect() 来获取围绕一组点的边界框。是否有任何其他函数/通用算法可以给我内接多边形(点集)的最大矩形?
如果给定一组线段 S ,我们能否设计一种算法来测试集合 S 中的线段是否可以形成多边形,我对它们是否相交多边形不感兴趣,我只想知道我可以测试什么标准, 任何建议 最佳答案 构建一个图形数据结构,其中节
如何从多个地理位置(经度、纬度值)创建多边形地理围栏。此外,如何在 Android 上跟踪用户进入此地理围栏区域或从该区域退出。 最佳答案 地理围栏只是一组形成多边形的纬度/经度点。获得纬度/经度点列
我想要一个 complex image like this在我的申请中。我想让用户点击复杂的多边形(在这种情况下是有边界的国家/地区)并突出显示他们点击的多边形。我有我需要用于该状态的图像。 我怎样才
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,
我想在 python tkinter 中移动对象,特别是多边形。问题出在 is_click 函数中。我似乎无法弄清楚如何确定我是否单击了该对象。代码还没有 100% 完成,移动仍然需要完成,但我现在需
我有一个大多边形,我想找到与该多边形相交的要素,但由于多边形太大,我遇到超时异常。 我试图研究 JTS 方法,但不知道如何使用它。 final List coordinates = List.of(n
我是一名优秀的程序员,十分优秀!