File: test_shape.py

package info (click to toggle)
geoalchemy2 0.18.4-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,692 kB
  • sloc: python: 10,031; sh: 159; makefile: 133
file content (156 lines) | stat: -rw-r--r-- 4,412 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
import importlib
import sys

import pytest
import shapely.wkb
from shapely.geometry import Point

import geoalchemy2.shape
from geoalchemy2.elements import WKBElement
from geoalchemy2.elements import WKTElement
from geoalchemy2.shape import from_shape
from geoalchemy2.shape import to_shape


def test_import_without_shapely(monkeypatch):
    """Ensure geoalchemy2.shape can be imported when Shapely is not installed."""
    # Save the current shapely entries in sys.modules

    shapely_modules = {
        k: v for k, v in sys.modules.items() if k == "shapely" or k.startswith("shapely.")
    }
    CHECK_COMPLETE = 0
    with monkeypatch.context() as m:
        try:
            for k in shapely_modules:
                m.setitem(sys.modules, k, None)

            # Now import the module - must not raise ImportError

            importlib.reload(geoalchemy2.shape)

            assert not geoalchemy2.shape.HAS_SHAPELY
            with pytest.raises(
                ImportError,
                match="This feature needs the optional Shapely dependency",
            ):
                to_shape(WKTElement("SRID=3857;POINT(1 2)"))
            CHECK_COMPLETE += 1
        finally:
            # Restore shapely modules and reload to return to normal state

            for k, v in shapely_modules.items():
                sys.modules[k] = v

            importlib.reload(geoalchemy2.shape)
            to_shape(WKTElement("SRID=3857;POINT(1 2)"))  # Should not raise ImportError
            CHECK_COMPLETE += 1

    assert geoalchemy2.shape.HAS_SHAPELY
    assert CHECK_COMPLETE == 2


def test_check_shapely(monkeypatch):
    @geoalchemy2.shape.check_shapely()
    def f():
        return "ok"

    assert f() == "ok"

    with monkeypatch.context() as m:
        m.setattr(geoalchemy2.shape, "HAS_SHAPELY", False)
        with pytest.raises(ImportError):
            f()


def test_to_shape_WKBElement():
    # POINT(1 2)
    e = WKBElement(
        b"\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0?\x00\x00\x00\x00\x00\x00\x00@"
    )
    s = to_shape(e)
    assert isinstance(s, Point)
    assert s.x == 1
    assert s.y == 2


def test_to_shape_WKBElement_str():
    # POINT(1 2)
    e = WKBElement("0101000000000000000000f03f0000000000000040")
    s = to_shape(e)
    assert isinstance(s, Point)
    assert s.x == 1
    assert s.y == 2


def test_to_shape_ExtendedWKBElement():
    # SRID=3857;POINT(1 2 3)
    e = WKBElement(
        b"\x01\x01\x00\x00\xa0\x11\x0f\x00\x00\x00"
        b"\x00\x00\x00\x00\x00\xf0?\x00\x00\x00\x00"
        b"\x00\x00\x00@\x00\x00\x00\x00\x00\x00\x08@",
        extended=True,
    )
    s = to_shape(e)
    assert isinstance(s, Point)
    assert s.x == 1
    assert s.y == 2
    assert s.z == 3


def test_to_shape_ExtendedWKTElement():
    e = WKTElement("SRID=3857;POINT(1 2)", extended=True)
    s = to_shape(e)
    assert isinstance(s, Point)
    assert s.x == 1
    assert s.y == 2


def test_to_shape_WKTElement():
    e = WKTElement("POINT(1 2)")
    s = to_shape(e)
    assert isinstance(s, Point)
    assert s.x == 1
    assert s.y == 2


def test_to_shape_wrong_type():
    with pytest.raises(TypeError, match="Only WKBElement and WKTElement objects are supported"):
        to_shape(0)


def test_from_shape():
    # Standard case: POINT(1 2)
    expected = WKBElement("0101000000000000000000f03f0000000000000040")
    p = Point(1, 2)
    e = from_shape(p)
    assert isinstance(e, WKBElement)
    assert isinstance(e.data, memoryview)
    assert e == expected

    s = shapely.wkb.loads(bytes(e.data))
    assert isinstance(s, Point)
    assert s.equals(p)

    # Standard case with SRID: SRID=2145;POINT(1 2)
    expected2 = WKBElement("0101000000000000000000f03f0000000000000040", srid=2154)
    p = Point(1, 2)
    e2 = from_shape(p, srid=2154)
    assert isinstance(e2, WKBElement)
    assert isinstance(e2.data, memoryview)
    assert e2 == expected2

    s2 = shapely.wkb.loads(bytes(e2.data))
    assert isinstance(s2, Point)
    assert s2.equals(p)

    # Extended case: SRID=2145;POINT(1 2)
    expected3 = WKBElement("01010000206a080000000000000000f03f0000000000000040", extended=True)
    e3 = from_shape(p, srid=2154, extended=True)
    assert isinstance(e3, WKBElement)
    assert isinstance(e3.data, memoryview)
    assert e3 == expected3

    s3 = shapely.wkb.loads(bytes(e3.data))
    assert isinstance(s, Point)
    assert s3.equals(p)