-
-
Notifications
You must be signed in to change notification settings - Fork 22
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
STContains/STWithin returning all results even if isn't inside #21
Comments
After a bit of manual playing around I was able to accomplish the task using the following. var geometryFactory = NtsGeometryServices.Instance.CreateGeometryFactory(srid: options.Value.Srid);
foreach (var state in collection.Features)
{
IGeometry stateGeo = null;
switch (state.Geometry.Type)
{
case GeoJSON.Net.GeoJSONObjectType.Polygon:
var poly = state.Geometry as Polygon;
var coords = poly.Coordinates.SelectMany(i => i.Coordinates.Select(x => new GeoAPI.Geometries.Coordinate(x.Longitude, x.Latitude)));
stateGeo = geometryFactory.CreatePolygon(coords.ToArray());
break;
case GeoJSON.Net.GeoJSONObjectType.MultiPolygon:
// ...
break;
}
var records = myData
.Where(i => i.Location.Within(stateGeo));
if(records != null && records.Count() > 0)
{
state.Properties.Add("myGeoJsonData", records.Count());
}
} I should of also added in the first post that I was using the new .net core/EF spatial data which seems to be different from the SqlGeography/SqlGeometry. Though I figured what I originally had should of still worked. For now I have found a work around. I am still needing to figure out MultiPolygon but shouldn't be too hard since I have a regular one done. |
Hi @lzinga ! |
Nuget Packages Used were the following with both being the latest version. I did indeed try with SqlGeometry instead of SqlGeography but then no data would should up on the map, I did play with the way the coordinates were entered too but didn't seem to change anything. |
This point is perfectly inside Washington. (see https://www.google.com/maps/place/47%C2%B013'18.8%22N+122%C2%B026'52.4%22W/@47.3602567,-124.4208462,6z/data=!4m5!3m4!1s0x0:0x0!8m2!3d47.2219!4d-122.4479) The code I used was : var geo = state.ToSqlGeography(4326);
if (geo.STIsValid().IsFalse) geo = geo.MakeValid();
bool within = SqlGeography.Point(47.2219, -122.4479, 4326).STWithin(geo).Value;
bool intersects = SqlGeography.Point(47.2219, -122.4479, 4326).STIntersects(geo).Value;
// both are true for Washington I am missing something here ? |
So the point should exist within Washington state but it also shows for all the states highlighted east of Utah as shown on the map when it is trying to select records with this code: var records = myData.Where(i => SqlGeography.Point(i.Location.Y, i.Location.X, options.Value.Srid).MakeValid().STWithin(geo).Value); and the |
@lzinga I found what's the problem. It's a classic one with geography types : the ring orientation of the geojson states does not follow the "left-hand-rule". More on that here on this excellent blog by @alastaira (I had to mention you!), the king-of-sql-spatial-who-then-switched-to-independant-gaming. So if you add the @alastaira's workaround : var geo = state.ToSqlGeography(4326);
if (geo.STIsValid().IsFalse) geo = geo.MakeValid(); // Make valid if not (warning this can alter geometry)
if (geo.EnvelopeAngle() >= 90) geo = geo.ReorientObject(); // reorient if needed This should work! |
Awesome, thanks! Not exactly sure what changed from my code before when the code was working but now I get a dll error. I didn't change framework or anything
I am sure the code above will fix the original issue though, just need to solve this problem now that appeared out of no where lol. |
Cool ! Please mark as resolved if it is ok for you. |
This is a .net core 2.2 application, I did the equivalent of the above and it alerts about Thanks! |
Hey I am not sure if I am doing something wrong or not. I am using GeoJson for states and am looking through my own data to add my data to it.
The reason the Y goes in the latitude and X goes in the longitude is because of this. It works for 2 of the states (Washingotn and Utah which is where the data is expected) however it ends up filling up other states as well.
When I place a break point in the if statement it starts off with Washington with the expected results, and then Utah, but then it breaks on Arkansas.
The Washington
geo
data for the boundry of the state comes out to beand here is the Arkansas
The
records
variable inside the if statement for these states is filled with every result that is with inmyData
a total of 21 records. Like I mentioned both Utah and Washington (which actually has data) turn out fine but all the others East of Utah are for some reason getting all records even if their latitude/longitude don't fall with in the polygons.I have tried both
SqlGeography.Point( ... ).STWithin(geo)
andgeo.STContains(SqlGeography.Point( ... ))
both return the same results.Lastly here is one of the points that is showing up in a state that shouldn't have any data
{POINT (47.2219 -122.4479)}
yet some how the methods above are showing true even though the point shouldn't exist within that location.Let me know if you need any more information, as I am really wanting to try to figure this out.
The text was updated successfully, but these errors were encountered: