Reputation: 3437
Update:
I changed the polygon as suggested, and I now get a LineString instead of a MultiLine string, but the difference in coordinates are still the same:
I'm comparing two libraries for working with spatial data, but they are giving me quite different results for the same input.
Here is a test using Microsoft.SqlServer.Types library
// Line from New York to Paris
SqlGeography line = SqlGeography.STLineFromText(new System.Data.SqlTypes.SqlChars("LINESTRING(-73.935242 40.730610, 2.349014 48.864716)"), 4326);
// Polygon in the Atlantic
SqlGeography polygon = SqlGeography.STPolyFromText(new System.Data.SqlTypes.SqlChars("POLYGON((-40 60, -40 30, -20 30, -20 60, -40 60))"), 4326);
SqlGeography intersection = line.STIntersection(polygon);
{LINESTRING (-19.99999999999997 52.21038270929611, -39.99999999999993 51.451383473748834)}
Here is a test with the NetTopologySuite:
var polygonText = "POLYGON((-40 60, -40 30, -20 30, -20 60, -40 60))";
string lineText = "LINESTRING(-73.935242 40.730610, 2.349014 48.864716)";
var rdr = new NetTopologySuite.IO.WKTReader();
var geometryPolygon = rdr.Read(polygonText);
var geometryLine = rdr.Read(lineText);
var polygon = _geometryFactory.CreatePolygon(geometryPolygon.Coordinates);
var line = _geometryFactory.CreateLineString(geometryLine.Coordinates);
var intersects = line.Intersection(polygon);
{LINESTRING (-40 44.34908739019244, -20 46.48166531033365)}
Any idea why there is such a large difference in the result?
Upvotes: 0
Views: 753
Reputation: 985
The problem is that NetTopologySuite only performs planar 2d geometry operations.
SqlServer's geography
type performs geodesic operations within computation of distances and/or other spatial operations.
If you use SqlServer's geometry
type you should be getting -more or less- the same results.
Upvotes: 1
Reputation: 7348
UPDATE:
The question is still not very clear, using SqlServerTypes and SQL server when checking for intersects I get a MultiLineString
geography type. But question suggests it's a LineString
This is what I get both in SQL Server and SqlServerTypes
MULTILINESTRING ((2.349014 48.864716, -19.99999999999997 52.21038270929611), (-39.99999999999993 51.451383473748834, -73.935242 40.73061))
Reversing the Polygon in SQL.
The original Polygon seems wrong to me, as in the Question OP says it's a Polygon in the Atlantic Ocean - but in fact it is a Polygon covering the entire Earth except a Polygon in the Atlantic Ocean.
DECLARE @polygon geography, @rvrPolygon geography;
SET @polygon = geography::STPolyFromText('POLYGON((-40 60, -20 60, -20 30, -40 30, -40 60))', 4326);
SET @rvrPolygon = @polygon.ReorientObject()
DECLARE @lineString geography;
SET @lineString = geography::STLineFromText('LINESTRING(-73.935242 40.730610, 2.349014 48.864716)', 4326);
Select
rvrPol = @rvrPolygon,
[email protected](),
[email protected](),
polygon = @polygon,
linestring = @lineString,
Intersections = @polygon.STIntersection(@lineString).ToString(),
IntersectsRvrPoly = @rvrPolygon.STIntersection(@lineString).ToString()
Without reversing the Polygon it gives me (matches the SqlServerTypes):
MULTILINESTRING ((2.349014 48.864716, -19.999999999999972 52.210382709296113), (-39.999999999999929 51.451383473748834, -73.935242 40.73061))
With the reverse polygon it gives me:
LINESTRING (-19.999999999999972 52.210382709296113, -39.999999999999929 51.451383473748834)
Without the correct data and steps to replicate it's impossible to replicate in NetTopolgy to come to a conclusion as to if this is an actual bug, data issue or config issue.
Both of your WKTs are different, not sure why you are expecting the same results when the test cases are not identical.
If you fire up SQL Management Studio and Run the following Query you will understand how and why they are different.
DECLARE @polygon geography;
SET @polygon = geography::STPolyFromText('POLYGON((-40 60, -20 60, -20 30, -40 30, -40 60))', 4326);
DECLARE @lineString geography;
SET @lineString = geography::STLineFromText('LINESTRING(-73.935242 40.730610, 2.349014 48.864716)', 4326);
DECLARE @polygon1 geography;
SET @polygon1 = geography::STPolyFromText('POLYGON ((60 -40, 60 -20, 30 -20, 30 -40, 60 -40))', 4326);
DECLARE @lineString1 geography;
SET @lineString1 = geography::STLineFromText('LINESTRING (40.730610 -73.935242, 48.864716 2.349014)', 4326);
Select
@polygon.ToString(),
@lineString.ToString(),
p = @polygon,
l = @lineString,
Intt = @polygon.STIntersection(@lineString),
Intersections = @polygon.STIntersection(@lineString).ToString()
UNION ALL
Select
@polygon1.ToString(),
@lineString1.ToString(),
p = @polygon1,
l = @lineString1,
Intt = @polygon1.STIntersection(@lineString1),
Intersections = @polygon1.STIntersection(@lineString1).ToString()
If you analyze the Spatial Results Tab and select the p columns.
@polygon
is all the green section except the one I've crossed out. So that will be the entire world except that particular Polygon.
@polygon1
is the orange polygon - I've highlighted in Red.
Similarly the LineStrings are different aswell.
So obviously their intersections will be different.One is a line string, the other is a Multi-Line string.
WKT is a global standard and should be the same for both NetTopology, SQL, Microsoft.SqlServer.Types etc. Wiki
If you have another example where the WKTs are identical and still the result is not correct happy to take a look and update the answer, but at this point of time the test cases are not identical.
Upvotes: 1