### Install pydelatin Source: https://github.com/kylebarron/pydelatin/blob/master/README.md Installation commands for pydelatin using pip or Conda. ```bash pip install pydelatin ``` ```bash conda install -c conda-forge pydelatin ``` -------------------------------- ### Run JavaScript benchmarks Source: https://github.com/kylebarron/pydelatin/blob/master/README.md Clone the repository and execute the benchmark script for the JavaScript implementation. ```bash git clone https://github.com/kylebarron/pydelatin cd test/bench_js/ yarn wget https://raw.githubusercontent.com/mapbox/delatin/master/index.js node -r esm bench.js ``` -------------------------------- ### Run Python benchmarks Source: https://github.com/kylebarron/pydelatin/blob/master/README.md Clone the repository and execute the benchmark script for the Python implementation. ```bash git clone https://github.com/kylebarron/pydelatin cd pydelatin pip install '.[test]' python bench.py ``` -------------------------------- ### Execute Complete Terrain Processing Pipeline Source: https://context7.com/kylebarron/pydelatin/llms.txt A full workflow demonstrating loading, mesh generation, rescaling, and quality comparison across different error thresholds. ```python from pydelatin import Delatin from pydelatin.util import decode_ele, rescale_positions from imageio import imread import numpy as np from time import time # Configuration TILE_PATH = 'terrain_rgb.png' MAX_ERROR = 30 # meters - lower = higher quality, more triangles BOUNDS = (-122.5, 37.5, -122.0, 38.0) # Geographic bounds # Load and decode terrain print("Loading terrain tile...") png = imread(TILE_PATH) terrain = decode_ele(png, 'mapbox') print(f"Terrain size: {terrain.shape}, range: {terrain.min():.1f}m to {terrain.max():.1f}m") # Generate mesh with timing print(f"\nGenerating mesh (max_error={MAX_ERROR}m)...") start = time() tin = Delatin(terrain, max_error=MAX_ERROR) elapsed = (time() - start) * 1000 # Get mesh data vertices = tin.vertices triangles = tin.triangles print(f"Generation time: {elapsed:.2f}ms") print(f"Vertices: {vertices.shape[0]}") print(f"Triangles: {triangles.shape[0]}") print(f"Actual max error: {tin.error:.4f}") # Rescale to geographic coordinates rescaled = rescale_positions(vertices, BOUNDS, flip_y=True) print(f"\nRescaled bounds:") print(f" X: {rescaled[:, 0].min():.6f} to {rescaled[:, 0].max():.6f}") print(f" Y: {rescaled[:, 1].min():.6f} to {rescaled[:, 1].max():.6f}") print(f" Z: {rescaled[:, 2].min():.2f}m to {rescaled[:, 2].max():.2f}m") # Quality comparison at different error levels print("\nQuality comparison:") for error in [1, 5, 10, 20, 50, 100]: tin_test = Delatin(terrain, max_error=error) print(f" max_error={error:3d}m: {tin_test.vertices.shape[0]:6d} vertices, {tin_test.triangles.shape[0]:6d} triangles") ``` -------------------------------- ### Export Terrain to Standard 3D Formats Source: https://context7.com/kylebarron/pydelatin/llms.txt Use meshio to save generated terrain meshes into common formats like VTK, STL, OBJ, or PLY. ```python from pydelatin import Delatin import meshio import numpy as np # Generate terrain mesh terrain = np.random.rand(256, 256) * 1000 tin = Delatin(terrain, max_error=20) vertices, triangles = tin.vertices, tin.triangles # Create meshio mesh object cells = [("triangle", triangles)] mesh = meshio.Mesh(vertices, cells) # Export to various formats mesh.write('terrain.vtk') # VTK format (ParaView) mesh.write('terrain.stl') # STL format (3D printing) mesh.write('terrain.obj') # OBJ format (Blender, etc.) mesh.write('terrain.ply') # PLY format (point cloud viewers) print(f"Exported mesh: {vertices.shape[0]} vertices, {triangles.shape[0]} triangles") ``` -------------------------------- ### Write mesh to file Source: https://github.com/kylebarron/pydelatin/blob/master/README.md Export the generated mesh to a VTK file using meshio. ```python mesh.write('foo.vtk') ``` -------------------------------- ### Save with Meshio Source: https://github.com/kylebarron/pydelatin/blob/master/README.md Exporting generated mesh data to various formats using the meshio library. ```python from pydelatin import Delatin import meshio tin = Delatin(terrain, max_error=30) vertices, triangles = tin.vertices, tin.triangles cells = [("triangle", triangles)] mesh = meshio.Mesh(vertices, cells) # Example output format ``` -------------------------------- ### Python benchmark output Source: https://github.com/kylebarron/pydelatin/blob/master/README.md Performance results for various max_error settings in the Python implementation. ```text mesh (max_error=30m): 27.322ms vertices: 5668, triangles: 11140 mesh (max_error=1m): 282.946ms mesh (max_error=2m): 215.839ms mesh (max_error=3m): 163.424ms mesh (max_error=4m): 127.203ms mesh (max_error=5m): 106.596ms mesh (max_error=6m): 91.868ms mesh (max_error=7m): 82.572ms mesh (max_error=8m): 74.335ms mesh (max_error=9m): 65.893ms mesh (max_error=10m): 60.999ms mesh (max_error=11m): 55.213ms mesh (max_error=12m): 54.475ms mesh (max_error=13m): 48.662ms mesh (max_error=14m): 47.029ms mesh (max_error=15m): 44.517ms mesh (max_error=16m): 42.059ms mesh (max_error=17m): 39.699ms mesh (max_error=18m): 37.657ms mesh (max_error=19m): 36.333ms mesh (max_error=20m): 34.131ms ``` -------------------------------- ### JavaScript benchmark output Source: https://github.com/kylebarron/pydelatin/blob/master/README.md Performance results for various max_error settings in the JavaScript implementation. ```text mesh (max_error=30m): 143.038ms vertices: 5668 triangles: 11140 mesh (max_error=0m): 1169.226ms mesh (max_error=1m): 917.290ms mesh (max_error=2m): 629.776ms mesh (max_error=3m): 476.958ms mesh (max_error=4m): 352.907ms mesh (max_error=5m): 290.946ms mesh (max_error=6m): 240.556ms mesh (max_error=7m): 234.181ms mesh (max_error=8m): 188.273ms mesh (max_error=9m): 162.743ms mesh (max_error=10m): 145.734ms mesh (max_error=11m): 130.119ms mesh (max_error=12m): 119.865ms mesh (max_error=13m): 114.645ms mesh (max_error=14m): 101.390ms mesh (max_error=15m): 100.065ms mesh (max_error=16m): 96.247ms mesh (max_error=17m): 89.508ms mesh (max_error=18m): 85.754ms mesh (max_error=19m): 79.838ms mesh (max_error=20m): 75.607ms ``` -------------------------------- ### Save as Quantized Mesh Source: https://github.com/kylebarron/pydelatin/blob/master/README.md Exporting generated mesh data to the Quantized Mesh format using quantized-mesh-encoder. ```python import quantized_mesh_encoder from pydelatin import Delatin from pydelatin.util import rescale_positions tin = Delatin(terrain, max_error=30) vertices, triangles = tin.vertices, tin.triangles # Rescale vertices linearly from pixel units to world coordinates rescaled_vertices = rescale_positions(vertices, bounds) with open('output.terrain', 'wb') as f: quantized_mesh_encoder.encode(f, rescaled_vertices, triangles) ``` -------------------------------- ### Download Terrain-RGB Tile Source: https://github.com/kylebarron/pydelatin/blob/master/test/README.md Use this URL to download a specific tile from the Mapbox Terrain-RGB dataset. Replace '...' with your Mapbox access token. ```url https://api.mapbox.com/v4/mapbox.terrain-rgb/10/906/404@2x.png?access_token=... ``` -------------------------------- ### Export Terrain to Quantized Mesh Source: https://context7.com/kylebarron/pydelatin/llms.txt Convert terrain data into the Quantized Mesh format for compatibility with Cesium and deck.gl. ```python import quantized_mesh_encoder from pydelatin import Delatin from pydelatin.util import rescale_positions, decode_ele from imageio import imread # Load and decode terrain tile png = imread('terrain_tile.png') terrain = decode_ele(png, 'mapbox') # Generate optimized mesh tin = Delatin(terrain, max_error=30) vertices, triangles = tin.vertices, tin.triangles # Define tile bounds (Web Mercator or WGS84) bounds = (-122.5, 37.5, -122.0, 38.0) # Rescale to geographic coordinates rescaled_vertices = rescale_positions(vertices, bounds, flip_y=True) # Export to Quantized Mesh format with open('output.terrain', 'wb') as f: quantized_mesh_encoder.encode(f, rescaled_vertices, triangles) print(f"Exported {triangles.shape[0]} triangles to output.terrain") ``` -------------------------------- ### Generate Terrain Mesh Source: https://github.com/kylebarron/pydelatin/blob/master/README.md Basic usage of the Delatin class to generate mesh vertices and triangles from terrain data. ```python from pydelatin import Delatin tin = Delatin(terrain, width, height) # Mesh vertices tin.vertices # Mesh triangles tin.triangles ``` -------------------------------- ### Class: Delatin Source: https://github.com/kylebarron/pydelatin/blob/master/README.md The Delatin class is the primary interface for generating terrain meshes from input arrays. ```APIDOC ## Class: Delatin ### Description Initializes the Delatin triangulation process on a provided terrain array. ### Arguments - **arr** (numpy ndarray) - Required - Data array. If 2D, dimensions are (height, width). If 1D, height and width must be provided. - **height** (int) - Optional - Height of array; required when arr is not 2D. - **width** (int) - Optional - Width of array; required when arr is not 2D. - **z_scale** (float) - Optional - z scale relative to x & y (default: 1). - **z_exag** (float) - Optional - z exaggeration (default: 1). - **max_error** (float) - Optional - maximum triangulation error (default: 0.001). - **max_triangles** (int) - Optional - maximum number of triangles. - **max_points** (int) - Optional - maximum number of vertices. - **base_height** (float) - Optional - solid base height (default: 0). - **level** (bool) - Optional - auto level input to full grayscale range (default: False). - **invert** (bool) - Optional - invert heightmap (default: False). - **blur** (int) - Optional - gaussian blur sigma (default: 0). - **gamma** (float) - Optional - gamma curve exponent (default: 0). - **border_size** (int) - Optional - border size in pixels (default: 0). - **border_height** (float) - Optional - border z height (default: 1). ### Attributes - **vertices** (ndarray) - The interleaved 3D coordinates of each vertex. - **triangles** (ndarray) - Indices within the vertices array representing triangles. - **error** (float) - The maximum error of the mesh. ``` -------------------------------- ### Rescale Mesh Vertex Positions to Geographic Coordinates Source: https://context7.com/kylebarron/pydelatin/llms.txt Use rescale_positions to convert mesh vertex coordinates from pixel space to geographic coordinates (e.g., Web Mercator). Requires the geographic bounds of the original data. The Y-axis can be flipped if the image origin is top-left. ```python from pydelatin import Delatin from pydelatin.util import rescale_positions import numpy as np # Generate mesh from terrain terrain = np.random.rand(256, 256) * 500 tin = Delatin(terrain, max_error=20) # Define geographic bounds [minx, miny, maxx, maxy] # Example: tile bounds in Web Mercator coordinates bounds = (-122.5, 37.5, -122.0, 38.0) # San Francisco area # Rescale vertices to geographic coordinates rescaled_vertices = rescale_positions( tin.vertices, bounds, flip_y=True # Flip Y since image origin is top-left ) print(f"Original X range: {tin.vertices[:, 0].min():.1f} to {tin.vertices[:, 0].max():.1f}") print(f"Rescaled X range: {rescaled_vertices[:, 0].min():.4f} to {rescaled_vertices[:, 0].max():.4f}") # Z values (elevations) are preserved print(f"Z values unchanged: {np.allclose(tin.vertices[:, 2], rescaled_vertices[:, 2])}") ``` -------------------------------- ### Function: util.rescale_positions Source: https://github.com/kylebarron/pydelatin/blob/master/README.md A helper function to rescale mesh vertices to a specific bounding box. ```APIDOC ## Function: util.rescale_positions ### Description Rescales the vertices output to a new bounding box. ### Arguments - **vertices** (np.ndarray) - Required - Vertices output from Delatin. - **bounds** (Tuple[float]) - Required - Extent defined as [minx, miny, maxx, maxy]. - **flip_y** (bool) - Optional - Flip y coordinates (default: False). ``` -------------------------------- ### Generate Terrain Mesh with Delatin Class Source: https://context7.com/kylebarron/pydelatin/llms.txt Use the Delatin class to generate a terrain mesh from a NumPy heightmap array. Specify error tolerance and other parameters for mesh quality and detail. Supports basic and advanced configurations, including handling 1D array inputs. ```python from pydelatin import Delatin import numpy as np # Create sample terrain data (512x512 heightmap) terrain = np.random.rand(512, 512) * 1000 # Random elevations 0-1000m # Basic mesh generation with 30m error tolerance tin = Delatin(terrain, max_error=30) # Access mesh data vertices = tin.vertices # Shape: (-1, 3) - [x, y, z] coordinates triangles = tin.triangles # Shape: (-1, 3) - vertex indices per triangle error = tin.error # Maximum mesh error print(f"Vertices: {vertices.shape[0]}") print(f"Triangles: {triangles.shape[0]}") print(f"Max error: {error}") # Advanced usage with all parameters tin_advanced = Delatin( terrain, z_scale=1.0, # Z scale relative to x & y z_exag=1.5, # Z exaggeration for visualization max_error=10, # Lower error = more triangles, higher quality max_triangles=50000, # Limit total triangles max_points=25000, # Limit total vertices base_height=0, # Solid base height level=False, # Auto-level to full grayscale range invert=False, # Invert heightmap blur=2, # Gaussian blur sigma (smoothing) gamma=0, # Gamma curve exponent border_size=0, # Border size in pixels border_height=1 # Border z height ) # Using 1D array input (requires explicit dimensions) flat_terrain = terrain.flatten() tin_1d = Delatin(flat_terrain, height=512, width=512, max_error=30) ``` -------------------------------- ### Decode Elevation Data from PNG Tiles Source: https://context7.com/kylebarron/pydelatin/llms.txt Use the decode_ele function to convert RGB-encoded elevation data from Mapbox Terrain RGB or Terrarium PNG tiles into meters. Requires imageio to load the PNG. ```python from pydelatin.util import decode_ele from imageio import imread import numpy as np # Load RGB terrain tile (e.g., from Mapbox or AWS Terrain Tiles) png = imread('terrain_tile.png') # Decode Mapbox RGB encoding # Formula: elevation = (R * 256 * 256 + G * 256 + B) / 10 - 10000 terrain_mapbox = decode_ele(png, encoding='mapbox') # Decode Terrarium encoding (used by AWS/Stamen terrain tiles) # Formula: elevation = (R * 256 + G + B / 256) - 32768 terrain_terrarium = decode_ele(png, encoding='terrarium') print(f"Terrain shape: {terrain_mapbox.shape}") print(f"Elevation range: {terrain_mapbox.min():.1f}m to {terrain_mapbox.max():.1f}m") # Full pipeline: decode and generate mesh from pydelatin import Delatin png = imread('fuji.png') terrain = decode_ele(png, 'mapbox') tin = Delatin(terrain, max_error=30) print(f"Generated mesh with {tin.vertices.shape[0]} vertices") ``` -------------------------------- ### Calculate Latitude Adjustment Factors Source: https://context7.com/kylebarron/pydelatin/llms.txt Adjust elevation scaling based on latitude to account for horizontal distance variations. ```python equator = latitude_adjustment(0) # 1.0 at equator san_francisco = latitude_adjustment(37.7749) # ~0.79 oslo = latitude_adjustment(59.9139) # ~0.50 print(f"Equator adjustment: {equator:.4f}") print(f"San Francisco (37.7°N): {san_francisco:.4f}") print(f"Oslo (59.9°N): {oslo:.4f}") # Use for scaling elevation relative to horizontal distances base_elevation_scale = 1.0 adjusted_scale = base_elevation_scale * latitude_adjustment(45.0) ``` -------------------------------- ### Delatin Class Source: https://context7.com/kylebarron/pydelatin/llms.txt The main class for generating terrain meshes from heightmap arrays. It accepts a NumPy array of elevation values and produces optimized triangle mesh vertices and indices. ```APIDOC ## Delatin Class ### Description Generates optimized 3D triangle meshes from 2D elevation arrays using the Delatin algorithm. ### Parameters - **terrain** (numpy.ndarray) - Required - 2D array of elevation values. - **z_scale** (float) - Optional - Z scale relative to x & y. - **z_exag** (float) - Optional - Z exaggeration for visualization. - **max_error** (float) - Optional - Error tolerance for mesh simplification. - **max_triangles** (int) - Optional - Limit total triangles. - **max_points** (int) - Optional - Limit total vertices. - **base_height** (float) - Optional - Solid base height. - **level** (bool) - Optional - Auto-level to full grayscale range. - **invert** (bool) - Optional - Invert heightmap. - **blur** (int) - Optional - Gaussian blur sigma. - **gamma** (float) - Optional - Gamma curve exponent. - **border_size** (int) - Optional - Border size in pixels. - **border_height** (float) - Optional - Border z height. - **height** (int) - Optional - Height dimension for 1D array input. - **width** (int) - Optional - Width dimension for 1D array input. ``` -------------------------------- ### decode_ele Function Source: https://context7.com/kylebarron/pydelatin/llms.txt Decodes RGB-encoded elevation data from Mapbox Terrain RGB or Terrarium PNG tiles into actual elevation values in meters. ```APIDOC ## decode_ele ### Description Decodes RGB-encoded elevation data into meters. ### Parameters - **png** (numpy.ndarray) - Required - RGB terrain tile data. - **encoding** (string) - Required - Encoding type, either 'mapbox' or 'terrarium'. ``` -------------------------------- ### rescale_positions Function Source: https://context7.com/kylebarron/pydelatin/llms.txt Rescales mesh vertex positions from pixel coordinates to real-world geographic coordinates. ```APIDOC ## rescale_positions ### Description Rescales mesh vertex positions to geographic coordinates. ### Parameters - **vertices** (numpy.ndarray) - Required - Mesh vertices. - **bounds** (tuple) - Required - Geographic bounds [minx, miny, maxx, maxy]. - **flip_y** (bool) - Optional - Flip Y axis if image origin is top-left. ``` -------------------------------- ### Calculate Latitude Adjustment Factor for Web Mercator Source: https://context7.com/kylebarron/pydelatin/llms.txt The latitude_adjustment function calculates a factor to correct for map distortion in Web Mercator projections at different latitudes. This is useful for accurate geographic scaling. ```python from pydelatin.util import latitude_adjustment ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.