谷歌地图多边形优化

10

我从某个地方提取了国家轮廓数据,并成功将其转换为经纬度坐标的数组,可以将其输入Google地图API以绘制折线或多边形。

问题是该形状中有约1200个点。虽然在Google地图上渲染得非常完美,但我需要将点的数量从1200个减少到不到100个。我不需要非常平滑的轮廓,只需放弃一些可有可无的点即可。需要任何算法或在线工具来帮助我减少点的数量。


你需要只做一次吗?另外,你使用任何可能具有空间扩展的数据库吗? - Argiropoulos Stavros
@Argiropoulos Stavros:只需要一次。没有涉及到数据库;它只是一个HTML/JavaScript页面。如果数据库有帮助的话,我可以将数据导入到MySQL 5.1数据库中,并执行您建议的任何操作。 - Salman A
搜索“编码折线”。它将把你的1200多个点减少到一个约40字节的字符串。 - Travis Webb
Potrace工作得很好,尽管我怀疑它不适用于地图数据。然而,Inkscape在其“简化”命令中有一个良好的postrace实现。 - bobbogo
我也在寻找同样的东西,Simplify.js非常好用。 - Anthony Hatzopoulos
6个回答

8
我找到了 Bill Chadwick 写的一段简单的 JavaScript 代码。只需要将 LatLng 数据输入到数组中,并将其传递给这里的函数中的源参数,即可使用Douglas Peucker 线简化例程。它会输出一个点数更少的多边形数组。
 var ArrayforPolygontoUse= GDouglasPeucker(theArrayofLatLng,2000) 
 var polygon=new google.maps.Polygon({ 

    path:ArrayforPolygontoUse,
    geodesic:true,
    strokeColor:"#0000FF",
    strokeOpacity:0.8,
    strokeWeight:2,
    fillColor:"#0000FF",
    fillOpacity:0.4,
    editable:true
  });

theArrayofLatLng是使用Google Maps API收集的latlng数组。 2000是以米为单位的kink值。我的假设是,该值越高,则输出时将删除更多点。

对于真正的初学者: 在使用之前,请确保在HTML页面上声明JS文件。 :)

<script type="text/javascript" src="js/GDouglasPeucker.js"></script>

4
我认为MapShaper可以在线完成这个任务。
否则,实现一些算法

解释负分被认为是礼貌的行为;我提供了一个可能做到所需功能的在线工具链接。 - Unreason
我能从Map Shaper生成的“shp”文件中提取坐标信息吗? - Salman A
抱歉,当时没有时间做更多的事情,只能点个踩。原因是似乎提供一个工具(和实现“某些算法”的模糊建议)作为解决方案对于一个关于如何编写程序解决问题的问题来说并不是很有帮助。现在OP澄清了他不需要编程,只需要做一次,系统允许的话我会撤回这个踩。 - Vojislav Stojkovic
@Salman A,据我所知,是的,你可以使用shp2pgsql将它们导入到PostGIS。 - Unreason
1
使用“道格拉斯-普克直线简化算法”对约1200个点进行处理,将其简化到70个。 - Salman A
Douglas-Peucker算法在这里的simplify方法中实现:http://googlemaps.github.io/android-maps-utils/javadoc/com/google/maps/android/PolyUtil.html#simplify-java.util.List-double- - Analizer

1

我也在寻找同样的东西,发现了Simplify.js。它可以完全满足你的需求,并且非常易于使用。你只需要传入你的坐标,它就会删除所有多余的点。

enter image description here

simplify(points, tolerance, highQuality)
points参数应包含格式为{x: 123, y: 123}的坐标数组。(之后您可以将其转换回所需的格式。) tolerance应该是十进制度数的精度。例如,11米的0.0001。增加此数字将减小输出大小。
如果您不介意等待几毫秒,将highQuality设置为true以获得更好的结果。

1

如果您可以安装PostGIS,我认为这很容易,因为他们提供了一个安装程序,那么您就可以导入数据并执行snaptogrid()st_simplify(),而在MySQL中我找不到相应的功能。如果您决定使用PostGIS,我建议这样做,因为它将帮助您解决未来的问题,我可以为您提供详细信息。

现在,对于一个简单的自定义解决方案,您可以通过截取或舍入坐标的一些最后数字来减小大小,然后合并相同的坐标,实际上会得到一个简单的snaptogrid()。

希望能帮到您。


0

很可能你想把点分成两半并尝试我的Javascript函数:

function shortenAndShow ( polyline, color ) {
  var dist = 0, copyPoints = Array ( );
  for ( var n = 0, var end = polyline.getVertexCount ( ) - 1; n < end ; n++ ) {
    dist += polyline.getVertex ( n ).distanceFrom ( polyline.getVertex ( n +1 ) );
    copyPoints.push ( polyline.getVertex (n) );
   }
   var lastPoint = copyPoints [copyPoints.length-1];
   var newLine = new GPolyline (copyPoints, color, 2, 1);
   gmap2.addOverlay ( newLine );
} 

0

我同意Unreason的答案,该网站支持GeoJson格式。我在我的网站上使用了它,并且它减少了我的geoJson文件大小,但我认为你也需要这个世界国家GeoJson


仅提供链接的答案应该作为评论。 - NSNoob
@NSNoob 是的,我想评论Unreason,但我没有50个声望。 - Sun

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接