Skip to main content

Python Package to Generate Any Random Geometry

Project description

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

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

anygeom_py-0.1.0.tar.gz (10.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

anygeom_py-0.1.0-py3-none-any.whl (11.4 kB view details)

Uploaded Python 3

File details

Details for the file anygeom_py-0.1.0.tar.gz.

File metadata

  • Download URL: anygeom_py-0.1.0.tar.gz
  • Upload date:
  • Size: 10.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.2.1 CPython/3.12.9 Darwin/25.3.0

File hashes

Hashes for anygeom_py-0.1.0.tar.gz
Algorithm Hash digest
SHA256 9eaf5bc9ccc29aec24ce58b0dd96229be92695b8ac1ad22801e39f5b9788f20f
MD5 85575da8702ffc99b844cd5ead3751b5
BLAKE2b-256 a4daf4b0f218e3f2669753079511d5870ec4913c18baac4666207aed558822e1

See more details on using hashes here.

File details

Details for the file anygeom_py-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: anygeom_py-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 11.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.2.1 CPython/3.12.9 Darwin/25.3.0

File hashes

Hashes for anygeom_py-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 2334ea4a4eb399bb721297cb84fb036021b8b341c820474fdf02833a72c29df3
MD5 cad2f91baf2386b2f704083c6e9b360a
BLAKE2b-256 85d35c5ba24b2660768c397adaeecaacb4688538e5ecd7212018a7066dee71d2

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page