Google Maps Polygons self intersecting detection

后端 未结 1 1389
南方客
南方客 2020-12-06 08:03

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 polyg

相关标签:
1条回答
  • 2020-12-06 08:40

    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&key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></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>

    0 讨论(0)
提交回复
热议问题