factor: Switch to Web Mercator coordinates
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
Convert LAS lidar files to .mound binary format for Three.js rendering.
|
||||
|
||||
Usage:
|
||||
python las_to_mound.py input.las output.mound
|
||||
python las2mound.py input.las output.mound
|
||||
|
||||
.mound Binary Format Specification
|
||||
==================================
|
||||
@@ -15,16 +15,18 @@ Header (64 bytes):
|
||||
4 4 uint32 Version number (currently 1)
|
||||
8 4 uint32 Point count (number of vertices)
|
||||
12 4 uint32 Triangle count (number of triangles)
|
||||
16 4 float32 Min X coordinate
|
||||
20 4 float32 Min Y coordinate
|
||||
24 4 float32 Min Z coordinate
|
||||
28 4 float32 Max X coordinate
|
||||
32 4 float32 Max Y coordinate
|
||||
36 4 float32 Max Z coordinate
|
||||
16 4 float32 Min X coordinate (Web Mercator meters)
|
||||
20 4 float32 Min Y coordinate (Web Mercator meters)
|
||||
24 4 float32 Min Z coordinate (elevation in meters)
|
||||
28 4 float32 Max X coordinate (Web Mercator meters)
|
||||
32 4 float32 Max Y coordinate (Web Mercator meters)
|
||||
36 4 float32 Max Z coordinate (elevation in meters)
|
||||
40 24 bytes Reserved (padding to 64 bytes)
|
||||
|
||||
Vertex Data (point_count * 12 bytes):
|
||||
Series of vertices in XYZ float32 triplets.
|
||||
X, Y are in Web Mercator meters (EPSG:3857)
|
||||
Z is elevation in meters
|
||||
Total size: point_count * 3 * 4 bytes
|
||||
|
||||
Index Data (triangle_count * 12 bytes):
|
||||
@@ -38,6 +40,10 @@ Example layout for 100 points and 50 triangles:
|
||||
Bytes 1264-1863: Index data (50 * 12)
|
||||
Total file size: 1864 bytes
|
||||
|
||||
Coordinate System:
|
||||
Input: Ohio State Plane North (EPSG:3734) in US Survey Feet
|
||||
Output: Web Mercator (EPSG:3857) in meters
|
||||
This ensures compatibility with MapLibre GL JS and web mapping standards.
|
||||
"""
|
||||
|
||||
import sys
|
||||
@@ -64,24 +70,26 @@ except ImportError:
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def transform_to_latlon(x, y, z):
|
||||
"""Transform Ohio State Plane coordinates to lat/lon."""
|
||||
print("Transforming coordinates to lat/lon...")
|
||||
def transform_to_webmercator(x, y, z):
|
||||
"""Transform Ohio State Plane coordinates to Web Mercator (EPSG:3857)."""
|
||||
print("Transforming coordinates to Web Mercator...")
|
||||
|
||||
# Ohio State Plane South (EPSG:3735) in US Survey Feet to WGS84 (EPSG:4326)
|
||||
# Note: Ohio has two zones - North (3734) and South (3735)
|
||||
# Ohio State Plane North (EPSG:3734) in US Survey Feet to Web Mercator (EPSG:3857) in meters
|
||||
# Newark is in the North zone
|
||||
transformer = Transformer.from_crs("EPSG:3734", "EPSG:4326", always_xy=True)
|
||||
transformer = Transformer.from_crs("EPSG:3734", "EPSG:3857", always_xy=True)
|
||||
|
||||
# Transform x,y (easting, northing) to lon, lat
|
||||
lon, lat = transformer.transform(x, y)
|
||||
# Transform x,y (easting, northing) to Web Mercator meters
|
||||
merc_x, merc_y = transformer.transform(x, y)
|
||||
|
||||
# Convert elevation from US Survey Feet to meters
|
||||
z_meters = z * 0.3048006096012192
|
||||
|
||||
print(f"Transformed to lat/lon bounds: lon[{lon.min():.6f}, {lon.max():.6f}] lat[{lat.min():.6f}, {lat.max():.6f}]")
|
||||
print(f"Transformed to Web Mercator bounds:")
|
||||
print(f" X (meters): [{merc_x.min():.2f}, {merc_x.max():.2f}] (span: {merc_x.max() - merc_x.min():.2f}m)")
|
||||
print(f" Y (meters): [{merc_y.min():.2f}, {merc_y.max():.2f}] (span: {merc_y.max() - merc_y.min():.2f}m)")
|
||||
print(f" Z (meters): [{z_meters.min():.2f}, {z_meters.max():.2f}] (span: {z_meters.max() - z_meters.min():.2f}m)")
|
||||
|
||||
return lon, lat, z_meters
|
||||
return merc_x, merc_y, z_meters
|
||||
|
||||
|
||||
def read_las(filepath):
|
||||
@@ -164,7 +172,7 @@ def write_mound(filepath, x, y, z, indices):
|
||||
|
||||
def main():
|
||||
if len(sys.argv) != 3:
|
||||
print("Usage: python las_to_mound.py input.las output.mound")
|
||||
print("Usage: python las2mound.py input.las output.mound")
|
||||
sys.exit(1)
|
||||
|
||||
input_file = sys.argv[1]
|
||||
@@ -177,14 +185,14 @@ def main():
|
||||
# Read LAS
|
||||
x, y, z = read_las(input_file)
|
||||
|
||||
# Transform to lat/lon
|
||||
lon, lat, z_meters = transform_to_latlon(x, y, z)
|
||||
# Transform to Web Mercator
|
||||
merc_x, merc_y, z_meters = transform_to_webmercator(x, y, z)
|
||||
|
||||
# Triangulate (using lon/lat as x/y)
|
||||
indices = triangulate_points(lon, lat, z_meters)
|
||||
# Triangulate (using Web Mercator coordinates)
|
||||
indices = triangulate_points(merc_x, merc_y, z_meters)
|
||||
|
||||
# Write output (lon as x, lat as y, elevation as z)
|
||||
write_mound(output_file, lon, lat, z_meters, indices)
|
||||
# Write output (Web Mercator X/Y in meters, elevation in meters)
|
||||
write_mound(output_file, merc_x, merc_y, z_meters, indices)
|
||||
|
||||
print("Done!")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user