I need to create a Polygon so that in my Entity Framework query I can do:
point.Intersects(polygon)
The code to create the point is:
var center = new TopologyPoint(longitude, latitude)
{
SRID = 4326
};
I think the code to create the rectangle is:
// Define the four corners of the rectangle
Coordinate lowerLeft = new Coordinate(box.West, box.South);
Coordinate upperLeft = new Coordinate(box.West, box.North);
Coordinate upperRight = new Coordinate(box.East, box.North);
Coordinate lowerRight = new Coordinate(box.East, box.South);
// Create a linear ring (a closed line string) from the corners
Coordinate[] coordinates = new Coordinate[] { lowerLeft, upperLeft, upperRight, lowerRight, lowerLeft };
LinearRing shell = new LinearRing(coordinates);
// Create the polygon from the linear ring
var rectangle = new Polygon(shell);
Is this correct? Will this be matching lat/long units? Or do I need something like the SRID = 4326
for the Point?
I am using this to determine what entities to return from a query to then populate an Azure Map with pins. Will the earth's curvature mean it will return points that are not visible in the map (ok)? Or does it mean it will not return some points that are on the edge of the bounding box of the map?
Should I add to the extents of the rectangle so I'm sure to get everything? If so, is there a multiple of the width & height to add to get everything?
As noted int he comments, ring orientation matters in spatial databases, and for a simple exterior polygon, you will want the points to be order in counter-clockwise order.
To be a valid polygon in a spatial database there are a few other requirements as noted here: https://learn.microsoft.com/en-us/sql/relational-databases/spatial/polygon?view=sql-server-ver16 For your scenario the main two requirements to be aware of is the point order (ring orientation), and that the first and last point are the same.
I believe you will need to set the SRID as the spatial database EF connects to will likely check that the SRID's between the polygon and the data in your database match.
The earths curvature and bounding boxes actually does get complicated here. Azure Maps uses what's called Pseudo-Mercator map projection (EPSG:3857) which is how the map is stretched out (most online maps use this projection). However, using the Geography type with 4326 will use an ellipsoidal projection (squashed sphere). As such a large bounding box from a Mercator map will not match up to the same area as the ellipsoidal projection along the north/south edges of the bounding box (the middle of an edge can end up including or excluding a bit of area. This effect becomes more noticeable the further you get from the equator. This is why the Geography type in SQL does not have a STEnvelope
method, but the Geometry type does. Instead the Geography type has EnvelopeCenter
and EnvelopeAngle
methods which is a more accurate bounding area. If you take the polygon you are calculating and display it in as a SQL Geography object in the SQL management studio, you will see it looks like the following:
Now there are a couple of options here:
geometry::STGeomFromWKB(MyGeographyColumn.STAsBinary(), 4326);
Here is a related thread: In Leaflet, how to convert leaflet viewport bounding box in EPSG3857 so I can retrieve data stored in EPSG4326Note, if you convert your Geography data to Geometry some calculations, such as distance, will not provide desired results. 4326 data as a Geometry will provide distances in degrees and not meters. While Geography distance calculations will provide meter distances.