Skip to main content

Rust transpilation of pymdu (Python Urban Data Model) - Python bindings

Project description

pymdurs

Rust transpilation of pymdu (Python Urban Data Model).

This project transpiles the Python pymdu library to Rust, using the GeoRust ecosystem for geospatial operations. It provides three deployment targets: native Rust library, Python bindings (PyO3), and WebAssembly (WASM) for browser-based applications.

๐ŸŽฏ Project Overview

pymdurs is a comprehensive geospatial data processing library for urban data analysis, providing:

  • Native Rust library (rsmdu) - High-performance geospatial operations
  • Python bindings (pymdurs) - Pythonic API with PyO3
  • WebAssembly bindings (rsmdu-wasm) - Browser-based geospatial processing

๐Ÿ“ฆ Project Structure

This project is organized as a Cargo workspace with three main crates:

pymdurs/
โ”œโ”€โ”€ rsmdu/              # Core Rust library
โ”‚   โ”œโ”€โ”€ src/
โ”‚   โ”‚   โ”œโ”€โ”€ geometric/          # Geometric data structures
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ building.rs     # Building and BuildingCollection
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ dem.rs          # Digital Elevation Model
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ cadastre.rs     # Cadastral parcel data
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ iris.rs         # IRIS statistical units
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ lcz.rs          # Local Climate Zone
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ road.rs         # Road segments
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ water.rs        # Water bodies
โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ vegetation.rs   # Vegetation zones
โ”‚   โ”‚   โ”œโ”€โ”€ collect/            # Data collection modules
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ ign/            # IGN API integration
โ”‚   โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ ign_collect.rs
โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ global_variables.rs
โ”‚   โ”‚   โ”œโ”€โ”€ geo_core.rs         # Base GeoCore class
โ”‚   โ”‚   โ”œโ”€โ”€ commons/            # Common utilities
โ”‚   โ”‚   โ”œโ”€โ”€ lib.rs              # Library root
โ”‚   โ”‚   โ””โ”€โ”€ main.rs             # Binary entry point
โ”‚   โ””โ”€โ”€ examples/               # Rust usage examples
โ”‚
โ”œโ”€โ”€ pymdurs/            # Python bindings (PyO3)
โ”‚   โ”œโ”€โ”€ src/
โ”‚   โ”‚   โ””โ”€โ”€ bindings/          # PyO3 bindings
โ”‚   โ”œโ”€โ”€ examples/              # Python usage examples
โ”‚   โ””โ”€โ”€ tests/                 # Python tests
โ”‚
โ””โ”€โ”€ rsmdu-wasm/        # WebAssembly bindings
    โ”œโ”€โ”€ src/
    โ”‚   โ””โ”€โ”€ lib.rs             # WASM bindings
    โ””โ”€โ”€ examples/              # Browser examples
        โ”œโ”€โ”€ index.html         # Building visualization
        โ””โ”€โ”€ dem.html           # DEM visualization

โœจ Features

๐Ÿข Building Data Management

  • Building data collection: Load buildings from Shapefiles, GeoJSON, or IGN API
  • Geometric operations: Area, centroid, and height calculations
  • Data processing: Height processing with fallback to storeys or mean district height
  • Height calculation: Automatic height filling using:
    • Number of storeys ร— default storey height
    • Alternative height field (HAUTEUR_2)
    • Mean district height (weighted by area)
  • DataFrame support: Integration with Polars for tabular operations (equivalent to GeoDataFrame)
  • WebAssembly support: Process building data directly in the browser

๐Ÿ—ป Digital Elevation Model (DEM)

  • DEM collection: Download DEM data from IGN API via WMS-R
  • Raster processing: GeoTIFF handling and validation
  • Mask generation: Automatic mask creation for DEM boundaries
  • Browser visualization: Interactive DEM viewer with Leaflet.js integration
  • IGN API integration: Direct loading from IGN WMS service in browser

