Geo Fencing - point inside/outside polygon

后端 未结 16 1752
我在风中等你
我在风中等你 2020-11-28 02:15

I would like to determine a polygon and implement an algorithm which would check if a point is inside or outside the polygon.

Does anyone know if there is any exampl

16条回答
  •  庸人自扰
    2020-11-28 02:59

    Relating to kobers answer I worked it out with more readable clean code and changed the longitudes that crosses the date border:

    public bool IsPointInPolygon(List polygon, double latitude, double longitude)
    {
      bool isInIntersection = false;
      int actualPointIndex = 0;
      int pointIndexBeforeActual = polygon.Count - 1;
    
      var offset = calculateLonOffsetFromDateLine(polygon);
      longitude = longitude < 0.0 ? longitude + offset : longitude;
    
      foreach (var actualPointPosition in polygon)
      {
        var p1Lat = actualPointPosition.Latitude;
        var p1Lon = actualPointPosition.Longitude;
    
        var p0Lat = polygon[pointIndexBeforeActual].Latitude;
        var p0Lon = polygon[pointIndexBeforeActual].Longitude;
    
        if (p1Lon < 0.0) p1Lon += offset;
        if (p0Lon < 0.0) p0Lon += offset;
    
        // Jordan curve theorem - odd even rule algorithm
        if (isPointLatitudeBetweenPolyLine(p0Lat, p1Lat, latitude)
        && isPointRightFromPolyLine(p0Lat, p0Lon, p1Lat, p1Lon, latitude, longitude))
        {
          isInIntersection = !isInIntersection;
        }
    
        pointIndexBeforeActual = actualPointIndex;
        actualPointIndex++;
      }
    
      return isInIntersection;
    }
    
    private double calculateLonOffsetFromDateLine(List polygon)
    {
      double offset = 0.0;
      var maxLonPoly = polygon.Max(x => x.Longitude);
      var minLonPoly = polygon.Min(x => x.Longitude);
      if (Math.Abs(minLonPoly - maxLonPoly) > 180)
      {
        offset = 360.0;
      }
    
      return offset;
    }
    
    private bool isPointLatitudeBetweenPolyLine(double polyLinePoint1Lat, double polyLinePoint2Lat, double poiLat)
    {
      return polyLinePoint2Lat <= poiLat && poiLat < polyLinePoint1Lat || polyLinePoint1Lat <= poiLat && poiLat < polyLinePoint2Lat;
    }
    
    private bool isPointRightFromPolyLine(double polyLinePoint1Lat, double polyLinePoint1Lon, double polyLinePoint2Lat, double polyLinePoint2Lon, double poiLat, double poiLon)
    {
      // lon <(lon1-lon2)*(latp-lat2)/(lat1-lat2)+lon2
      return poiLon < (polyLinePoint1Lon - polyLinePoint2Lon) * (poiLat - polyLinePoint2Lat) / (polyLinePoint1Lat - polyLinePoint2Lat) + polyLinePoint2Lon;
    }
    

提交回复
热议问题