Unhexlify errors when converting 50 character string

479 Views Asked by At

I want to convert WKB representations of XY coordinates into a YX format. The code I'm using works with 42 character WKB strings, but when I use it on 50 character strings it gives me an odd YX output. I'm running Python 2.7.5.

Here's my code:

from osgeo import ogr
from binascii import unhexlify

## converts a WKB string into a YX coordinate

input = raw_input("Enter WKB string: ")
wkb = unhexlify(input)
point = ogr.CreateGeometryFromWkb(wkb)
print "%.3f,%.3f" % (point.GetY(), point.GetX())


# no work 0101000020E6100000BD30B7B921A85AC07513F26D8A1A4840
# work    0101000000C458A65F22A85AC0E412471E881A4840

When I input the 42 character string my results are good: POINT (-106.627098 48.207279)

but when I input my 50 character string I get: 355513472847601729897331967629935245053837846890691162677352753848836303684477311589993604618806134471993299583159702126592.000,-0.000

when I print the point only, I get this: POINT (-0.0 too_big)

can anyone help me with an explanation?

3

There are 3 best solutions below

0
On

Where does this 50 chars string come from? It's header, 0101000020 do not seem to be a valid WKB header, as first 01 implies little-endiannes, so geomertry type is translated as 0x20000001, which is undefined.

Second, for a point length of WKB representation is 42, never 50, as coordinates are doubles (8 bytes long), hence 16 chars long when hexlified. See for your working example:

>>> s = 'C458A65F22A85AC0E412471E881A4840'
>>> struct.unpack('<d', unhexlify(s[:16]))
(-106.62709799999999,)
>>> struct.unpack('<d', unhexlify(s[16:]))
(48.207279,)

It is then clear why your second example do not work, as something like follows happens (not sure how exactly 16 chars substring are extracted by osgeo):

>>> s = 'E6100000BD30B7B921A85AC07513F26D8A1A4840'
>>> struct.unpack('>d', unhexlify(s[-32:-16]))
(-5.939309002701494e-14,)
>>> struct.unpack('>d', unhexlify(s[-16:]))
(9.359519850637786e+255,)    
3
On

My 50 character string comes from manually edited points. When I input the 50 character string into QGIS I get a valid point. Also, when I run this in psql:

select concat(Y,',',X) as YX from
(select ST_Y('0101000020E6100000BD30B7B921A85AC07513F26D8A1A4840') as Y, st_x('0101000020E6100000BD30B7B921A85AC07513F26D8A1A4840') as X) as meister;

I get a valid YX:

48.2073495323192,-106.627058438203

So the WKB is valid and reads a a point geometry. but for some reason unhexlify can't read it as well as the psql function can. Could this be a multidimensional point since it has been created and edited multiple times?

1
On

I figured it out. It's a bit hackey, though

So the 50 character string that didn't work was this: 0101000020E6100000BD30B7B921A85AC07513F26D8A1A4840

I made some changes and turned it into this and it worked: 0101000020BD30B7B921A85AC07513F26D8A1A4840

I deleted the 11-18th character and it turned into a valid point.

from osgeo import ogr
from binascii import unhexlify

## converts a WKB string into a YX coordinate

input = raw_input("Enter WKB string: ")
wkb = unhexlify(input)
point = ogr.CreateGeometryFromWkb(wkb)
print "%.6f,%.6f" % (point.GetY(), point.GetX())

For some reason it had an SRID error/extra digits. Once I removed those 8 digits, then it gave me the proper YX