anygeom-py
Python package to generate any kind of geospatial geometry
Motivation
As a GIS developer, often times while working on projects, I need to test my functions with dummy geometries, currently, I go on sites like geojson.io to generate geometries. But this process is time consuming, and more importantly I can only generate data in EPSG:4326. I need solution that can Generate Random Geometry based on
- Geometry Type
- Projection
- BBOX
- Count
- Multi/Single
as per my need.
Installation
pip install anygeom-py
Quick Start
from anygeom import Point, LineString, Polygon, Circle
# Generate single point (returns GeoJSON Feature)
point = Point()
# Generate 3 random points in projection EPSG:32643, within given bbox
# Returns list of 3 GeoJSON Features
points = Point(count=3, crs=32643, bbox=[53.127823, 7.047742, 106.125870, 35.488629])
# Generate 4 random linestrings in projection EPSG:4326, each having 3 to 6 vertices
# Returns list of 4 GeoJSON Features
linestrings = LineString(count=4, crs=4326, min_vertex=3, max_vertex=6)
# Generate random polygon having 6 to 10 vertices with hole in it
# Returns single GeoJSON Feature
polygon = Polygon(hole=True, min_vertex=6, max_vertex=10)
# Generate random circle with custom radius
circle = Circle(radius=5, crs=4326)
# Generate multiple circles
circles = Circle(count=3, bbox=[0, 0, 10, 10])
Features
- Geometry Types: Point, LineString, Polygon, Circle, MultiPoint, MultiLineString, MultiPolygon
- CRS Support: Any EPSG code (e.g., 4326, 3857, 32643)
- Custom Bounding Box: Define area for geometry generation
- Vertex Control: Set min/max vertices for LineStrings and Polygons
- Polygon Holes: Generate polygons with holes
- Count Control: Generate single or multiple geometries
- GeoJSON Export: Proper GeoJSON Feature format with list coordinates
- Shapely Compatible: All geometries are Shapely objects
- Input Validation: Clear error messages for invalid parameters
Usage Examples
Basic Geometry Generation
from anygeom import Point, LineString, Polygon, Circle
import json
# Single geometry returns GeoJSON Feature
point = Point()
print(json.dumps(point.__geo_interface__, indent=2))
# Output:
# {
# "type": "Feature",
# "properties": {},
# "geometry": {
# "type": "Point",
# "coordinates": [34.62, 14.18]
# }
# }
# Multiple geometries return list of Features
points = Point(count=3)
print(len(points)) # 3
print(points[0]) # Access individual features
Working with Different CRS
# Generate geometries in Web Mercator (EPSG:3857)
point_3857 = Point(crs=3857)
# Generate geometries in UTM Zone 43N (EPSG:32643)
points_utm = Point(count=5, crs=32643, bbox=[72.0, 12.0, 84.0, 30.0])
Custom Bounding Box
# Generate geometries within specific area
india_bbox = [68.1766, 7.9668, 97.4025, 35.4940]
points = Point(count=10, bbox=india_bbox)
lines = LineString(count=5, bbox=india_bbox, min_vertex=3, max_vertex=8)
LineStrings with Vertex Control
# Simple linestring with 2-5 vertices
line = LineString()
# Complex linestring with 10-20 vertices
complex_line = LineString(min_vertex=10, max_vertex=20)
# Multiple linestrings
lines = LineString(count=4, min_vertex=3, max_vertex=6)
Polygons with Holes
# Simple polygon
polygon = Polygon()
# Polygon with specific vertex count
polygon = Polygon(min_vertex=8, max_vertex=12)
# Polygon with hole
polygon_with_hole = Polygon(hole=True, min_vertex=6, max_vertex=10)
# Multiple polygons with holes
polygons = Polygon(count=3, hole=True)
Circles
# Circle with auto-calculated radius
circle = Circle()
# Circle with custom radius (in CRS units)
circle = Circle(radius=5, crs=4326)
# Circle in Web Mercator with radius in meters
circle_meters = Circle(radius=1000, crs=3857)
# Multiple circles
circles = Circle(count=5, bbox=[0, 0, 10, 10])
# Control circle smoothness
smooth_circle = Circle(num_points=128) # More points = smoother circle
Exporting as GeoJSON
# Single geometry
point = Point()
geojson = point.__geo_interface__
# Returns: {"type": "Feature", "properties": {}, "geometry": {...}}
# Multiple geometries
points = Point(count=3)
geojson_list = points.__geo_interface__
# Returns: [{"type": "Feature", ...}, {"type": "Feature", ...}, ...]
# Save to file
import json
with open('points.geojson', 'w') as f:
json.dump(geojson_list, f, indent=2)
Using with Shapely
from anygeom import Point, Polygon
# All geometries are Shapely-compatible
point = Point()
print(point.x, point.y) # Access Shapely properties
print(point.buffer(1)) # Use Shapely methods
polygon = Polygon()
print(polygon.area) # Calculate area
print(polygon.bounds) # Get bounds
API Reference
Common Parameters
All geometry classes support these parameters:
- count (int): Number of geometries to generate (default: 1)
- crs (int): EPSG code for coordinate reference system (default: 4326)
- bbox (list): Bounding box as [minx, miny, maxx, maxy] (default: world bounds)
Point
Point(count=1, crs=4326, bbox=None)
Generates random point geometries.
LineString
LineString(count=1, crs=4326, bbox=None, min_vertex=2, max_vertex=5)
Generates random linestring geometries.
Additional Parameters:
- min_vertex (int): Minimum number of vertices (default: 2)
- max_vertex (int): Maximum number of vertices (default: 5)
Polygon
Polygon(count=1, crs=4326, bbox=None, min_vertex=3, max_vertex=8, hole=False)
Generates random polygon geometries.
Additional Parameters:
- min_vertex (int): Minimum number of vertices (default: 3)
- max_vertex (int): Maximum number of vertices (default: 8)
- hole (bool): Generate polygon with hole (default: False)
Circle
Circle(count=1, crs=4326, bbox=None, radius=None, num_points=64)
Generates circular polygon geometries.
Additional Parameters:
- radius (float): Circle radius in CRS units (default: auto-calculated from bbox)
- num_points (int): Number of points to approximate circle (default: 64)
MultiPoint, MultiLineString, MultiPolygon
MultiPoint(count=2, crs=4326, bbox=None)
MultiLineString(count=2, crs=4326, bbox=None, min_vertex=2, max_vertex=5)
MultiPolygon(count=2, crs=4326, bbox=None, min_vertex=3, max_vertex=8, hole=False)
Generates Multi* geometry types (single feature with multiple geometries).
Output Format
Single Geometry
When count=1, returns a single GeoJSON Feature:
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "Point",
"coordinates": [34.62, 14.18]
}
}
Multiple Geometries
When count>1, returns a list of GeoJSON Features:
[
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "Point",
"coordinates": [34.62, 14.18]
}
},
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "Point",
"coordinates": [37.27, 10.92]
}
}
]
Error Handling
The package validates all inputs and provides clear error messages:
# Invalid vertex range
LineString(min_vertex=40, max_vertex=6)
# ValueError: min_vertex (40) cannot be greater than max_vertex (6)
# Invalid bbox (minx > maxx)
Point(bbox=[83.77, 29.12, 72.81, 12.70])
# ValueError: bbox minx (83.77) must be less than maxx (72.81)
# Invalid count
Point(count=0)
# ValueError: count must be at least 1, got 0
# Invalid bbox format
Point(bbox=[0, 0, 10])
# ValueError: bbox must have exactly 4 values [minx, miny, maxx, maxy], got 3
Dependencies
- Python >= 3.11
- shapely >= 2.1.2 - For geometry operations and GeoJSON export
- pyproj >= 3.7.2 - For coordinate reference system transformations
Technical Details
Architecture
The package uses a wrapper pattern to provide GeoJSON Feature output while maintaining Shapely compatibility:
- _GeometryWrapper: Wraps single Shapely geometries and returns GeoJSON Features
- _GeometryListWrapper: Wraps multiple geometries and returns list of Features
- All geometry classes use
__new__to return appropriate wrapper types
CRS Handling
- Default CRS is EPSG:4326 (WGS84)
- Bounding boxes are always provided in EPSG:4326 and transformed internally
- Special handling for EPSG:3857 (Web Mercator) with latitude limits (-85 to 85)
- Uses pyproj for accurate coordinate transformations
GeoJSON Compliance
- Coordinates are proper Python lists (not tuples)
- All geometries wrapped in GeoJSON Feature format
- Compatible with standard GeoJSON tools and libraries
- Can be directly serialized to JSON
Geometry Generation
- Points: Random coordinates within bbox
- LineStrings: Random vertices connected in sequence
- Polygons: Generated using center point and radius with random variations
- Circles: Created using Shapely's buffer operation for perfect circles
- All geometries respect the specified bounding box
Development
Setup
# Clone repository
git clone https://github.com/yourusername/anygeom-py.git
cd anygeom-py
# Install dependencies
poetry install
# Run tests
poetry run python test_anygeom.py
# Run examples
poetry run python example.py
Building
# Build package
poetry build
# Install locally
pip install dist/anygeom_py-0.1.0-py3-none-any.whl
Contributing
Contributions are welcome! Please follow these guidelines:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes
- Add tests for new functionality
- Ensure all tests pass
- Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Code Style
- Follow PEP 8 guidelines
- Use type hints where appropriate
- Add docstrings for public methods
- Keep functions focused and minimal
Testing
- Add tests for new features
- Ensure existing tests pass
- Test with different CRS codes
- Validate GeoJSON output format
License
MIT License - see LICENSE file for details
Author
Krishna Lodha (krishna@rottengrapes.tech)
Links
Metadata
Release files for anygeom-py 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| anygeom_py-0.1.0.tar.gz | 10.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| anygeom_py-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 21.7 kB
Release files / anygeom_py-0.1.0.tar.gz
| Download URL | anygeom_py-0.1.0.tar.gz |
|---|---|
| Size | 10.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9eaf5bc9ccc29aec24ce58b0dd96229be92695b8ac1ad22801e39f5b9788f20f
|
|
BLAKE2b-256 checksum How to use checksums |
a4daf4b0f218e3f2669753079511d5870ec4913c18baac4666207aed558822e1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/2.2.1 CPython/3.12.9 Darwin/25.3.0
|
Release files / anygeom_py-0.1.0-py3-none-any.whl
| Download URL | anygeom_py-0.1.0-py3-none-any.whl |
|---|---|
| Size | 11.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
2334ea4a4eb399bb721297cb84fb036021b8b341c820474fdf02833a72c29df3
|
|
BLAKE2b-256 checksum How to use checksums |
85d35c5ba24b2660768c397adaeecaacb4688538e5ecd7212018a7066dee71d2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/2.2.1 CPython/3.12.9 Darwin/25.3.0
|