๐Ÿ—บ๏ธ Cadastral Data

  • Cadastre collection: Download cadastral parcel data from IGN API via WFS
  • GeoJSON parsing: Automatic parsing of IGN API responses
  • GeoJSON export: Save cadastral data to GeoPackage format

๐Ÿ“Š IRIS Statistical Units

  • IRIS collection: Download IRIS (statistical units) data from IGN API via WFS
  • GeoJSON parsing: Automatic parsing of IGN API responses
  • GeoJSON export: Save IRIS data to GeoPackage format

๐ŸŒก๏ธ LCZ (Local Climate Zone)

  • LCZ collection: Load Local Climate Zone data from external sources
  • Color mapping: Built-in LCZ color table (17 LCZ types)
  • Spatial filtering: Filter LCZ data by bounding box
  • Shapefile support: Load from zip URLs (requires GDAL)

๐Ÿ›ฃ๏ธ Road and Infrastructure

  • Road collection: Download road segments from IGN API
  • Water bodies: Download water body data from IGN API
  • Vegetation zones: Download vegetation data from IGN API

๐Ÿ›ฐ๏ธ LiDAR Processing

  • LiDAR data collection: Download LAZ files from IGN WFS service
  • Point cloud processing: Load and process LiDAR point clouds
  • Raster generation: Create DSM (Digital Surface Model), DTM (Digital Terrain Model), and CHM (Canopy Height Model)
  • Classification filtering: Filter points by classification (ground, vegetation, buildings, water, etc.)
  • Multi-band GeoTIFF export: Export processed rasters as multi-band GeoTIFF files
  • Automatic workflow: Points are automatically fetched and loaded when bounding box is set

๐ŸŒ IGN API Integration

  • WFS (Web Feature Service): Vector data retrieval (buildings, roads, water, etc.)
  • WMS (Web Map Service): Raster data retrieval (DEM, orthoimagery, etc.)
  • WMS-R endpoint: Optimized raster service endpoint
  • OGC compliance: Follows OGC WFS 2.0.0 and WMS 1.3.0 standards
  • Browser support: Direct API calls from WebAssembly

๐ŸŽจ WebAssembly Features

  • Building processing: Load and process building GeoJSON in the browser
  • DEM visualization: Interactive DEM viewer with color scales
  • IGN API integration: Fetch data directly from IGN API in browser
  • Leaflet.js integration: Seamless integration with Leaflet maps
  • Dynamic bbox: Automatic bounding box updates based on map view

๐Ÿš€ Installation

Python Package

Requirements: Python >= 3.10, pandas >= 2.0.0, numpy >= 2.0.2

Important: Run maturin from the project root (where pyproject.toml is). Maturin uses manifest-path = "pymdurs/Cargo.toml".

1. Clone and setup

git clone https://github.com/rupeelab17/rsmdu.git
cd rsmdu
uv venv .venv --python 3.13
source .venv/bin/activate
uv pip install maturin
uv sync

2. Install GDAL (prerequisite)

Platform Command
macOS brew install gdal or ARCHFLAGS="-arch arm64" uv pip install --no-cache-dir gdal
Linux sudo apt-get update && sudo apt-get install -y libgdal-dev gdal-bin libclang-dev
Windows OSGeo4W (GDAL, GEOS, PROJ, SQLite3) + choco install llvm pkgconfiglite sqlite -y + set GDAL_HOME, PKG_CONFIG_PATH, PATH

3. Build (maturin develop)

Platform Target Command
macOS (Apple Silicon) aarch64-apple-darwin maturin develop --target aarch64-apple-darwin
macOS (Intel) x86_64-apple-darwin maturin develop --target x86_64-apple-darwin
Linux (x86_64) x86_64-unknown-linux-gnu maturin develop --target x86_64-unknown-linux-gnu or maturin develop
Linux (ARM64) aarch64-unknown-linux-gnu maturin develop --target aarch64-unknown-linux-gnu
Windows x86_64-pc-windows-msvc maturin develop --target x86_64-pc-windows-msvc

