togo 0.2.2__cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl

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.
@@ -0,0 +1,344 @@
1
+ Metadata-Version: 2.4
2
+ Name: togo
3
+ Version: 0.2.2
4
+ Summary: Lightweight Python bindings for the TG geometry library
5
+ Author-email: Giorgio Salluzzo <giorgio.salluzzo@gmail.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/mindflayer/togo
8
+ Project-URL: Source, https://github.com/mindflayer/togo
9
+ Project-URL: Tracker, https://github.com/mindflayer/togo/issues
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: C
12
+ Classifier: Operating System :: POSIX :: Linux
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Topic :: Scientific/Engineering :: GIS
15
+ Requires-Python: >=3.8
16
+ Description-Content-Type: text/markdown
17
+ License-File: LICENSE
18
+ Dynamic: license
19
+ Dynamic: license-file
20
+
21
+ # ToGo
22
+ Python bindings for [TG](https://github.com/tidwall/tg)
23
+ (Geometry library for C - Fast point-in-polygon)
24
+
25
+ ToGo is a high-performance Python library for computational geometry, providing a Cython wrapper around the above-mentioned C library.
26
+
27
+ The main goal is to offer a Pythonic, object-oriented, fast and memory-efficient library for geometric operations, including spatial predicates, format conversions, and spatial indexing.
28
+
29
+ **New:** ToGo now provides a **Shapely-compatible API**! See [SHAPELY_API.md](SHAPELY_API.md) for details.
30
+
31
+ ## Installation
32
+
33
+ ```bash
34
+ pip install togo
35
+ ```
36
+
37
+ ## Features
38
+
39
+ - Fast and efficient geometric operations
40
+ - Support for standard geometry types: Point, Line, Ring, Polygon, and their multi-variants
41
+ - **Shapely-compatible API** with familiar class names and properties
42
+ - Geometric predicates: contains, intersects, covers, touches, etc.
43
+ - Format conversion between WKT, GeoJSON, WKB, and HEX
44
+ - Spatial indexing for accelerated queries
45
+ - Memory-efficient C implementation with Python-friendly interface
46
+
47
+ ## Basic Usage
48
+
49
+ ### Shapely-Compatible API
50
+
51
+ ```python
52
+ from togo import Point, LineString, Polygon
53
+ from togo import from_wkt, from_geojson
54
+
55
+ # Create geometries using familiar Shapely-like syntax
56
+ point = Point(1.0, 2.0)
57
+ line = LineString([(0, 0), (1, 1), (2, 2)])
58
+ poly = Polygon([(0, 0), (4, 0), (4, 4), (0, 4), (0, 0)])
59
+
60
+ # Access Shapely-compatible properties
61
+ print(point.geom_type) # 'Point'
62
+ print(point.bounds) # (1.0, 2.0, 1.0, 2.0)
63
+ print(line.length) # 2.828...
64
+ print(poly.area) # 16.0
65
+
66
+ # Parse from WKT/GeoJSON
67
+ geom = from_wkt("POINT (1 2)")
68
+ geom2 = from_geojson('{"type":"Point","coordinates":[3,4]}')
69
+
70
+ # Spatial predicates
71
+ poly_geom = poly.as_geometry()
72
+ point_geom = point.as_geometry()
73
+ if poly_geom.contains(point_geom):
74
+ print("Polygon contains point!")
75
+ ```
76
+
77
+ ### Original ToGo API
78
+
79
+ ```python
80
+ from togo import Geometry, Point, Ring, Poly
81
+
82
+ # Create a geometry from GeoJSON
83
+ geom = Geometry('{"type":"Point","coordinates":[1.0,2.0]}')
84
+
85
+ # Create a point
86
+ point = Point(1.0, 2.0)
87
+
88
+ # Create a polygon
89
+ ring = Ring([(0,0), (10,0), (10,10), (0,10), (0,0)])
90
+ polygon = Poly(ring)
91
+
92
+ # Convert to various formats
93
+ wkt = polygon.as_geometry().to_wkt()
94
+ geojson = polygon.as_geometry().to_geojson()
95
+
96
+ # Perform spatial predicates
97
+ point_geom = point.as_geometry()
98
+ contains = polygon.as_geometry().contains(point_geom)
99
+ ```
100
+
101
+ ## Core Classes
102
+
103
+ ### Geometry
104
+
105
+ The base class that wraps tg_geom structures and provides core operations:
106
+
107
+ ```python
108
+ # Create from various formats
109
+ g1 = Geometry('POINT(1 2)', fmt='wkt')
110
+ g2 = Geometry('{"type":"Point","coordinates":[1,2]}', fmt='geojson')
111
+
112
+ # Geometric predicates
113
+ g1.intersects(g2)
114
+ g1.contains(g2)
115
+ g1.within(g2)
116
+
117
+ # Format conversion
118
+ g1.to_wkt()
119
+ g1.to_geojson()
120
+
121
+ # Access sub-geometries by index (e.g., for GeometryCollection, MultiPoint, etc.)
122
+ gc = Geometry('GEOMETRYCOLLECTION(POINT(1 2),POINT(3 4))', fmt='wkt')
123
+ first = gc[0] # Bound to TG function call tg_geom_geometry_at(idx)
124
+ second = gc[1]
125
+ print(first.type_string()) # 'Point'
126
+ ```
127
+
128
+ ### Point
129
+
130
+ ```python
131
+ from togo import Point
132
+
133
+ # Create a point
134
+ p = Point(1.0, 2.0)
135
+
136
+ # Access coordinates
137
+ print(f"X: {p.x}, Y: {p.y}")
138
+
139
+ # Get as a tuple
140
+ print(p.as_tuple())
141
+
142
+ # Convert to a Geometry object
143
+ geom = p.as_geometry()
144
+ print(geom.type_string())
145
+ ```
146
+
147
+ ### Segment
148
+
149
+ ```python
150
+ from togo import Segment, Point
151
+
152
+ # Create a segment from two points (or tuples)
153
+ seg = Segment(Point(0, 0), Point(1, 1))
154
+ # Or using tuples
155
+ tuple_seg = Segment((0, 0), (1, 1))
156
+
157
+ # Access endpoints
158
+ print(seg.a) # Point(0, 0)
159
+ print(seg.b) # Point(1, 1)
160
+
161
+ # Get the bounding rectangle
162
+ rect = seg.rect()
163
+ print(rect) # ((0.0, 0.0), (1.0, 1.0))
164
+
165
+ # Check intersection with another segment
166
+ other = Segment((1, 1), (2, 2))
167
+ print(seg.intersects(other)) # True or False
168
+ ```
169
+
170
+ ### Line
171
+
172
+ ```python
173
+ from togo import Line
174
+
175
+ # Create a line from a list of tuples
176
+ line = Line([(0,0), (1,1), (2,0)])
177
+
178
+ # Get number of points
179
+ print(f"Number of points: {line.num_points}")
180
+
181
+ # Get all points as a list of tuples
182
+ print(f"Points: {line.points()}")
183
+
184
+ # Get the length of the line
185
+ print(f"Length: {line.length}")
186
+
187
+ # Get the bounding box
188
+ print(f"Bounding box: {line.rect()}")
189
+
190
+ # Get a point by index
191
+ print(f"First point: {line[0].as_tuple()}")
192
+ ```
193
+
194
+ ### Ring
195
+
196
+ ```python
197
+ from togo import Ring
198
+
199
+ # Create a ring (must be closed)
200
+ ring = Ring([(0,0), (10,0), (10,10), (0,10), (0,0)])
201
+
202
+ # Get area and perimeter
203
+ print(f"Area: {ring.area()}")
204
+ print(f"Perimeter: {ring.perimeter()}")
205
+
206
+ # Check if it's convex or clockwise
207
+ print(f"Is convex: {ring.is_convex()}")
208
+ print(f"Is clockwise: {ring.is_clockwise()}")
209
+
210
+ # Get bounding box
211
+ min_pt, max_pt = ring.rect().min, ring.rect().max
212
+ print(f"Bounding box: {min_pt.as_tuple()}, {max_pt.as_tuple()}")
213
+ ```
214
+
215
+ ### Poly
216
+
217
+ ```python
218
+ from togo import Poly, Ring, Point
219
+
220
+ # Create a polygon with one exterior ring and one interior hole
221
+ exterior = Ring([(0,0), (10,0), (10,10), (0,10), (0,0)])
222
+ hole1 = Ring([(1,1), (2,1), (2,2), (1,2), (1,1)])
223
+ poly = Poly(exterior, holes=[hole1])
224
+
225
+ # Get the exterior ring
226
+ ext_ring = poly.exterior()
227
+ print(f"Exterior has {ext_ring.num_points} points")
228
+
229
+ # Get number of holes
230
+ print(f"Number of holes: {poly.num_holes()}")
231
+
232
+ # Get a hole by index
233
+ h = poly.hole(0)
234
+ print(f"Hole area: {h.area()}")
235
+
236
+ # A polygon is a geometry, so you can use geometry methods
237
+ geom = poly.as_geometry()
238
+ print(f"Contains point (5,5): {geom.contains(Point(5,5).as_geometry())}")
239
+ # Point is inside the hole, so it is not contained by the polygon
240
+ print(f"Contains point (1.5,1.5): {geom.contains(Point(1.5,1.5).as_geometry())}")
241
+ ```
242
+
243
+ ### MultiGeometries
244
+
245
+ Creating collections of geometries:
246
+
247
+ ```python
248
+ from togo import Geometry, Point, Line, Poly, Ring
249
+
250
+ # Create a MultiPoint
251
+ multi_point = Geometry.from_multipoint([(0,0), (1,1), Point(2,2)])
252
+
253
+ # Create a MultiLineString
254
+ multi_line = Geometry.from_multilinestring([
255
+ [(0,0), (1,1)],
256
+ Line([(2,2), (3,3)])
257
+ ])
258
+
259
+ # Create a MultiPolygon
260
+ poly1 = Poly(Ring([(0,0), (1,0), (1,1), (0,1), (0,0)]))
261
+ poly2 = Poly(Ring([(2,2), (3,2), (3,3), (2,3), (2,2)]))
262
+ multi_poly = Geometry.from_multipolygon([poly1, poly2])
263
+ ```
264
+
265
+ ## Polygon Indexing
266
+
267
+ Togo supports different polygon indexing strategies for optimized spatial operations:
268
+
269
+ ```python
270
+ from togo import TGIndex, set_polygon_indexing_mode
271
+
272
+ # Set the indexing mode
273
+ set_polygon_indexing_mode(TGIndex.NATURAL) # or NONE, YSTRIPES
274
+ ```
275
+
276
+ ## Integration with tgx and libgeos
277
+
278
+ Togo integrates with the [tgx](https://github.com/tidwall/tgx) extension and [libgeos](https://libgeos.org/) to provide advanced geometry operations, such as topological unions and conversions between TG and GEOS geometry formats. This allows you to leverage the speed of TG for basic operations and the flexibility of GEOS for more complex tasks.
279
+
280
+ ### Example: Unary Union (GEOS integration)
281
+
282
+ The `unary_union` method demonstrates this integration. It combines multiple geometries into a single geometry using GEOS's topological union, with all conversions handled automatically:
283
+
284
+ ```python
285
+ from togo import Geometry, Point, Poly, Ring
286
+
287
+ # Create several polygons
288
+ poly1 = Poly(Ring([(0,0), (2,0), (2,2), (0,2), (0,0)]))
289
+ poly2 = Poly(Ring([(1,1), (3,1), (3,3), (1,3), (1,1)]))
290
+
291
+ # Perform unary union (requires tgx and libgeos)
292
+ union = Geometry.unary_union([poly1, poly2])
293
+
294
+ # The result is a single geometry representing the union of the input polygons
295
+ print(union.to_wkt())
296
+ ```
297
+
298
+ This operation uses `tgx` to convert `TG` geometries to `GEOS`, applies the union in `libgeos`, and converts the result back to `TG` format for further use in `ToGo`.
299
+
300
+ ### Example: Buffer Operations (GEOS integration)
301
+
302
+ The `buffer()` method creates geometrical buffers (expanded or shrunk versions of geometries) using GEOS:
303
+
304
+ ```python
305
+ from togo import Point, LineString, Polygon, Ring, Geometry
306
+
307
+ # Buffer a point to create a circular zone
308
+ point = Point(0, 0)
309
+ circular_zone = point.buffer(10.0, quad_segs=16)
310
+ print(f"Point buffer: {circular_zone.geom_type}") # Polygon
311
+
312
+ # Buffer a line to create a corridor around it
313
+ line = LineString([(0, 0), (10, 10)])
314
+ corridor = line.buffer(2.0, cap_style=1) # round ends
315
+ print(f"Line buffer: {corridor.geom_type}") # Polygon
316
+
317
+ # Buffer a polygon to expand or shrink it
318
+ exterior = Ring([(0, 0), (10, 0), (10, 10), (0, 10), (0, 0)])
319
+ poly = Polygon(exterior)
320
+
321
+ expanded = poly.buffer(2.0) # Expand outward by 2 units
322
+ shrunk = poly.buffer(-1.0) # Shrink inward by 1 unit
323
+
324
+ # Via Geometry object with advanced parameters
325
+ geom = Geometry("POLYGON((0 0, 20 0, 20 20, 0 20, 0 0))")
326
+ buffered = geom.buffer(
327
+ distance=3.0,
328
+ quad_segs=16, # Segments per quadrant (higher = smoother)
329
+ cap_style=1, # 1=round, 2=flat, 3=square
330
+ join_style=1, # 1=round, 2=mitre, 3=bevel
331
+ mitre_limit=5.0 # Mitre ratio limit
332
+ )
333
+ ```
334
+
335
+ Like `unary_union`, buffer operations automatically handle TG ↔ GEOS conversions. For comprehensive buffer documentation, see [BUFFER_API.md](BUFFER_API.md).
336
+
337
+ ## Performance Considerations
338
+
339
+ - Togo is optimized for speed and memory efficiency
340
+ - For large datasets, proper indexing can significantly improve performance
341
+ - Creating geometries with the appropriate format avoids unnecessary conversions
342
+ - Buffer operations support quad_segs parameter to balance quality vs. performance
343
+
344
+ Soon there will be a full API documentation, for now please refer to the test suite for more usage examples.
@@ -0,0 +1,6 @@
1
+ togo.cpython-310-x86_64-linux-gnu.so,sha256=QyHl6x6znhJkKixldkDhQRtkZy-O69nz7KMkJE00tN8,9696040
2
+ togo-0.2.2.dist-info/METADATA,sha256=RNo-vhZRQuFJmvXPHcXvuacinIpEMKC7LLFXiShIudE,10054
3
+ togo-0.2.2.dist-info/WHEEL,sha256=HeTPKmtWRHAcGMCPCdnU4FtSZuvZBNNr3hB4MNGY2JY,152
4
+ togo-0.2.2.dist-info/top_level.txt,sha256=bldd6tssR8THqoSDFauQQdh_pg79DMHBDhiNKgS4ttM,5
5
+ togo-0.2.2.dist-info/RECORD,,
6
+ togo-0.2.2.dist-info/licenses/LICENSE,sha256=OfTFHFMDSt9X89g-BWUVis-GuTPWAdjplg2z9d2dBCw,1073
@@ -0,0 +1,6 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.9.0)
3
+ Root-Is-Purelib: false
4
+ Tag: cp310-cp310-manylinux_2_24_x86_64
5
+ Tag: cp310-cp310-manylinux_2_28_x86_64
6
+
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Giorgio Salluzzo
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1 @@
1
+ togo
Binary file