NetTopologySuite / NetTopologySuite.IO.GeoJSON

GeoJSON IO module for NTS.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[Discussion] deserializing decimals from doubles / missing methods from StjObjects

cjahermanns opened this issue · comments

commented

Hi guys,
as described in NetTopologySuite/NetTopologySuite.IO.ShapeFile#54, after deserializing double values from Features, they become decimal and can't be written to ShapeFiles. The general behavior of deserialized StjObjects (like StjFeature or StjAttributeTable) differs from the non deserialized "normal" objects behavior. Are there any plans to integrate methods like StjAttributeTable.Add() or StjAttributeTable.Delete() and change the decimal deserialization implementation?

after deserializing double values from Features

Technically, once these values make it into GeoJSON, they are no longer double; they are, instead, the decimal approximations bundled up in JSON "number" values.

The idea behind representing JSON "number" values as System.Decimal in STJ features is because this more perfectly preserves the information that we were given in the text file. We keep the underlying DOM representation of the JSON document around so that you can use these extension methods to convert the value from JSON differently than how IAttributesTable is implemented.

can't be written to ShapeFiles

This part was correctly flagged as an issue with the shapefile implementation, not an issue with STJ. It's particularly annoying because the DBF format stores decimal values in text as well, and so it really should have been doing the same all along...

The general behavior of deserialized StjObjects (like StjFeature or StjAttributeTable) differs from the non deserialized "normal" objects behavior.

When serializing an object to a stream in a standard interchange format such as GeoJSON or Shapefile, we can only translate your data into that format as faithfully as we can. The intended result is not just "will I be able to load this back up later, using the same version of this library?", but also "will a completely different third-party application be able to load this back up later?".

Similarly in the other direction: when we see GeoJSON or Shapefile data, we don't look for any NTS-specific flags on the instance or anything. We treat it as if it may have come from a completely different third-party application, following the rules of the format.

As a consequence, a serialize --> deserialize round-trip may not fully preserve the exact shape of your original objects. For STJ, we make a best-effort attempt to faithfully represent the contents of the document that we're given, but since JSON lacks type information, we make trade-offs about how to represent the values as object. Most relevant to this, whenever we have a "number" value, we chose to box it as System.Decimal no matter what the actual value is, since this ensures consistent behavior when interacting with the object boxes, while allowing you to extract the values back out using the strongly-typed extension methods if you have more specific information about what's in the box.

Are there any plans to integrate methods like StjAttributeTable.Add() or StjAttributeTable.Delete() [...]?

At the moment, no. Nested objects in StjAttributesTable are exposed as other StjAttributesTable instances that point to slices of the same underlying JSON data, so if we wanted to support editing the values, we would need to do something complicated.

Are there any plans to [...] change the decimal deserialization implementation?

At the moment, no. If you have some specific reason why decimal won't work for you, then the intent is for you to use the facilities that we provide (or a System.Convert.ToX method) to interpret the data as a different type than the one-size-fits-all.

Unlike the previous one, I do see a kind of path forward for making this work, at some unknown point in the future: we could allow the callers to provide GeoJsonConverterFactory a list of "strategies" for converting JSON fragments to the .NET model.

  • For example, we could implement something where the caller gives us something like a mapping from a JSONPath to the CLR type that it should deserialize as by default when extracting it from an IAttributesTable.
commented

Ok, so I definitely should have done more research beforehand!

Thank you for this very nice explanation. I didn't really think some things I tried to accomplish through. The whole (JSON) (de)serialization topic is completely new to me and I just started to get the gist of it. But I now understand some of the design choices you made with the StjObjects and the restrictions you had, much better.

I saw that you consider reworking the whole ShapeFile read (and write) routine(s). I will definitely follow this approach and maybe replace my workaround with a propper solution you eventually offer.

Thank you again for this great answer! I appreciate your time and effort in helping me as a beginner in programming.