With uv: uv run maturin develop --target <target>

macOS: linker can't find GDAL / "library 'gdal' not found"
If you upgraded GDAL or PROJ with Homebrew, the linker may still use old paths. Clean and point pkg-config at the current install, then rebuild:

cd pymdurs && cargo clean && cd ..
export PKG_CONFIG_PATH="/opt/homebrew/lib/pkgconfig"
maturin develop --target aarch64-apple-darwin

4. Verify and release

python -c "import pymdurs; print('OK')"
# Release wheel
maturin build --target <target> --release

Installing Rust

Maturin compiles the Rust extension. If Rust is not installed, follow the instructions for your operating system:

Windows

  1. Download and run rustup-init.exe:

    • Visit https://rustup.rs/
    • Download rustup-init.exe
    • Run the installer and follow the prompts
  2. Or use PowerShell:

    Invoke-WebRequest -Uri https://win.rustup.rs/x86_64 -OutFile rustup-init.exe
    .\rustup-init.exe
    
  3. Verify installation:

    rustc --version
    cargo --version
    
  4. Install Visual Studio Build Tools (required for Windows):

Note: On Windows, you may need to restart your terminal after installation for PATH changes to take effect.

macOS

  1. Install using Homebrew (recommended):

    brew install rust
    
  2. Or use rustup (official installer):

    curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
    
  3. Follow the prompts and restart your terminal

  4. Verify installation:

    rustc --version
    cargo --version
    

Note: On macOS, you may need to install Xcode Command Line Tools:

xcode-select --install

Linux

  1. Install using your package manager:

    Ubuntu/Debian:

    sudo apt update
    sudo apt install rustc cargo
    

    Fedora:

    sudo dnf install rust cargo
    

    Arch Linux:

    sudo pacman -S rust
    
  2. Or use rustup (recommended for latest version):

    curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
    source $HOME/.cargo/env
    
  3. Install build dependencies (required):

    Ubuntu/Debian:

    sudo apt install build-essential pkg-config libssl-dev
    

    Fedora:

    sudo dnf install gcc pkg-config openssl-devel
    

    Arch Linux:

    sudo pacman -S base-devel
    
  4. Verify installation:

    rustc --version
    cargo --version
    

Docker

When building an image that installs pymdurs with uv pip install https://github.com/rupeelab17/rsmdu.git, Rust must be installed in a previous layer. If Rust is not present, maturin installs it on the fly and can hit "Text file busy (os error 26)" when running cargo metadata immediately after.

Fix: install Rust (e.g. with rustup) before the step that runs uv pip install:

# Install Rust so maturin does not auto-install it (avoids "Text file busy")
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable \
    && . "$HOME/.cargo/env" \
    && rustc --version
ENV PATH="/root/.cargo/bin:${PATH}"

# Then install pymdurs (maturin will find cargo and build the wheel)
RUN micromamba run -n umep_pymdu python -m uv pip install https://github.com/rupeelab17/rsmdu.git

Adjust the environment (e.g. micromamba run -n umep_pymdu, or ENV PATH if Rust is installed for another user) to match your image.

WebAssembly

# Install wasm-pack
cargo install wasm-pack

# Add WASM target
rustup target add wasm32-unknown-unknown

# Navigate to WASM package directory
cd rsmdu-wasm

# Fix WASM target (if needed)
./fix-wasm-target.sh

# Build WASM package
./build.sh

See rsmdu-wasm/README.md for detailed WebAssembly setup instructions.

๐Ÿ“– Usage

Rust Library

Building Collection

use rsmdu::geometric::building::BuildingCollection;

// Create BuildingCollection (Python: Building(output_path='./'))
let mut buildings = BuildingCollection::new(
    None,                              // filepath_shp (None = use IGN API)
    Some("./output".to_string()),      // output_path
    3.0,                               // defaultStoreyHeight
    None,                              // set_crs (None = default EPSG:2154)
)?;

