I have a shapefile defining shapes to cover a city. I also have a set of coordinates defined by latitude and longitude.
I need to be able to determine if these points are within any of the shapes in the shapefile.
Currently I'm trying to use easygis.net to figure this out, but it doesn't seem to be working.
I believe the coordinates in the shapefile are in UTM but have an offset northing, and I don't know how to correct it, translate it to lat/long, or convert my lat/long pairs to match.
I've been looking at other libraries like dotspatial and sharpmap, but I don't see intuitive answer to the problem.
At the same time, I'm sure this is a problem that has been solved. Are there any libraries that do this easily? Or how do I convert the offset UTM of the map to lat/long, or my lat/long points to this offset UTM?
Draw a horizontal line to the right of each point and extend it to infinity. Count the number of times the line intersects with polygon edges. A point is inside the polygon if either count of intersections is odd or point lies on an edge of polygon.
If the number of times this ray intersects the line segments making up the polygon is even then the point is outside the polygon. Whereas if the number of intersections is odd then the point (xp,yp) lies inside the polygon.
To perform a Point in Polygon (PIP) query in Python, we can resort to the Shapely library's functions . within(), to check if a point is within a polygon, or . contains(), to check if a polygon contains a point.
Use polygon. contains(point) to test if point is inside ( True ) or outside ( False ) the polygon.
Here is some sample code on how you might use DotSpatial to firstly handle reprojection and secondly to test whether points are in a polygon, using the Contains method.
public bool PointInShape() {
// Load a shapefile. If the shapefile is already using your custom projection, we don't need to change it.
Shapefile wierdShapefile = Shapefile.OpenFile("C:\\MyShapefile.shp");
// Note, if your shapefile with custom projection has a .prj file, then we don't need to mess with defining the projection.
// If not, we can define the projection as follows:
// First get a ProjectionInfo class for the normal UTM projection
ProjectionInfo pInfo = DotSpatial.Projections.KnownCoordinateSystems.Projected.UtmNad1983.NAD1983UTMZone10N;
// Next modify the pINfo with your custom False Northing
pInfo.FalseNorthing = 400000;
wierdShapefile.Projection = pInfo;
// Reproject the strange shapefile so that it is in latitude/longitude coordinates
wierdShapefile.Reproject(DotSpatial.Projections.KnownCoordinateSystems.Geographic.World.WGS1984);
// Define the WGS84 Lat Lon point to test
Coordinate test = new Coordinate(-120, 40);
foreach (Feature f in wierdShapefile.Features) {
Polygon pg = f.BasicGeometry as Polygon;
if (pg != null)
{
if (pg.Contains(new Point(test)))
{
// If the point is inside one of the polygon features
return true;
}
}
else {
// If you have a multi-part polygon then this should also handle holes I think
MultiPolygon polygons = f.BasicGeometry as MultiPolygon;
if (polygons.Contains(new Point(test))) {
return true;
}
}
}
return false;
}
Or how do I convert the offset UTM of the map to lat/long, or my lat/long points to this offset UTM?
This requires reprojecting your points (or the shapefile's data). This can be done via Proj4Net (unless your GIS already supports it).
Once that's done, then it's a point in polygon test. There are many options for this, though I often use the winding number method.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With