structure saas with tools
This commit is contained in:
@@ -0,0 +1,176 @@
|
||||
import binascii
|
||||
import math
|
||||
import struct
|
||||
import sys
|
||||
|
||||
import pytest
|
||||
|
||||
from shapely import wkt
|
||||
from shapely.geometry import Point
|
||||
from shapely.tests.legacy.conftest import shapely20_todo
|
||||
from shapely.wkb import dump, dumps, load, loads
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def some_point():
|
||||
return Point(1.2, 3.4)
|
||||
|
||||
|
||||
def bin2hex(value):
|
||||
return binascii.b2a_hex(value).upper().decode("utf-8")
|
||||
|
||||
|
||||
def hex2bin(value):
|
||||
return binascii.a2b_hex(value)
|
||||
|
||||
|
||||
def hostorder(fmt, value):
|
||||
"""Re-pack a hex WKB value to native endianness if needed
|
||||
|
||||
This routine does not understand WKB format, so it must be provided a
|
||||
struct module format string, without initial indicator character ("@=<>!"),
|
||||
which will be interpreted as big- or little-endian with standard sizes
|
||||
depending on the endian flag in the first byte of the value.
|
||||
"""
|
||||
|
||||
if fmt and fmt[0] in "@=<>!":
|
||||
raise ValueError("Initial indicator character, one of @=<>!, in fmt")
|
||||
if not fmt or fmt[0] not in "cbB":
|
||||
raise ValueError("Missing endian flag in fmt")
|
||||
|
||||
(hexendian,) = struct.unpack(fmt[0], hex2bin(value[:2]))
|
||||
hexorder = {0: ">", 1: "<"}[hexendian]
|
||||
sysorder = {"little": "<", "big": ">"}[sys.byteorder]
|
||||
if hexorder == sysorder:
|
||||
return value # Nothing to do
|
||||
|
||||
return bin2hex(
|
||||
struct.pack(
|
||||
sysorder + fmt,
|
||||
{">": 0, "<": 1}[sysorder],
|
||||
*struct.unpack(hexorder + fmt, hex2bin(value))[1:],
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def test_dumps_srid(some_point):
|
||||
result = dumps(some_point)
|
||||
assert bin2hex(result) == hostorder(
|
||||
"BIdd", "0101000000333333333333F33F3333333333330B40"
|
||||
)
|
||||
result = dumps(some_point, srid=4326)
|
||||
assert bin2hex(result) == hostorder(
|
||||
"BIIdd", "0101000020E6100000333333333333F33F3333333333330B40"
|
||||
)
|
||||
|
||||
|
||||
def test_dumps_endianness(some_point):
|
||||
result = dumps(some_point)
|
||||
assert bin2hex(result) == hostorder(
|
||||
"BIdd", "0101000000333333333333F33F3333333333330B40"
|
||||
)
|
||||
result = dumps(some_point, big_endian=False)
|
||||
assert bin2hex(result) == "0101000000333333333333F33F3333333333330B40"
|
||||
result = dumps(some_point, big_endian=True)
|
||||
assert bin2hex(result) == "00000000013FF3333333333333400B333333333333"
|
||||
|
||||
|
||||
def test_dumps_hex(some_point):
|
||||
result = dumps(some_point, hex=True)
|
||||
assert result == hostorder("BIdd", "0101000000333333333333F33F3333333333330B40")
|
||||
|
||||
|
||||
def test_loads_srid():
|
||||
# load a geometry which includes an srid
|
||||
geom = loads(hex2bin("0101000020E6100000333333333333F33F3333333333330B40"))
|
||||
assert isinstance(geom, Point)
|
||||
assert geom.coords[:] == [(1.2, 3.4)]
|
||||
# by default srid is not exported
|
||||
result = dumps(geom)
|
||||
assert bin2hex(result) == hostorder(
|
||||
"BIdd", "0101000000333333333333F33F3333333333330B40"
|
||||
)
|
||||
# include the srid in the output
|
||||
result = dumps(geom, include_srid=True)
|
||||
assert bin2hex(result) == hostorder(
|
||||
"BIIdd", "0101000020E6100000333333333333F33F3333333333330B40"
|
||||
)
|
||||
# replace geometry srid with another
|
||||
result = dumps(geom, srid=27700)
|
||||
assert bin2hex(result) == hostorder(
|
||||
"BIIdd", "0101000020346C0000333333333333F33F3333333333330B40"
|
||||
)
|
||||
|
||||
|
||||
def test_loads_hex(some_point):
|
||||
assert loads(dumps(some_point, hex=True), hex=True) == some_point
|
||||
|
||||
|
||||
def test_dump_load_binary(some_point, tmpdir):
|
||||
file = tmpdir.join("test.wkb")
|
||||
with open(file, "wb") as file_pointer:
|
||||
dump(some_point, file_pointer)
|
||||
with open(file, "rb") as file_pointer:
|
||||
restored = load(file_pointer)
|
||||
|
||||
assert some_point == restored
|
||||
|
||||
|
||||
def test_dump_load_hex(some_point, tmpdir):
|
||||
file = tmpdir.join("test.wkb")
|
||||
with open(file, "w") as file_pointer:
|
||||
dump(some_point, file_pointer, hex=True)
|
||||
with open(file) as file_pointer:
|
||||
restored = load(file_pointer, hex=True)
|
||||
|
||||
assert some_point == restored
|
||||
|
||||
|
||||
# pygeos handles both bytes and str
|
||||
@shapely20_todo
|
||||
def test_dump_hex_load_binary(some_point, tmpdir):
|
||||
"""Asserts that reading a binary file as text (hex mode) fails."""
|
||||
file = tmpdir.join("test.wkb")
|
||||
with open(file, "w") as file_pointer:
|
||||
dump(some_point, file_pointer, hex=True)
|
||||
|
||||
with pytest.raises(TypeError):
|
||||
with open(file, "rb") as file_pointer:
|
||||
load(file_pointer)
|
||||
|
||||
|
||||
def test_dump_binary_load_hex(some_point, tmpdir):
|
||||
"""Asserts that reading a text file (hex mode) as binary fails."""
|
||||
file = tmpdir.join("test.wkb")
|
||||
with open(file, "wb") as file_pointer:
|
||||
dump(some_point, file_pointer)
|
||||
|
||||
# TODO(shapely-2.0) on windows this doesn't seem to error with pygeos,
|
||||
# but you get back a point with garbage coordinates
|
||||
if sys.platform == "win32":
|
||||
with open(file) as file_pointer:
|
||||
restored = load(file_pointer, hex=True)
|
||||
assert some_point != restored
|
||||
return
|
||||
|
||||
with pytest.raises((UnicodeEncodeError, UnicodeDecodeError)):
|
||||
with open(file) as file_pointer:
|
||||
load(file_pointer, hex=True)
|
||||
|
||||
|
||||
def test_point_empty():
|
||||
g = wkt.loads("POINT EMPTY")
|
||||
result = dumps(g, big_endian=False)
|
||||
# Use math.isnan for second part of the WKB representation there are
|
||||
# many byte representations for NaN)
|
||||
assert result[: -2 * 8] == b"\x01\x01\x00\x00\x00"
|
||||
coords = struct.unpack("<2d", result[-2 * 8 :])
|
||||
assert len(coords) == 2
|
||||
assert all(math.isnan(val) for val in coords)
|
||||
|
||||
|
||||
def test_point_z_empty():
|
||||
g = wkt.loads("POINT Z EMPTY")
|
||||
assert g.wkb_hex == hostorder(
|
||||
"BIddd", "0101000080000000000000F87F000000000000F87F000000000000F87F"
|
||||
)
|
||||
Reference in New Issue
Block a user