// Set bounding box (Python: buildings.bbox = [...])
buildings.set_bbox(-1.152704, 46.181627, -1.139893, 46.18699)?;

// Run processing (Python: buildings = buildings.run())
let buildings = buildings.run()?;

// Convert to Polars DataFrame (Python: buildings.to_gdf())
let df = buildings.to_polars_df()?;

DEM (Digital Elevation Model)

use rsmdu::geometric::dem::Dem;

// Create Dem instance
let mut dem = Dem::new(Some("./output".to_string()))?;

// Set bounding box
dem.set_bbox(-1.152704, 46.181627, -1.139893, 46.18699);

// Run DEM processing
let dem_result = dem.run(None)?;

// Get output paths
println!("DEM saved to: {:?}", dem_result.get_path_save_tiff());
println!("Mask: {:?}", dem_result.get_path_save_mask());

Python Bindings

import pymdurs

# Create BuildingCollection
buildings = pymdurs.geometric.Building(
    output_path="./output",
    defaultStoreyHeight=3.0
)

# Set bounding box
buildings.set_bbox(-1.152704, 46.181627, -1.139893, 46.18699)

# Run processing (downloads from IGN API)
buildings = buildings.run()

# Convert to pandas DataFrame
df = buildings.to_pandas()

LiDAR Processing

import pymdurs

# Create Lidar instance
lidar = pymdurs.geometric.Lidar(output_path="./output")

# Set bounding box (automatically fetches LAZ file URLs and loads points)
# Format: min_x, min_y, max_x, max_y (WGS84, EPSG:4326)
lidar.set_bbox(-1.154894, 46.182639, -1.148361, 46.186820)

# Set CRS (optional, defaults to EPSG:2154)
lidar.set_crs(2154)

# Process points to create rasters (DSM, DTM, CHM)
# Classification filter: 2=Ground, 3=Low Vegetation, 4=Medium, 5=High, 6=Building, 9=Water
classification_list = [3, 4, 5, 9]  # Vegetation and water
output_path = lidar.run(file_name="CDSM.tif", classification_list=classification_list)

print(f"GeoTIFF saved to: {output_path}")
# File contains 3 bands: DSM, DTM, CHM

WebAssembly (Browser)

Building Processing

import init, { WasmBuildingCollection } from "./pkg/rsmdu_wasm.js";

// Initialize WASM
await init("./pkg/rsmdu_wasm_bg.wasm");

// Load buildings from GeoJSON
const geojson = {
  type: "FeatureCollection",
  features: [
    /* ... */
  ],
};

const collection = WasmBuildingCollection.from_geojson(
  JSON.stringify(geojson),
  3.0, // default storey height in meters
);

// Process heights
collection.process_heights();

// Get processed GeoJSON
const processedGeojson = collection.to_geojson();

// Get statistics
const stats = collection.get_stats();
console.log("Building count:", stats.count);
console.log("Total area:", stats.total_area);
console.log("Mean height:", stats.mean_height);

DEM Loading

import init, { WasmDem } from "./pkg/rsmdu_wasm.js";

// Initialize WASM
await init("./pkg/rsmdu_wasm_bg.wasm");

// Load DEM from IGN API
const dem = await WasmDem.from_ign_api(
  -1.152704, // min_x
  46.181627, // min_y
  -1.139893, // max_x
  46.18699, // max_y
);

// Get DEM dimensions
console.log("Width:", dem.width());
console.log("Height:", dem.height());

// Get extent
const extent = dem.get_extent();
console.log("Extent:", extent);

See rsmdu-wasm/examples/index.html and rsmdu-wasm/examples/dem.html for complete browser examples.

๐Ÿ“š Examples

Comprehensive examples are available for all three deployment targets:

Rust Examples

Located in rsmdu/examples/:

