Google Maps多边形自相交检测 [英] Google Maps Polygons self intersecting detection

查看:263
本文介绍了Google Maps多边形自相交检测的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图从Google Maps API V3多边形实现多边形自交算法

目标是检测是或否,是否绘制简单的多边形由用户自行过关。



我发现这个非常有趣的链接,但它假定多边形顶点的坐标在 geoJSON 格式。但是,这不是我的情况;我只能使用 polygon.getPath()将多边形坐标检索到 polygoncomplete 事件中。



这是我检索坐标的方式:

  google.maps.event.addDomListener (drawingManager,'polygoncomplete',function(polygon)
{
var polygonBounds = polygon.getPath();
var coordinates = [];

for i = 0; i< polygonBounds.length; i ++)
{
vertice = {
Latitude:polygonBounds.getAt(i).lat(),
Longitude :polygonBounds.getAt(i).lng()
}

coordinates.push(vertice);
}
}
polygon.getpath()



$ b> em> geoJSON 格式?

有没有更好的方法来检测Google Maps多边形是否自相交?如果有,请分享一下一些代码示例,而不仅仅是一个数学解释?



PS:我见过这个链接,但没有任何代码示例,我有点迷路。

解决方案

您不需要将它们转换为GeoJSON以使用 jsts库,您需要将它们从google.maps.LatLng对象转换为jsts.geom.Coordinates。而不是使用它:

  var geoJSON2JTS = function(boundaries){
var coordinates = [];
for(var i = 0; i< boundaries.length; i ++){
coordinates.push(new jsts.geom.Coordinate(
boundaries [i] [1] I] [0]));
}
返回坐标;
};

使用它可以将google.maps.Polygon路径中的坐标转换为JTS格式: / p>

  var googleMaps2JTS =函数(边界){
var coordinates = [];
for(var i = 0; i< boundaries.getLength(); i ++){
coordinates.push(new jsts.geom.Coordinate(
boundaries.getAt(i).lat (),boundaries.getAt(i).lng()));
}
返回坐标;
};

然后像下面这样改变findSelfIntersects:

  / ** 
* findSelfIntersects
*
*检测多边形中的自相交。
*
* @param {object} google.maps.Polygon路径坐标。
* @return {array}交点点数组。
* /
var findSelfIntersects = function(googlePolygonPath){
var coordinates = googleMaps2JTS(googlePolygonPath);
var geometryFactory = new jsts.geom.GeometryFactory();
var shell = geometryFactory.createLinearRing(coordinates);
var jstsPolygon = geometryFactory.createPolygon(shell);

//如果几何体是一个简单的线性环,不要
//尝试找到自交点。
var validator = new jsts.operation.IsSimpleOp(jstsPolygon);
if(validator.isSimpleLinearGeometry(jstsPolygon)){
return;
}

var res = [];
var graph = new jsts.geomgraph.GeometryGraph(0,jstsPolygon);
var cat = new jsts.operation.valid.ConsistentAreaTester(graph);
var r = cat.isNodeConsistentArea();
if(!r){
var pt = cat.getInvalidPoint();
res.push([pt.x,pt.y]);
}
return res;
};

概念验证小提琴(赠送给HoffZ)

代码段:

