|
Geometry : |
Subject: Re: [geometry] Changes in WKB (read) behaviour proposal
From: Mats Taraldsvik (mats.taraldsvik_at_[hidden])
Date: 2013-11-04 15:31:34
Hi Mateusz,
On 11/04/2013 03:26 PM, Mateusz Loskot wrote:
> (response to Mats' e-mail received off-list due to the list posting problems)
>
> On 2 November 2013 19:27, Mats Taraldsvik <mats.taraldsvik_at_[hidden]> wrote:
>> 1. The current Point parsing behaviour is to silently ignore dimensions that
>> the target point type can not handle, i.e. Z and M in a point is silently
>> ignored.
> Yes, this assumption is a kind of legacy after initial simplified
> implementation of WKB parsing. But, we should aim to remove that
> limitation.
> The whole idea is to provide implementation of WKB, and WKT as well,
> which conforms to the OpenGIS specifications as closely as possible.
> So, whenever we or Boost.Geometry users speak of WKB or WKT,
> we mean the OpenGIS.
>
>> However, this can not easily be applied further -- to linestrings,
>> polygons and multi-, because there is no way to know the dimension of points
>> in the WKB while parsing (please correct me if I'm wrong here).
> The WKB stream carries all (meta)data needed to determine all the
> types of coordinates and geometries.
> If you look at the latest OGC Simple feature access - Part 1: Common
> architecture document (OGC 06-103r3, version: 1.2.0) ,
> there is enum WKBGeometryType with all combinations of point types
> listed with corresponding numerical identifier:
> plain Point = 1, PointZ = 1001, PointM = 2001, PointZM = 3001, etc.
>
> Then, geometries of higher dimensions carry this type in second field
> of the WKB byte stream, 4 bytes unsigned integer, after the first
> field of 1 byte indicating byte order.
>
> So, we simply have to rely on that information implementing necessary
> if-else branching at run-time (the WKB byte stream is an dynamic
> user-defined input, so compile-time checks are not very usable here, IMO).
>
> Does that answer your 1st concern?
Ah, yes, thank you! :)
>
>> Therefore, I added a (more or less trivial) run-time check that compares the
>> actual byte size and the expected byte size of the points, linestring,
>> polygon etc. which will give a run-time error during parsing, if the WKB
>> does not have the expected data/dimensions/size.
> Right, that's the mixed run-time and compile-time test we need to
> consider indeed.
>
> I see there are a couple of possibilities:
>
> 0) If type of WKB input and (geometry) type of target container are
> different, then throw error and give up.
>
> 1) WKB input w/ geometry of higher dimension than target container
> a) throw error
> b) flatten (or clamp) the coordinates. I think we can assume we always
> have at least 2D target container with X and Y. So, we can simply ignore
> Z and M dimensions in this case.
>
> 2) WKB input w/ geometry of lower dimension than target container
> a) throw error
> b) ignore the higher dimension coordinates in the target geometry,
> or set with zero. I think, this option makes little sense.
>
> My opinion is that the 0) gives most consistent behaviour, but from usability
> point, we may prefer combination of 1)b) and 2)a)
>
> What do you think?
While testing the linestring, I tried assigning a 3D WKB Linestring to a
2D (boost::geometry) Linestring. The WKB Linestring (1 2 3, 4 5 6, 7 8
9) became the (boost::geometry) Linestring (1 2, 3 4, 5 6), which was a
surprise. If this is equal to the 1b) alternative you propose, I'm not
sure if I'd want that behaviour.
Because of this, I implemented the check on byte size/ number of points,
which I described above, which corresponds to your 1a and 2a check.
I used postgisonline.org to get the WKB, so it should be what PostGIS
would output. It appears that the geometry type from PostGIS on a 3D
Point is Point (1), not PointZ (1001), but perhaps that is EWKB, and
not WKB. However, as this might be easy to mix up, I'd vote for the
length check I have implemented.
What about the 0) check you propose, which should always be an error,
and 1a and 2a as an additional check that can be turned off with a
template parameter? What error should be thrown?
>
>> The parser should support 3D as long as both the expected point dimensions
>> and the wkb point dimensions match. I have tested this for 3D/Z. M is not
>> supported by WKT yet, apparently, so I could not test this easily.
> M is there too, see OGC specification in version 1.2.0.
I meant boost::geometry's WKT reading. At least, I got an error when I
tried POINTM(1 2 3), but that might be the wrong syntax.
>
>> Coincidentally, this also removes the need to (artificially) limit the
>> points parser to two dimensions, that I saw a TODO-comment suggesting.
>> might statically assert that the expected_geometry has two-dimensional
>> points instead, if WKB should be limited to 2D.
> Yes, as I mentioned in the beginning, this is a legacy limitation that
> should go.
>
> Best regards,
Best regards,
Mats
Geometry list run by mateusz at loskot.net