Skip to main content

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:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Make your changes
  4. Add tests for new functionality
  5. Ensure all tests pass
  6. Commit your changes (git commit -m 'Add amazing feature')
  7. Push to the branch (git push origin feature/amazing-feature)
  8. 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)

Source distribution for anygeom-py 0.1.0
File Size Uploaded
anygeom_py-0.1.0.tar.gz 10.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for anygeom-py 0.1.0
File Interpreter ABI Platform
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

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page