Q-bertsuit
Q-bertsuit

Reputation: 3437

The NetTopologySuit library gives very different results compared to the SqlGeography library

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

Answers (2)

FObermaier
FObermaier

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

Dawood Awan
Dawood Awan

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.

enter image description here

@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.

enter image description here

So obviously their intersections will be different.One is a line string, the other is a Multi-Line string.

enter image description here

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

Related Questions