jts icon indicating copy to clipboard operation
jts copied to clipboard

WKT output is no longer compatible with SQLServer

Open aaime opened this issue 5 years ago • 6 comments

Currently generating a linestring with z values results in "POINT Z(x y z)". This has been introduced in https://github.com/locationtech/jts/commit/b464d54960cf0c99195a0f93a26ccfeab55c7f55

However, SQLServer does not understand the Z specifier, and would like to get a "POINT(x y z,)" instead.

E.g.:

1> DECLARE @g geometry;  
2> SET @g = geometry::STGeomFromText('POINT(1 2 3 4)', 0);  
3> SELECT @g.STAsText();  
4> SELECT @g.AsTextZM();  
5> go
POINT (1 2)
POINT (1 2 3 4)

while trying to use "POINT Z" results in the following

1> DECLARE @g2 geometry= 'POINT Z(1 1 0)'; 
2> GO
Msg 6522, Level 16, State 1, Server 4dd2f9838640, Line 1
A .NET Framework error occurred during execution of user-defined routine or aggregate "geometry": 
System.FormatException: 24142: Expected "(" at position 6. The input has "Z".
System.FormatException: 
   at Microsoft.SqlServer.Types.WellKnownTextReader.RecognizeToken(Char token)
   at Microsoft.SqlServer.Types.WellKnownTextReader.ParsePointText(Boolean parseParentheses)
   at Microsoft.SqlServer.Types.WellKnownTextReader.ParseTaggedText(OpenGisType type)
   at Microsoft.SqlServer.Types.WellKnownTextReader.Read(OpenGisType type, Int32 srid)
   at Microsoft.SqlServer.Types.SqlGeometry.GeometryFromText(OpenGisType type, SqlChars text, Int32 srid)
   at Microsoft.SqlServer.Types.SqlGeometry.Parse(SqlString s)

As far as I can see, there is no way to get the desired output, if the writer is not setup to produce Z values, it won't output the Z ordinates. I don't see a way to subclass and override this behavior, all relevant methods are private...

aaime avatar Jan 10 '20 09:01 aaime

This was caused as a result of PR #291. It's not clear to me if this change was intended (@FObermaier @jodygarnett comments?).

Seems like there are at least two options to mitigate this:

  • Revert to the old WKT output for XYZ, and provide a WKTWriter.setXXX method to request GEOM Z format
  • Keep GEOM Z as the default, and provide a WKTWriter.setXXX method to request the old format

Any thoughts on what the resolution should be? (I have lost track of where the standards ended up for WKT).

dr-jts avatar Jan 10 '20 18:01 dr-jts

I think that feeding a database server with WKT is not a good choice in the first place. String.replace(“Z“, ““) will probably help.

I am no expert in BNF interpretation but to me writing the Z literal is correct. (OGC SFA-CA 1.2.1, Ch. 8). So -for my part- this was intentional.

FObermaier avatar Jan 10 '20 21:01 FObermaier

It was also intensional on my part and agrees with PostGIS WKT output. We may wish to report a bug to SQLServer?

If you wanted a flag to use POINT (vs POINTZ, POINTM, POINTZM) writer.setDimensionalitySuffix(false) would be appropriate (based on reading postgis documentation).

jodygarnett avatar Jan 10 '20 21:01 jodygarnett

Thanks for confirming the spec, @FObermaier . And good point about PostGIS supporting that version of WKT for output (although I note that it also supports the old-style syntax for read, which is more relevant).

So the minimal fix for this is to add a flag for the WKTWriter. I lean towards setDimensionSuffix. Presumably this should NOT drop an M tag, since that would cause ambiguity? And might as well support ZM too?

@aaime Any comments on whether this works for your use case? And how compatible it is with SQL Server?

dr-jts avatar Jan 10 '20 22:01 dr-jts

@dr-jts, I believe that having such setter would work. I found this while working on curves support in SQL Server. After this report I switched the data store to using the GeoTools WKTWriter2 (which can write curves), and the problem went away.... sorry for the noise :-D

In the meantime I've also opened a ticket against the Microsoft JDBC driver (mostly because it's open source and had a clear way to report issues, although the report should probably have gone against SQL Server itself): https://github.com/microsoft/mssql-jdbc/issues/1228

aaime avatar Jan 11 '20 10:01 aaime

Any thoughts on what the resolution should be?

For reference, on the NetTopologySuite side, we did: NetTopologySuite/NetTopologySuite@0810335

airbreather avatar Mar 14 '20 13:03 airbreather