TouchTerrain

repository·main·Indexed 43 days ago

https://github.com/chharding/touchterrain_for_cageo

A tool for converting digital elevation model (DEM) data into 3D printable STL or OBJ files. It features a web-based interface and a standalone Python-based workflow for local processing, supporting data from Google Earth Engine or local raster files. Key capabilities include automatic UTM projection, adaptive downsampling, GPX path extrusion, and offset masks for specific regions.

Tokens
9.3K
Snippets
27
Records
37
Agent score
50%

What's inside TouchTerrain

  1. Overview of TouchTerrain

    main

    TouchTerrain is a tool designed to convert digital elevation model (DEM) data into 3D printable digital model files in STL or OBJ formats. It processes geographical extents—either downloaded from Google Earth Engine or provided via local raster files—to generate 3D mesh models.

    Key features include:

    • Automatic UTM projection for online Earth Engine data.
    • Adaptive downsampling of data.
    • Output as a ZIP file containing the 3D model (which may consist of multiple tiles) and a log file detailing the processing steps.

    TouchTerrain is available in two modes:

    1. Web Application: Hosted at http://touchterrain.org or http://touchterrain.geol.iastate.edu.
    2. Standalone Mode: For local processing via Python scripts or Jupyter Notebooks.
  2. Install TouchTerrain via pip

    main

    To use TouchTerrain in standalone mode, you must install the touchterrain package and its dependencies. If you are working from the source directory (where setup.py is located), you can install it using pip.

    Note: Installing gdal via pip can be difficult as it requires a C++ compiler. On Windows, you may need to find a pre-compiled .whl file or use conda via conda-forge.

    Optional Modules:

    • pip install geemap: Enables interactive in-cell maps for digitizing print areas.
    • pip install k3d: Enables 3D STL file previews in the notebook.
    # From the directory containing setup.py
    pip install .
    
    # Optional modules
    pip install geemap
    pip install k3d
  3. Export large GeoTIFFs from Google Earth Engine to Google Drive

    main

    To bypass the 10-megapixel download limit in Google Earth Engine (EE) and obtain high-resolution GeoTIFFs for use with TouchTerrain's standalone mode, you can export the data directly to Google Drive using an EE script.

    Workflow:

    1. Identify DEM Details: Find the DEM source (e.g., JAXA/ALOS/AW3D30/V2_2) and the elevation band name (e.g., AVE_DSM) via the EE catalog.
    2. Get Coordinates: Use the TouchTerrain web app to find the top-right and bottom-left latitude/longitude coordinates of your desired area.
    3. Determine Projection: Find the appropriate EPSG code (e.g., for a UTM zone) by checking the log files in the TouchTerrain web app.
    4. Run EE Script: Copy the provided JavaScript example into the Google Earth Engine Code Editor, update the dataset, elevation band, geometry coordinates, scale, and crs, then run the task.
    5. Download from Drive: Once the task completes in the EE 'Tasks' tab, open the file in Google Drive and download the .tif file.
    6. Process in TouchTerrain: Run TouchTerrain in standalone mode and set the importDEM parameter to your downloaded file. To use the original resolution, set printres to -1.
    // Example of exporting a raster from EE to Google Drive (Jan. 2021)
    
    // Set DEM source  
    var dataset = ee.Image('JAXA/ALOS/AW3D30/V2_2');
    var elevation = dataset.select('AVE_DSM');
    print(elevation); // print some metadata into console
    
    // make a spectral color scheme for elevation data layer
    var elevationVis = { 
      min: 0,
      max: 4000,
      palette: ['0000ff', '00ffff', 'ffff00', 'ff0000', 'ffffff'],
      opacity: 0.5,
    };
    Map.addLayer(elevation, elevationVis, 'Elevation');
    
    // define area to export and show as box layer
    var trlat = 46.78374215384358
    var trlon = 8.071201291153262
    var bllat = 46.63448889213306
    var bllon = 7.574375128591488
    var geometry = ee.Geometry.Rectangle([ trlon, trlat, bllon, bllat ]);
    Map.addLayer(geometry, {'opacity': 0.5}, 'box');  
    
    // Fly to center of Box
    Map.setCenter(
      trlon - ((trlon - bllon) / 2), 
      trlat - ((trlat - bllat) / 2), 
      8 // zoomlevel
    );
    
    // Export the image, specifying scale and region.
    Export.image.toDrive({
      image: elevation,
      description: 'EE_to_Google_Drive_example', // name of geotiff (.tif will be added)
      fileFormat: 'GeoTIFF',
      scale: 30, // resolution in meters
      maxPixels: 1e12, // overwrites the default of 1e08
      region: geometry,
      crs: "EPSG:32632" // EPSG code for the UTM zone or whatever coordinate system you want to use
    });
  4. Digitize a print area using geemap

    main

    If you have geemap installed, you can interactively define a custom shape (rectangle, circle, or polygon) instead of using the bounding box coordinates.

    1. Run the geemap cell to display a hillshaded map.
    2. Use the drawing tools on the left of the map to define your shape.
    3. Run the cell that extracts the draw_last_feature to convert the shape into a GeoJSON polygon.
    4. The resulting args["polygon"] will override the bllat/trlat bounding box during processing.
    # After drawing a shape in the geemap interface:
    polyft = Map.draw_last_feature
    from geojson import Polygon
    coords = polyft.getInfo()['geometry']['coordinates']
    poly = Polygon(coords)
    args["polygon"] = poly
  5. Run TouchTerrain in Standalone Mode

    main

    Standalone mode allows you to process DEM (Digital Elevation Model) data locally using Python, bypassing web server quotas and enabling the creation of very large 3D models (> 150 MB). You can define processing parameters via a JSON configuration file or directly in a Python dictionary.

    Methods of Execution

    1. TouchTerrain_standalone.py: A Python script that accepts a path to a JSON configuration file as its only argument. If no argument is provided, it generates a default JSON file.
    2. Jupyter Notebooks: Preferred for beginners. These notebooks allow you to define parameters as Python dictionaries and include a geemap interface for digitizing areas (box, circle, or polygon).

    Because installing dependencies like GDAL can be difficult, it is highly recommended to use the touchterrain_jupyter docker container or run the notebooks on Google Colab or Binder.

    # Run with a specific JSON configuration
    python TouchTerrain_standalone.py stuff/example_config.json
    
    # Run without arguments to generate a default config file
    python TouchTerrain_standalone.py
  6. Choose a Jupyter Notebook version for Standalone mode

    main

    TouchTerrain provides four distinct Jupyter notebook versions depending on your environment and expertise:

    1. TouchTerrain_standalone_jupyter_notebook.ipynb: For local or Docker use; intended for users familiar with Python. Supports k3d for model preview.
    2. TouchTerrain_jupyter_for_starters.ipynb: A more verbose version of the above, designed to walk beginners through the workflow. Supports k3d preview.
    3. TouchTerrain_jupyter_for_starters_colab.ipynb: The easiest and fastest way. Optimized for Google Colab. It handles most installations automatically, though k3d model preview is unavailable.
    4. TouchTerrain_jupyter_for_starters_binder.ipynb: Tailored for Binder. Note that installation can be slow (10-15 minutes) and instances may time out.
  7. Configure TouchTerrain processing settings via the `args` dictionary

    main

    All processing parameters for TouchTerrain are controlled through a dictionary named args. You set values by assigning them to specific keys.

    Common settings include:

    • importedDEM: Path to a local GeoTIFF file or None to use online DEMs.
    • DEM_name: The name of the online Earth Engine DEM (e.g., "USGS/3DEP/10m" for US or "JAXA/ALOS/AW3D30/V2_2" for worldwide).
    • tilewidth: The physical width of the printed model in mm.
    • ntilesx / ntilesy: Number of tiles to divide the area into (set to 1 for a single STL).
    • basethick: Thickness of the base in mm.
    • printres: Print resolution in mm (typically 0.4).
    • zscale: Elevation exaggeration factor. Use a positive number (e.g., 2.0) or a negative number to specify a target height in mm (e.g., -20 for 20mm tall).
    # Example configuration
    args["importedDEM"] = None
    args["DEM_name"] = "USGS/3DEP/10m"
    args["tilewidth"] = 150
    args["ntilesx"] = 1
    args["ntilesy"] = 1
    args["basethick"] = 1
    args["printres"] = 0.4
    args["zscale"] = -20
    args["zip_file_name"] = "myterrain"
  8. Define the print area (Polygon)

    main

    The print area can be defined in three ways:

    1. Coordinates: Set args["bllat"], args["bllon"] (Bottom-Left) and args["trlat"], args["trlon"] (Top-Right).
    2. Interactive (geemap): Use the geemap interactive map to draw a Rectangle, Polygon, or Circle. The last drawn feature is captured using Map.draw_last_feature and converted to a geojson.Polygon assigned to args["polygon"].
    3. KML File: Provide a path to a .kml file (not .kmz) via args["poly_file"].
    # Method A: Coordinates
    args["bllat"] = 39.322
    args["bllon"] = -120.374
    args["trlat"] = 39.457
    args["trlon"] = -120.2
    
    # Method B: Interactive (after drawing on Map)
    polyft = Map.draw_last_feature
    args["polygon"] = Polygon(polyft.getInfo()['geometry']['coordinates'])
    
    # Method C: KML
    args["poly_file"] = "stuff/polygon_example.kml"
  9. Configure TouchTerrain processing parameters

    main

    TouchTerrain is controlled via a Python dictionary (args). The parameters are divided into DEM selection, 3D print settings, and expert settings.

    Key Parameter Groups:

    1. DEM/Area Selection

    • importedDEM: Path to a local GeoTIFF file. If None, the system uses online sources.
    • DEM_name: The Google Earth Engine DEM source (e.g., "USGS/3DEP/10m").
    • bllat, bllon, trlat, trlon: Coordinates for the bottom-left and top-right corners of the area.
    • polygon: A GeoJSON polygon (if using geemap to digitize an area).

    2. 3D Print Parameters

    • tilewidth: Width of each tile in mm.
    • printres: Horizontal resolution of the printer in mm (e.g., 0.4).
    • ntilesx, ntilesy: Number of tiles in the X and Y directions.
    • basethick: Thickness of the printed base in mm.
    • zscale: Vertical elevation scaling.
    • fileformat: Output format ("STLb" for binary STL, "STLa" for ASCII STL, "obj" for wavefront OBJ, or "GeoTiff" for raw raster).
    • zip_file_name: Base name for the resulting zip file.

    3. Expert Settings

    • CPU_cores_to_use: 0 for all cores, None for single-core.
    • no_bottom: If True, omits bottom triangles.
    • no_normal: If True, skips normal calculation (faster, but some viewers may struggle).
    • projection: An EPSG integer for UTM projection (defaults to closest UTM zone).
    args = {
        "importedDEM": None,
        "DEM_name": "USGS/3DEP/10m",
        "bllat": 44.50185267072875,
        "bllon": -108.25427910156247,
        "trlat": 44.69741706507476,
        "trlon": -107.97962089843747,
        "tilewidth": 120,
        "printres": 0.4,
        "ntilesx": 1,
        "ntilesy": 1,
        "basethick": 0.6,
        "zscale": 2,
        "fileformat": "STLb",
        "zip_file_name": "myterrain",
        "tile_centered": False,
        "CPU_cores_to_use": 0,
        "max_cells_for_memory_only": 5000**2,
        "no_bottom": False,
        "no_normal": True,
        "bottom_image": None,
        "ignore_leq": None,
        "lower_leq": None,
        "unprojected": False,
        "projection": None,
        "only": None,
        "importedGPX": [],
    }
  10. Configure the TouchTerrain server

    main

    Server-specific settings are located in touchterrain/server/config.py. Key configuration options include:

    • NUM_CORES: Controls CPU usage. 0 uses all available cores; 1 uses only one core (useful for debugging).
    • MAX_CELLS: Threshold for memory management. If a raster exceeds this number of cells, the server uses temporary files instead of memory during later processing stages to reduce memory intensity.
    • MAX_CELLS_PERMITED: A heuristic threshold to prevent processing jobs that are too large and might cause server thrashing. If the cell count exceeds this, processing will not start. It is recommended to adjust this based on your system's virtual memory (swapspace) usage.
    • GOOGLE_ANALYTICS_TRACKING_ID: The ID for Google Analytics in index.html. Set to UA-XXXXXXXX to disable tracking.
    • PROJ_DIR: A workaround for OSgeo/GDAL projection issues. If using the GPX path option in standalone mode, set this to the path of the folder containing the proj.db database. This sets the PROD environment variable.