Building Examples:

  • building_manual.rs: Minimal example of manually creating buildings
  • building_from_geojson.rs: Complete example loading from GeoJSON
  • building_from_ign.rs: Example using run() method (Python-style)
  • building_from_ign_api.rs: Detailed example loading buildings from IGN API
  • building_complete.rs: Comprehensive example covering all use cases

Other Examples:

  • dem_from_ign.rs: Downloading and processing DEM from IGN API
  • cadastre_from_ign.rs: Downloading and processing cadastral data from IGN API
  • iris_from_ign.rs: Downloading and processing IRIS statistical units from IGN API
  • lcz_from_url.rs: Loading and processing LCZ data from URL
  • cosia_from_ign.rs: Downloading COSIA landcover raster from IGN API
  • rnb_from_api.rs: Downloading RNB (French National Building Reference) data from RNB API
  • road_from_ign.rs: Downloading road segments from IGN API
  • water_from_ign.rs: Downloading water bodies from IGN API
  • vegetation_from_ign.rs: Downloading vegetation zones from IGN API

Run Rust examples:

cd rsmdu
cargo run --example building_manual
cargo run --example building_from_geojson
cargo run --example building_from_ign
cargo run --example dem_from_ign
cargo run --example cadastre_from_ign
cargo run --example iris_from_ign
cargo run --example lcz_from_url
cargo run --example cosia_from_ign
cargo run --example rnb_from_api

Python Examples

Located in examples/ (see examples/README.md for full documentation):

  • building_basic.py: Basic Building usage
  • building_from_ign.py: Load buildings from IGN API
  • dem_from_ign.py: Download DEM from IGN API
  • cadastre_from_ign.py: Download cadastral data from IGN API
  • iris_from_ign.py: Download IRIS statistical units from IGN API
  • lcz_from_url.py: Load LCZ data from URL
  • cosia_from_ign.py: Complete COSIA workflow - download, vectorize and convert to UMEP format
  • rnb_from_api.py: Download RNB (French National Building Reference) data from RNB API
  • lidar_from_wfs.py: Download and process LiDAR data from IGN WFS service
  • road_from_ign.py: Download road segments from IGN API
  • water_from_ign.py: Download water bodies from IGN API
  • vegetation_from_ign.py: Download vegetation zones from IGN API
  • umep_workflow.py: Complete UMEP workflow for urban climate modeling (SOLWEIG, SVF, etc.)
  • umep_workflow_new.py: Alternative UMEP workflow using solweig (SOLWEIG from UMEP-dev), with GIF export from preview PNGs

Run Python examples (from project root):

python examples/building_basic.py
python examples/building_from_ign.py
python examples/dem_from_ign.py
python examples/cosia_from_ign.py
python examples/umep_workflow.py
python examples/umep_workflow_new.py

WebAssembly Examples

Located in rsmdu-wasm/examples/:

  • index.html: Interactive building visualization with Leaflet.js
    • Load buildings from GeoJSON or IGN API
    • Dynamic bounding box based on map view
    • Building statistics and visualization
  • dem.html: Interactive DEM visualization with Leaflet.js
    • Load DEM from local TIFF files or IGN API
    • Multiple color scales (terrain, elevation, grayscale)
    • Elevation query on click
    • Automatic OSM layer opacity adjustment

Run WebAssembly examples:

cd rsmdu-wasm
./build.sh
cd examples
python3 -m http.server 8000
# Open http://localhost:8000/index.html or http://localhost:8000/dem.html

๐ŸŒ IGN API

The library integrates with the French IGN (Institut Gรฉographique National) Gรฉoplateforme API.

Available Services

Vector Data (WFS):

  • buildings: Building footprints (BDTOPO_V3:batiment)
  • road: Road segments (BDTOPO_V3:troncon_de_route)
  • water: Water bodies (BDTOPO_V3:plan_d_eau)
  • cadastre: Cadastral parcels (CADASTRALPARCELS.PARCELLAIRE_EXPRESS:parcelle)
  • iris: IRIS statistical units (STATISTICALUNITS.IRIS:contours_iris)
  • lidar: LiDAR point cloud data (IGNF_LIDAR-HD_TA:nuage-dalle)
  • vegetation: Vegetation zones
  • hydrographique: Hydrographic details

