togo 0.1.3__tar.gz → 0.1.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of togo might be problematic. Click here for more details.
- {togo-0.1.3/togo.egg-info → togo-0.1.4}/PKG-INFO +1 -1
- {togo-0.1.3 → togo-0.1.4}/pyproject.toml +4 -1
- togo-0.1.4/setup.py +65 -0
- {togo-0.1.3 → togo-0.1.4}/tests/test_geometries.py +31 -0
- {togo-0.1.3 → togo-0.1.4}/tests/test_geometry.py +41 -1
- togo-0.1.4/tgx.c +781 -0
- togo-0.1.4/tgx.h +21 -0
- {togo-0.1.3 → togo-0.1.4}/togo.c +6116 -3536
- {togo-0.1.3 → togo-0.1.4/togo.egg-info}/PKG-INFO +1 -1
- {togo-0.1.3 → togo-0.1.4}/togo.egg-info/SOURCES.txt +2 -0
- {togo-0.1.3 → togo-0.1.4}/togo.pyx +223 -41
- togo-0.1.3/setup.py +0 -52
- {togo-0.1.3 → togo-0.1.4}/LICENSE +0 -0
- {togo-0.1.3 → togo-0.1.4}/MANIFEST.in +0 -0
- {togo-0.1.3 → togo-0.1.4}/README.md +0 -0
- {togo-0.1.3 → togo-0.1.4}/setup.cfg +0 -0
- {togo-0.1.3 → togo-0.1.4}/tests/test_factories.py +0 -0
- {togo-0.1.3 → togo-0.1.4}/tests/test_line.py +0 -0
- {togo-0.1.3 → togo-0.1.4}/tests/test_point.py +0 -0
- {togo-0.1.3 → togo-0.1.4}/tests/test_poly.py +0 -0
- {togo-0.1.3 → togo-0.1.4}/tests/test_rect.py +0 -0
- {togo-0.1.3 → togo-0.1.4}/tests/test_ring.py +0 -0
- {togo-0.1.3 → togo-0.1.4}/tests/test_segment.py +0 -0
- {togo-0.1.3 → togo-0.1.4}/tg.c +0 -0
- {togo-0.1.3 → togo-0.1.4}/tg.h +0 -0
- {togo-0.1.3 → togo-0.1.4}/togo.egg-info/dependency_links.txt +0 -0
- {togo-0.1.3 → togo-0.1.4}/togo.egg-info/top_level.txt +0 -0
|
@@ -8,7 +8,7 @@ build-backend = "setuptools.build_meta"
|
|
|
8
8
|
|
|
9
9
|
[project]
|
|
10
10
|
name = "togo"
|
|
11
|
-
version = "0.1.
|
|
11
|
+
version = "0.1.4"
|
|
12
12
|
description = "Lightweight Python bindings for the TG geometry library"
|
|
13
13
|
readme = "README.md"
|
|
14
14
|
authors = [
|
|
@@ -33,3 +33,6 @@ Tracker = "https://github.com/mindflayer/togo/issues"
|
|
|
33
33
|
addopts = "-v -x -q"
|
|
34
34
|
testpaths = ["tests"]
|
|
35
35
|
pythonpath = ["."]
|
|
36
|
+
|
|
37
|
+
[tool.cython-lint]
|
|
38
|
+
max-line-length = 100
|
togo-0.1.4/setup.py
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import urllib.request
|
|
3
|
+
from urllib.parse import urlparse
|
|
4
|
+
|
|
5
|
+
from setuptools import setup, Extension
|
|
6
|
+
from Cython.Build import cythonize
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
# Download the tg and tgx source and header files if not already present
|
|
10
|
+
NEEDED_FILES = [
|
|
11
|
+
"https://raw.githubusercontent.com/tidwall/tg/main/tg.c",
|
|
12
|
+
"https://raw.githubusercontent.com/tidwall/tg/main/tg.h",
|
|
13
|
+
"https://raw.githubusercontent.com/tidwall/tgx/main/tgx.c",
|
|
14
|
+
"https://raw.githubusercontent.com/tidwall/tgx/main/tgx.h",
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def download_if_missing(url: str, filename: str):
|
|
19
|
+
if not os.path.exists(filename):
|
|
20
|
+
print(f"Downloading {filename}...")
|
|
21
|
+
urllib.request.urlretrieve(url, filename)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
for url in NEEDED_FILES:
|
|
25
|
+
filename = os.path.basename(urlparse(url).path)
|
|
26
|
+
download_if_missing(url, filename)
|
|
27
|
+
|
|
28
|
+
# Enable optional AddressSanitizer build via env var ASAN=1
|
|
29
|
+
asan_enabled = os.environ.get("ASAN") == "1"
|
|
30
|
+
extra_compile_args = []
|
|
31
|
+
extra_link_args = []
|
|
32
|
+
if asan_enabled:
|
|
33
|
+
# Favor debuggability over speed
|
|
34
|
+
extra_compile_args += [
|
|
35
|
+
"-O1",
|
|
36
|
+
"-g",
|
|
37
|
+
"-fno-omit-frame-pointer",
|
|
38
|
+
"-fsanitize=address",
|
|
39
|
+
]
|
|
40
|
+
extra_link_args += [
|
|
41
|
+
"-fsanitize=address",
|
|
42
|
+
]
|
|
43
|
+
|
|
44
|
+
setup(
|
|
45
|
+
ext_modules=cythonize(
|
|
46
|
+
[
|
|
47
|
+
Extension(
|
|
48
|
+
"togo",
|
|
49
|
+
sources=["togo.pyx", "tg.c", "tgx.c"],
|
|
50
|
+
include_dirs=[
|
|
51
|
+
".",
|
|
52
|
+
"/usr/include",
|
|
53
|
+
"/usr/include/geos",
|
|
54
|
+
], # Add GEOS include path
|
|
55
|
+
libraries=["geos_c"], # Link against libgeos_c
|
|
56
|
+
extra_compile_args=extra_compile_args,
|
|
57
|
+
extra_link_args=extra_link_args,
|
|
58
|
+
)
|
|
59
|
+
]
|
|
60
|
+
),
|
|
61
|
+
# Explicitly disable auto-discovery in flat layout
|
|
62
|
+
packages=[],
|
|
63
|
+
py_modules=[],
|
|
64
|
+
license="MIT",
|
|
65
|
+
)
|
|
@@ -58,3 +58,34 @@ def test_buenos_aires():
|
|
|
58
58
|
b_aires_center = rect.center()
|
|
59
59
|
assert b_aires_center.as_tuple() == (-58.38268310487112, -34.70305640194427)
|
|
60
60
|
assert b_aires.intersects(b_aires_center.as_geometry())
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def test_togo_union_benin():
|
|
64
|
+
g = Geometry.unary_union(
|
|
65
|
+
[Geometry(TOGO, fmt="geojson"), Geometry(BENIN, fmt="geojson")]
|
|
66
|
+
)
|
|
67
|
+
# The union should not be empty and should be a valid geometry
|
|
68
|
+
assert not g.is_empty()
|
|
69
|
+
assert g.type_string() == "Polygon"
|
|
70
|
+
wkt = g.to_wkt()
|
|
71
|
+
new_g = Geometry(wkt, fmt="wkt")
|
|
72
|
+
assert new_g.equals(g)
|
|
73
|
+
assert new_g.rect() == g.rect()
|
|
74
|
+
assert new_g.within(g) and g.within(new_g)
|
|
75
|
+
assert g.contains(new_g) and new_g.contains(g)
|
|
76
|
+
assert g.intersects(new_g) and new_g.intersects(g)
|
|
77
|
+
assert not g.disjoint(new_g) and not new_g.disjoint(g)
|
|
78
|
+
assert not g.touches(new_g) and not new_g.touches(g)
|
|
79
|
+
assert g.num_points() == new_g.num_points()
|
|
80
|
+
assert g.dims() == new_g.dims()
|
|
81
|
+
assert g.has_z() == new_g.has_z()
|
|
82
|
+
assert g.has_m() == new_g.has_m()
|
|
83
|
+
assert g.is_feature() == new_g.is_feature()
|
|
84
|
+
assert g.is_featurecollection() == new_g.is_featurecollection()
|
|
85
|
+
assert g.to_geojson() == new_g.to_geojson()
|
|
86
|
+
assert g.to_hex() == new_g.to_hex()
|
|
87
|
+
assert g.to_wkb() == new_g.to_wkb()
|
|
88
|
+
assert g.to_geobin() == new_g.to_geobin()
|
|
89
|
+
assert g.memsize() == new_g.memsize()
|
|
90
|
+
assert g.coveredby(new_g) and new_g.coveredby(g)
|
|
91
|
+
assert g.covers(new_g) and new_g.covers(g)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import pytest
|
|
2
|
-
from togo import Geometry
|
|
2
|
+
from togo import Geometry, Point, Ring, Poly
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
def test_geometry_wkt():
|
|
@@ -193,3 +193,43 @@ def test_geometry_geom_at():
|
|
|
193
193
|
assert g1.type_string() == "Point"
|
|
194
194
|
assert g0.point().x == 1.0 and g0.point().y == 2.0
|
|
195
195
|
assert g1.point().x == 3.0 and g1.point().y == 4.0
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
def test_tgx_meters_grid():
|
|
199
|
+
# Create a simple point geometry
|
|
200
|
+
g = Geometry('{"type": "Point", "coordinates": [1.0, 2.0]}')
|
|
201
|
+
origin = Point(0.0, 0.0)
|
|
202
|
+
g2 = g.to_meters_grid(origin)
|
|
203
|
+
g3 = g2.from_meters_grid(origin)
|
|
204
|
+
# Should round-trip back to original coordinates
|
|
205
|
+
assert g3.point().x == pytest.approx(1.0, abs=1e-6)
|
|
206
|
+
assert g3.point().y == pytest.approx(2.0, abs=1e-6)
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
def test_unary_union_geos_lines():
|
|
210
|
+
g1 = Geometry("LINESTRING(0 0, 1 1)", fmt="wkt")
|
|
211
|
+
g2 = Geometry("LINESTRING(1 1, 2 2)", fmt="wkt")
|
|
212
|
+
u = Geometry.unary_union([g1, g2])
|
|
213
|
+
assert u.type_string() == "MultiLineString"
|
|
214
|
+
wkt = u.to_wkt()
|
|
215
|
+
assert wkt == "MULTILINESTRING((0 0,1 1),(1 1,2 2))"
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
def test_unary_union_geos_polys():
|
|
219
|
+
# Two intersecting squares
|
|
220
|
+
outer1 = Ring([(0, 0), (2, 0), (2, 2), (0, 2), (0, 0)])
|
|
221
|
+
poly1 = Poly(outer1)
|
|
222
|
+
outer2 = Ring([(1, 1), (3, 1), (3, 3), (1, 3), (1, 1)])
|
|
223
|
+
poly2 = Poly(outer2)
|
|
224
|
+
union_geom = Geometry.unary_union([poly1, poly2])
|
|
225
|
+
# Should be a single Polygon
|
|
226
|
+
assert union_geom.type_string() == "Polygon"
|
|
227
|
+
# Area should be 7 (each square is 4, overlap is 1)
|
|
228
|
+
# So union area = 4 + 4 - 1 = 7
|
|
229
|
+
area = union_geom.poly().exterior().area()
|
|
230
|
+
assert area == 7.0
|
|
231
|
+
# Bounding box should be ((0,0),(3,3))
|
|
232
|
+
assert union_geom.rect() == ((0.0, 0.0), (3.0, 3.0))
|
|
233
|
+
# WKT should represent the merged polygon
|
|
234
|
+
wkt = union_geom.to_wkt()
|
|
235
|
+
assert wkt == "POLYGON((2 0,0 0,0 2,1 2,1 3,3 3,3 1,2 1,2 0))"
|