var mapOptions = {zoom:16,center:new google.maps.LatLng(62.1482,6.0696)}; var drawingManager = new google.maps.drawing.DrawingManager({drawingControl:false,polygonOptions:{editable:true}}); var googleMaps2JTS = function(boundaries){var coordinates = []; for(var i = 0; i< boundaries.getLength(); i ++){coordinates.push(new jsts.geom.Coordinate(boundaries.getAt(i).lat(),boundaries.getAt(i).lng ))); } coordinates.push(坐标[0]);的console.log(坐标);返回坐标;}; / ** * findSelfIntersects * *检测多边形中的自相交。 * * @param {object} google.maps.Polygon路径坐标。 * @return {array}交点点数组。 * / var findSelfIntersects = function(googlePolygonPath){var coordinates = googleMaps2JTS(googlePolygonPath); var geometryFactory = new jsts.geom.GeometryFactory(); var shell = geometryFactory.createLinearRing(coordinates); var jstsPolygon = geometryFactory.createPolygon(shell); //如果几何体是一个简单的线性环,不要//尝试找到自我交点。 var validator = new jsts.operation.IsSimpleOp(jstsPolygon); if(validator.isSimpleLinearGeometry(jstsPolygon)){return; } var res = []; var graph = new jsts.geomgraph.GeometryGraph(0,jstsPolygon); var cat = new jsts.operation.valid.ConsistentAreaTester(graph); var r = cat.isNodeConsistentArea(); if(!r){var pt = cat.getInvalidPoint(); res.push([pt.x,pt.y]); } return res;}; var map = new google.maps.Map(document.getElementById(map),mapOptions); drawingManager.setDrawingMode(google.maps.drawing.OverlayType.POLYGON); drawingManager.setMap(map); google.maps.event.addListener(drawingManager,'polygoncomplete',function(polygon){// var polyPath = event.overlay.getPath(); var intersects = findSelfIntersects(polygon.getPath()); console.log(intersects) ; if(intersects&& intersects.length){alert('Polygon intersects its');} else {alert('Polygon does not intersect itself');}});

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

< script src =https ://maps.google.com/maps/api/js?libraries = drawing>< / script>< script src =https://cdn.rawgit.com/bjornharrtell/jsts/gh-pages/ 1.4.0 / jsts.min.js>< /脚本>< p为H.在地图上绘制多边形< / p>< div id =map>< / div>


I'm trying to implement a polygon self intersection algorithm from Google Maps API V3 polygons.
The goal is just to detect if yes or no, a simple polygon drawn by the user is self crossing.

I have found this very interesting link, but it assumes that coordinates of the polygon's vertices are given on geoJSON format. However, this isn't my case ; I'm only able to retrieve polygons coordinates using polygon.getPath() into a polygoncomplete event.

This is how i retrieve the coordinates :

google.maps.event.addDomListener(drawingManager, 'polygoncomplete', function(polygon)
{
    var polygonBounds = polygon.getPath();
    var coordinates = [];

    for(var i = 0 ; i < polygonBounds.length ; i++)
    {            
        vertice = {
                      "Latitude" : polygonBounds.getAt(i).lat(),
                      "Longitude" : polygonBounds.getAt(i).lng()
                  }

        coordinates.push(vertice );
    }
}

How can I transform these coordinates, given by polygon.getpath() into geoJSON format ?
Is there any better way to detect if a Google Maps polygon is self-intersecting ? If so, could you please share some code sample and not just a mathematical explaination ?

PS : I've seen this link but without any code sample, I'm a little bit lost.

解决方案

You don't need to convert them to GeoJSON to use the jsts library, you need to convert them from google.maps.LatLng objects to jsts.geom.Coordinates. Instead of using this:

var geoJSON2JTS = function(boundaries) {
  var coordinates = [];
  for (var i = 0; i < boundaries.length; i++) {
    coordinates.push(new jsts.geom.Coordinate(
        boundaries[i][1], boundaries[i][0]));
  }
  return coordinates;
};

Use this, which will convert coordinates in a google.maps.Polygon path to the JTS format:

var googleMaps2JTS = function(boundaries) {
  var coordinates = [];
  for (var i = 0; i < boundaries.getLength(); i++) {
    coordinates.push(new jsts.geom.Coordinate(
        boundaries.getAt(i).lat(), boundaries.getAt(i).lng()));
  }
  return coordinates;
};

then change "findSelfIntersects" like this:

/**
 * findSelfIntersects
 *
 * Detect self-intersections in a polygon.
 *
 * @param {object} google.maps.Polygon path co-ordinates.
 * @return {array} array of points of intersections.
 */
var findSelfIntersects = function(googlePolygonPath) {
  var coordinates = googleMaps2JTS(googlePolygonPath);
  var geometryFactory = new jsts.geom.GeometryFactory();
  var shell = geometryFactory.createLinearRing(coordinates);
  var jstsPolygon = geometryFactory.createPolygon(shell);

  // if the geometry is aleady a simple linear ring, do not
  // try to find self intersection points.
  var validator = new jsts.operation.IsSimpleOp(jstsPolygon);
  if (validator.isSimpleLinearGeometry(jstsPolygon)) {
    return;
  }

  var res = [];
  var graph = new jsts.geomgraph.GeometryGraph(0, jstsPolygon);
  var cat = new jsts.operation.valid.ConsistentAreaTester(graph);
  var r = cat.isNodeConsistentArea();
  if (!r) {
    var pt = cat.getInvalidPoint();
    res.push([pt.x, pt.y]);
  }
  return res;
};

proof of concept fiddle (credit to HoffZ)

code snippet:

var mapOptions = {
  zoom: 16,
  center: new google.maps.LatLng(62.1482, 6.0696)
};

var drawingManager = new google.maps.drawing.DrawingManager({
  drawingControl: false,
  polygonOptions: {
    editable: true
  }
});

var googleMaps2JTS = function(boundaries) {
  var coordinates = [];
  for (var i = 0; i < boundaries.getLength(); i++) {
    coordinates.push(new jsts.geom.Coordinate(
      boundaries.getAt(i).lat(), boundaries.getAt(i).lng()));
  }
  coordinates.push(coordinates[0]);
  console.log(coordinates);
  return coordinates;
};

/**
 * findSelfIntersects
 *
 * Detect self-intersections in a polygon.
 *
 * @param {object} google.maps.Polygon path co-ordinates.
 * @return {array} array of points of intersections.
 */
var findSelfIntersects = function(googlePolygonPath) {
  var coordinates = googleMaps2JTS(googlePolygonPath);
  var geometryFactory = new jsts.geom.GeometryFactory();
  var shell = geometryFactory.createLinearRing(coordinates);
  var jstsPolygon = geometryFactory.createPolygon(shell);

  // if the geometry is aleady a simple linear ring, do not
  // try to find self intersection points.
  var validator = new jsts.operation.IsSimpleOp(jstsPolygon);
  if (validator.isSimpleLinearGeometry(jstsPolygon)) {
    return;
  }

  var res = [];
  var graph = new jsts.geomgraph.GeometryGraph(0, jstsPolygon);
  var cat = new jsts.operation.valid.ConsistentAreaTester(graph);
  var r = cat.isNodeConsistentArea();
  if (!r) {
    var pt = cat.getInvalidPoint();
    res.push([pt.x, pt.y]);
  }
  return res;
};


var map = new google.maps.Map(document.getElementById("map"), mapOptions);
drawingManager.setDrawingMode(google.maps.drawing.OverlayType.POLYGON);
drawingManager.setMap(map);
google.maps.event.addListener(drawingManager, 'polygoncomplete', function(polygon) {
  //var polyPath = event.overlay.getPath();
  var intersects = findSelfIntersects(polygon.getPath());
  console.log(intersects);
  if (intersects && intersects.length) {
    alert('Polygon intersects itself');
  } else {
    alert('Polygon does not intersect itself');
  }
});

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

<script src="https://maps.google.com/maps/api/js?libraries=drawing"></script>
<script src="https://cdn.rawgit.com/bjornharrtell/jsts/gh-pages/1.4.0/jsts.min.js"></script>
<p>
  Draw a polygon on the map
</p>

<div id="map">

</div>

这篇关于Google Maps多边形自相交检测的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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