Raster Data (WMS-R):

  • dem: Digital Elevation Model (ELEVATION.ELEVATIONGRIDCOVERAGE.HIGHRES)
  • dsm: Digital Surface Model
  • irc: IRC orthoimagery
  • ortho: High-resolution orthoimagery
  • cosia: COSIA imagery

API Requirements

  • Internet connection: Required for API requests
  • Rate limiting: The API may have rate limits
  • Coordinate system: Bounding boxes must be in WGS84 (EPSG:4326)
  • API keys: For production use, you may need to register at https://geoservices.ign.fr/
  • CORS: Browser-based requests require CORS support (available for IGN API)

๐Ÿ—๏ธ Architecture

Workspace Structure

The project uses a Cargo workspace with three crates:

  1. rsmdu: Core Rust library with all geospatial functionality

    • Uses feature flags (wasm) to conditionally compile WASM-incompatible dependencies
    • Optional dependencies: gdal, proj, geos, polars, reqwest, etc.
  2. pymdurs: Python bindings using PyO3

    • Depends on rsmdu crate
    • Provides Pythonic API with aliases
  3. rsmdu-wasm: WebAssembly bindings

    • Uses rsmdu with wasm feature flag
    • Only WASM-compatible dependencies (geo, geojson, geotiff, tiff)
    • Browser-specific APIs (web-sys, wasm-bindgen)

Inheritance Pattern (Python โ†’ Rust)

In Python, Building inherits from IgnCollect, which inherits from GeoCore. In Rust, we use composition:

// Python: class Building(IgnCollect)
// Rust: BuildingCollection contains GeoCore and IgnCollect
pub struct BuildingCollection {
    pub geo_core: GeoCore,           // Inherits from GeoCore
    ign_collect: Option<IgnCollect>,  // Inherits from IgnCollect
    // ...
}

GeoCore Properties

GeoCore provides base functionality:

  • epsg: Coordinate Reference System (default: 2154)
  • bbox: Bounding box
  • output_path: Output directory
  • output_path_shp: Shapefile output path
  • filename_shp: Shapefile filename

๐Ÿ“Š Status

โœ… Fully Implemented

Core Features:

  • โœ… GeoJSON parsing and building collection
  • โœ… IGN API integration (WFS and WMS)
  • โœ… Building height processing with multiple fallback strategies
  • โœ… DEM collection via WMS-R
  • โœ… Cadastral data collection via WFS
  • โœ… IRIS statistical units collection via WFS
  • โœ… LCZ data structure with color mapping (17 LCZ types)
  • โœ… Road, water, and vegetation data collection
  • โœ… Polars DataFrame conversion
  • โœ… GeoCore base class with all properties
  • โœ… BuildingCollection with run() method (Python-style)
  • โœ… Coordinate Reference System (CRS) transformations using Proj

Python Bindings (PyO3):

  • โœ… Complete Python bindings installable via pip install pymdurs
  • โœ… All geometric classes available: Building, Dem, Cadastre, Iris, Lcz, Lidar, Road, Water, Vegetation
  • โœ… Geometric submodule (pymdurs.geometric) for organized class access
  • โœ… Pythonic API with aliases (e.g., pymdurs.geometric.Building instead of PyBuilding)
  • โœ… Pandas DataFrame conversion for Building data
  • โœ… GeoJSON export/import
  • โœ… LiDAR processing with automatic point loading
  • โœ… Comprehensive Python examples and tests

WebAssembly Bindings:

  • โœ… Building collection processing in browser
  • โœ… DEM loading from IGN API in browser
  • โœ… DEM loading from local TIFF files
  • โœ… Interactive Leaflet.js visualization
  • โœ… Dynamic bounding box updates
  • โœ… Building statistics
  • โœ… DEM visualization with color scales
  • โœ… Elevation query on map click
  • โœ… OSM layer opacity control

