ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

javascript – 谷歌地图多边形自相交检测

2019-08-30 15:42:04  阅读:238  来源: 互联网

标签:shapes javascript polygon google-maps-api-3 self-intersection


我正在尝试使用Google Maps API V3多边形实现多边形自相交算法.
目标只是检测是或否,用户绘制的简单多边形是自交叉.

我找到了this very interesting link,但它假设多边形顶点的坐标是以geoJSON格式给出的.但是,这不是我的情况;我只能使用polygon.getPath()将多边形坐标检索到polygoncomplete事件中.

这是我检索坐标的方式:

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

如何将polygon.getpath()给出的坐标转换为geoJSON格式?
有没有更好的方法来检测Google地图多边形是否自相交?如果是这样,请您分享一些代码示例,而不仅仅是数学解释?

PS:我看过this链接,但没有任何代码示例,我有点迷失.

解决方法:

您无需将它们转换为GeoJSON即可使用jsts library,您需要将它们从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], boundaries[i][0]));
  }
  return coordinates;
};

使用此方法,它会将google.maps.Polygon路径中的坐标转换为JTS格式:

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

然后像这样改变“findSelfIntersects”:

/**
 * 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)

代码段:

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>

标签:shapes,javascript,polygon,google-maps-api-3,self-intersection
来源: https://codeday.me/bug/20190830/1769385.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有