Data Formats:

  • โœ… GeoJSON parsing and generation
  • โœ… GeoTIFF reading and validation
  • โœ… GeoJSON export (simplified, saves as GeoJSON temporarily)

๐Ÿšง In Progress / Limitations

Current Limitations:

  • โš ๏ธ GDAL Shapefile I/O temporarily disabled (API compatibility issues)
  • โš ๏ธ Full GeoJSON export not yet implemented (saves as GeoJSON as workaround)
  • โš ๏ธ LCZ shapefile loading from zip URLs requires full GDAL implementation
  • โš ๏ธ Raster reprojection simplified (full resampling not yet implemented)
  • โš ๏ธ Shapefile export for masks not yet available
  • โš ๏ธ DEM pixel data access in WASM (currently metadata only)

Workarounds:

  • Use GeoJSON format instead of Shapefiles for input/output
  • GeoJSON export currently saves as GeoJSON (full GeoJSON support planned)
  • LCZ processing structure ready but full shapefile loading pending GDAL fixes
  • DEM visualization uses JavaScript libraries (GeoRasterLayer) for pixel access

๐Ÿ“‹ Planned Features

Short-term:

  • Complete GDAL integration for Shapefile I/O
  • Full GeoJSON export with proper layer management
  • Full raster reprojection with resampling options
  • LCZ shapefile loading from zip URLs
  • Full DEM pixel data access in WASM

Long-term:

  • Additional geometric operations
  • More IGN API services
  • Performance optimizations
  • Additional output formats
  • Enhanced error handling and validation
  • 3D visualization capabilities

๐Ÿงช Testing

Rust Tests

Run Rust unit tests:

cd rsmdu
cargo test

Python Tests

Run Python tests:

cd pymdurs
pytest tests/

Or manually test the Python bindings:

cd pymdurs
python -c "import pymdurs; print('โœ… pymdurs imported successfully')"
python -c "import pymdurs; print('Available classes:', [x for x in dir(pymdurs.geometric) if not x.startswith('_')])"
python -c "import pymdurs; lidar = pymdurs.geometric.Lidar(output_path='./test'); print('โœ… Lidar class works')"

WebAssembly Tests

cd rsmdu-wasm
wasm-pack test --headless --firefox

๐Ÿค Contributing

Contributions are welcome! This project follows standard Rust and Python best practices.

Development Setup

  1. Clone the repository:

    git clone https://github.com/rupeelab17/pymdurs.git
    cd pymdurs
    
  2. Set up Rust development:

    Note: If you haven't installed Rust yet, see the Installing Rust section above.

    cd rsmdu
    cargo build
    cargo test
    
  3. Set up Python development: See Python Package for platform-specific build instructions.

  4. Set up WebAssembly development:

    cd rsmdu-wasm
    rustup target add wasm32-unknown-unknown
    cargo install wasm-pack
    ./build.sh
    

Contribution Guidelines

  • Follow Rust naming conventions and style
  • Add tests for new features
  • Update documentation (README.md) for significant changes
  • Ensure all examples still work after changes
  • Test all three deployment targets (Rust, Python, WASM)
  • Use feature flags for WASM-incompatible code

Reporting Issues

Please use GitHub Issues to report bugs or request features. Include:

  • Description of the issue
  • Steps to reproduce
  • Expected vs actual behavior
  • Environment details (OS, Rust version, Python version, browser for WASM)

๐Ÿ“„ License

GPL-3.0 (same as pymdu)

โšก Performance

This Rust implementation provides significant performance improvements over the original Python version:

  • Memory efficiency: Rust's ownership system prevents memory leaks
  • Concurrency: Safe parallel processing capabilities
  • Speed: Native compilation provides faster execution
  • Type safety: Compile-time error checking reduces runtime errors
  • WebAssembly: Near-native performance in the browser

๐Ÿ”— Related Projects

๐Ÿ“ Version

Current version: 0.1.1 (Alpha)

This is an early release. The API may change in future versions. See the Status section for implementation details.

๐Ÿ“š Documentation

  • Rust API: Run cargo doc --open in the rsmdu directory
  • Python API: See pymdurs/README.md
  • WebAssembly API: See rsmdu-wasm/README.md
  • Examples: See examples/README.md, rsmdu/examples/, and rsmdu-wasm/examples/

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

pymdurs-0.1.1.tar.gz (176.3 kB view details)

Uploaded Source

Built Distributions

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

pymdurs-0.1.1-cp38-abi3-manylinux_2_39_x86_64.whl (65.4 MB view details)

Uploaded CPython 3.8+manylinux: glibc 2.39+ x86-64

pymdurs-0.1.1-cp38-abi3-macosx_11_0_arm64.whl (7.6 MB view details)

Uploaded CPython 3.8+macOS 11.0+ ARM64

pymdurs-0.1.1-cp38-abi3-macosx_10_12_x86_64.whl (8.0 MB view details)

Uploaded CPython 3.8+macOS 10.12+ x86-64

File details

Details for the file pymdurs-0.1.1.tar.gz.

File metadata

  • Download URL: pymdurs-0.1.1.tar.gz
  • Upload date:
  • Size: 176.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pymdurs-0.1.1.tar.gz
Algorithm Hash digest
SHA256 1d1865874de58a320d6286356c4072ce15547a8dca58de599bda5be530916fc8
MD5 3d485dcb391a65cadcbd0408092103f7
BLAKE2b-256 50e829539a6fc517f9d7159c4f9fc4bfcca7486ba6c301ff3364bf8113aa89f5

See more details on using hashes here.

Provenance

The following attestation bundles were made for pymdurs-0.1.1.tar.gz:

Publisher: release-python.yml on rupeelab17/rsmdu

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pymdurs-0.1.1-cp38-abi3-manylinux_2_39_x86_64.whl.

File metadata

File hashes

Hashes for pymdurs-0.1.1-cp38-abi3-manylinux_2_39_x86_64.whl
Algorithm Hash digest
SHA256 2c491d525d14992d8eafc17e98f3245574595c3d36b893fb269feceae4a822da
MD5 28fa03bc21ca7af11f15cbb3f0448bba
BLAKE2b-256 a5d50d3943421ad26ed1b2ab21a7e9f0cfea198d3650034a37de53440cb88a42

See more details on using hashes here.

Provenance

The following attestation bundles were made for pymdurs-0.1.1-cp38-abi3-manylinux_2_39_x86_64.whl:

Publisher: release-python.yml on rupeelab17/rsmdu

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pymdurs-0.1.1-cp38-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for pymdurs-0.1.1-cp38-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 9403131deae810fe37dae421a5f84e5ed52da698adb781728ecd66441540a3d3
MD5 0b4d2def48c46b2d8bd4a7d7c6ea6544
BLAKE2b-256 45eee908cfcd8fbd11294d170d6ff453a7eb1b0190b5da4068316c3de4b7263c

See more details on using hashes here.

Provenance

The following attestation bundles were made for pymdurs-0.1.1-cp38-abi3-macosx_11_0_arm64.whl:

Publisher: release-python.yml on rupeelab17/rsmdu

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pymdurs-0.1.1-cp38-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for pymdurs-0.1.1-cp38-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 5024805518835b38f70cb28013225476fd173296b4d023ff62b795d046093345
MD5 a7bc3392fbff125e84114e3fe70f36db
BLAKE2b-256 6471ab21c9aa5f51bc28fb78608ad64e426f73e424729c407390377669a2d998

See more details on using hashes here.

Provenance

The following attestation bundles were made for pymdurs-0.1.1-cp38-abi3-macosx_10_12_x86_64.whl:

Publisher: release-python.yml on rupeelab17/rsmdu

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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