### Install TouchTerrain module Source: https://github.com/chharding/touchterrain_for_cageo/blob/main/TouchTerrain_jupyter_starters_colab.ipynb Installs the TouchTerrain module directly from its GitHub repository. ```python # installing the touchterrain module from github !pip install git+https://github.com/ChHarding/TouchTerrain_for_CAGEO.git ``` -------------------------------- ### Expert Settings Examples Source: https://github.com/chharding/touchterrain_for_cageo/blob/main/TouchTerrain_jupyter_starters_colab.ipynb Provides examples of advanced configuration options. These settings allow for fine-tuning of the terrain generation process, such as ignoring or modifying low-lying raster cells, or changing the map projection. ```python # remove all raster cells that are equal or lower than 0 #args["ignore_leq"] = 0 ``` ```python # lower raster cells that are equal or lower than 0 by 3 m #args["lower_leq"] = [0, 3] #[0, 3] is a list with 2 values ``` ```python # set projection to ESPG code 3857 (Web mercator) #args["projection"] = 3857 ``` ```python # Switch off border smoothing for models with polygon borders (True by default) #args["smooth_borders"] = False ``` -------------------------------- ### Install geemap package Source: https://github.com/chharding/touchterrain_for_cageo/blob/main/TouchTerrain_jupyter_starters_colab.ipynb Installs the geemap Python package quietly. Remove '-q' to see detailed output. ```python # The following pip commands all have -q (quiet) at the end which hides (most of) their output. Remove the -q if you want to see the details !pip install geemap -q ``` -------------------------------- ### Download example data files Source: https://github.com/chharding/touchterrain_for_cageo/blob/main/TouchTerrain_jupyter_starters_colab.ipynb Downloads example data files including a GeoTIFF DEM, a GPX path, and a KML polygon using curl. These files will appear in the Colab file browser. ```python # Download some example files, these will eventually show up in the Files tab on the left # More on how to use these later # Example local geotiff DEM file !curl -LJO https://github.com/ChHarding/TouchTerrain_for_CAGEO/raw/master/stuff/geotiff_example.tif # Example of a gpx path (trail !curl -LJO https://github.com/ChHarding/TouchTerrain_for_CAGEO/raw/master/stuff/gpx-test/example_path.gpx # Example of kml polygon file !curl -LJO https://github.com/ChHarding/TouchTerrain_for_CAGEO/raw/master/stuff/polygon_example.kml ``` -------------------------------- ### Install K3D extension in Colab Source: https://github.com/chharding/touchterrain_for_cageo/blob/main/TouchTerrain_jupyter_starters_colab.ipynb Configures the environment to support K3D widgets by installing extensions and enabling the custom widget manager. ```bash !jupyter nbextension install --py --user k3d !jupyter nbextension enable --py --user k3d %load_ext google.colab.data_table ``` -------------------------------- ### Install TouchTerrain via pip Source: https://github.com/chharding/touchterrain_for_cageo/blob/main/TouchTerrain_standalone_jupyter_notebook.ipynb Use this snippet to install the touchterrain module and its dependencies directly from a Jupyter cell. ```python #import sys #!{sys.executable} -m pip install . ``` -------------------------------- ### Commented and Uncommented Code Example Source: https://github.com/chharding/touchterrain_for_cageo/blob/main/TouchTerrain_jupyter_starters_binder.ipynb Illustrates proper commenting and uncommenting of Python code. Lines starting with '#' are ignored by the interpreter. ```python print(123) #print(123) print(123) ``` ```python _#print(123) _print(123) ``` -------------------------------- ### List All Argument Settings Source: https://github.com/chharding/touchterrain_for_cageo/blob/main/TouchTerrain_jupyter_starters_binder.ipynb Iterate through and print all available settings within the 'args' dictionary to review current configurations. ```python for name in args: print(name, args[name]) ``` -------------------------------- ### Scale Tile Width (tilewidth_scale) Source: https://github.com/chharding/touchterrain_for_cageo/blob/main/ReadMe.md A scale factor to override the calculated tile width. For example, a factor of 10000 divides the real-world width by 10000 and multiplies by 1000 to get the new tile width in mm. Note that the final x/y scale may differ slightly due to projection adjustments. ```python tilewidth_scale: (default: `None`). Uses this scale factor to calculate and override the tile width. Ex: a factor of 10000 will divide the real-world width of the area by 10000 and multiply that value by 1000 to arrive at a new tilewidth (in mm). Note that the final x/y scale (reported in the log file) may be slightly different due to some projection adjustments. __(New in 3.6.1)__ ``` -------------------------------- ### Initialize Google Earth Engine Source: https://github.com/chharding/touchterrain_for_cageo/blob/main/TouchTerrain_standalone_jupyter_notebook.ipynb Import the Earth Engine library and authenticate the session. The authentication call should only be executed once to generate the credentials file. ```python import ee # earthengine-api should have been installed via pip earlier #ee.Authenticate() ``` -------------------------------- ### Configure GPX Path Parameters Source: https://github.com/chharding/touchterrain_for_cageo/blob/main/TouchTerrain_jupyter_starters_colab.ipynb Sets the height, point density, and thickness for imported GPX path lines. ```python args["gpxPathHeight"] = 5 args["gpxPixelsBetweenPoints"] = 20 args["gpxPathThickness"] = 2 ``` -------------------------------- ### Initialize StlViewer and Progress Tracking Source: https://github.com/chharding/touchterrain_for_cageo/blob/main/touchterrain/server/templates/preview.html Configures the STL viewer with progress callbacks and model data. Requires the StlViewer library to be loaded in the environment. ```javascript function load_prog(load_status, load_session){ let loaded = 0; let total = 0; Object.keys(load_status).forEach(function(model_id) { if (load_status[model_id].load_session == load_session){ loaded += load_status[model_id].loaded; total += load_status[model_id].total; } }); document.getElementById("pbtotal").value = loaded/total; } var stl_viewer = new StlViewer( document.getElementById("stl_cont"), { loading_progress_callback: load_prog, all_loaded_callback: function(){ document.getElementById("pbtotal").style.display='none'; document.getElementById("working").innerHTML = "Model Previewer: Zoom with mouse wheel, rotate with left mouse drag, pan with right mouse drag"; }, models: {{ models|safe }}, load_three_files: "/static/js/", center_models: {{ center_models }} } ); ``` -------------------------------- ### Initialize TouchTerrain Module Source: https://github.com/chharding/touchterrain_for_cageo/blob/main/TouchTerrain_standalone_jupyter_notebook.ipynb Imports necessary packages and the TouchTerrainEarthEngine class to prepare for processing. ```python # import packages import os, sys from pprint import pprint # The touchterrain module should have been installed via pip earlier # This will also run ee.Initialize() and should show: EE init() worked with .config/earthengine/credentials # If you don't plan on using online DEM data and thus didn't authenticate earlier, you will get a warning, which you can ignore. from touchterrain.common import TouchTerrainEarthEngine as TouchTerrain ``` -------------------------------- ### Authenticate Earth Engine Source: https://github.com/chharding/touchterrain_for_cageo/blob/main/TouchTerrain_jupyter_starters_binder.ipynb Authenticate your Earth Engine account to consume DEM data from Google. This line should be uncommented for the initial setup and commented out afterwards to avoid re-authentication. ```python #ee.Authenticate() # authenticate your earth engine to consume DEM data from Google ``` -------------------------------- ### Initialize polygon mask processing Source: https://context7.com/chharding/touchterrain_for_cageo/llms.txt Sets up the environment to use KML files for defining terrain boundaries. ```python from touchterrain.common import TouchTerrainEarthEngine as TouchTerrain ``` -------------------------------- ### Initialize Interactive Map Source: https://github.com/chharding/touchterrain_for_cageo/blob/main/TouchTerrain_jupyter_starters_binder.ipynb Create a geemap instance centered on the defined area and overlay a hillshade layer for visual reference. ```python # Create an interactive map and center on default area center_lat = (args["trlat"] + args["bllat"]) / 2 center_lon = (args["trlon"] + args["bllon"]) / 2 Map = geemap.Map(center=(center_lat, center_lon), zoom=7) # make a hillshade layer and add it to map dem = ee.Image(args["DEM_name"]) # DEM source hs = ee.Terrain.hillshade(dem, 315, 35) # sun azimuth and angle vis_params = {'min': 0,'max': 255,} # greyscale color ramp Map.addLayer(hs, vis_params, 'hillshade', shown=True, opacity=0.5) # semi transparent overlay ``` -------------------------------- ### Run TouchTerrain Standalone Source: https://github.com/chharding/touchterrain_for_cageo/blob/main/ReadMe.md Execute the standalone script using a JSON configuration file to define processing parameters. ```bash python TouchTerrain_standalone.py stuff/example_config.json ``` -------------------------------- ### Set Print Parameters Source: https://github.com/chharding/touchterrain_for_cageo/blob/main/TouchTerrain_jupyter_for_starters.ipynb Configures physical dimensions, tiling, base thickness, and resolution for the 3D model. ```python args["tilewidth"] = 120 # in mm ``` ```python args["ntilesx"] = 1 # number of tiles in x args["ntilesy"] = 1 # number of tiles in y ``` ```python args["basethick"] = 0.6 # in mm ``` ```python args["printres"] = 0.4 # in mm ``` -------------------------------- ### Initialize Interactive Geemap Source: https://github.com/chharding/touchterrain_for_cageo/blob/main/TouchTerrain_jupyter_starters_colab.ipynb Create an interactive map with a hillshade layer to visualize and select the terrain area. ```python # Create an interactive map and center on default area center_lat = (args["trlat"] + args["bllat"]) / 2 center_lon = (args["trlon"] + args["bllon"]) / 2 Map = geemap.Map(center=(center_lat, center_lon), zoom=7) # make a hillshade layer and add it to map dem = ee.Image(args["DEM_name"]) # DEM source hs = ee.Terrain.hillshade(dem, 315, 35) # sun azimuth and angle vis_params = {'min': 0,'max': 255,} # greyscale color ramp Map.addLayer(hs, vis_params, 'hillshade', shown=True, opacity=0.5) # semi transparent overlay # if GPX files were used, add them to the map if args["importedGPX"] != None and len(args["importedGPX"]) > 0: gpx = ee.Feature(convert_to_GeoJSON(args["importedGPX"])) Map.addLayer(gpx, {"color":'00FFFF', "strokeWidth":"1"}, "GPX line", opacity=0.9) Map # makes the interactive map show up as output of this cell ``` -------------------------------- ### Configure KML File Path Source: https://github.com/chharding/touchterrain_for_cageo/blob/main/TouchTerrain_jupyter_starters_colab.ipynb Verify the current working directory and configure the path for a KML polygon file. ```python # If you uploaded a kml file, check that it shows up here: print("Current folder", getcwd(), " contains: ", listdir()) # Comment out either this line: args["poly_file"] = None # Don't use a kml file # or both of these lines: #args["poly_file"] = "polygon_example.kml" # location of kml file to use #args["polygon"] = None # ensures that any gee polygon you might have digitized is not used ``` -------------------------------- ### Standalone Script with JSON Configuration Source: https://context7.com/chharding/touchterrain_for_cageo/llms.txt Run TouchTerrain from the command line using a JSON configuration file for batch processing and automation. The script reads the JSON and calls `get_zipped_tiles`. ```json { "DEM_name": "USGS/3DEP/10m", "trlat": 44.69741706507476, "trlon": -107.97962089843747, "bllat": 44.50185267072875, "bllon": -108.25427910156247, "printres": 0.4, "ntilesx": 1, "ntilesy": 1, "tilewidth": 100, "basethick": 1.0, "zscale": 1.5, "fileformat": "STLb", "zip_file_name": "my_terrain", "tile_centered": false, "no_bottom": false, "ignore_leq": null, "CPU_cores_to_use": 0, "max_cells_for_memory_only": 1000000, "smooth_borders": true } ``` ```python # Run from command line: # python TouchTerrain_standalone.py config.json # The script reads the JSON and calls get_zipped_tiles(): import json import sys from touchterrain.common import TouchTerrainEarthEngine as TouchTerrain with open(sys.argv[1], 'r') as f: args = json.load(f) totalsize, zipfile = TouchTerrain.get_zipped_tiles(**args) print(f"Created {zipfile} ({totalsize:.2f} Mb)") ``` -------------------------------- ### Configure DEM Source Source: https://github.com/chharding/touchterrain_for_cageo/blob/main/TouchTerrain_jupyter_starters_binder.ipynb Select the online elevation data source by setting the DEM_name parameter. Use USGS/3DEP/10m for the lower 48 US states or JAXA/ALOS/AW3D30/V2_2 for global coverage. ```python # Comment out one of the following two lines args["DEM_name"] = "USGS/3DEP/10m" # area is within the lower 48 (US) #args["DEM_name"] = "JAXA/ALOS/AW3D30/V2_2" # area is outside the US (worldwide) ``` -------------------------------- ### Configure TouchTerrain Settings Source: https://github.com/chharding/touchterrain_for_cageo/blob/main/TouchTerrain_standalone_jupyter_notebook.ipynb Defines the dictionary of parameters for DEM source selection, 3D printing specifications, and expert settings. ```python args = { # DEM/Area to print # A: use local DEM raster (geotiff) #"importedDEM": "stuff/pyramid.tif", # path to the geotif in relation to where this notebook sits # B: use area and a DEM online source via EarthEngine "importedDEM": None, "DEM_name": "USGS/3DEP/10m", # DEM source # the following defines the area, but you can also define it by hand (see digitizing) "bllat": 44.50185267072875, # bottom left corner lat "bllon": -108.25427910156247, # bottom left corner long "trlat": 44.69741706507476, # top right corner lat "trlon": -107.97962089843747, # top right corner long # 3D print parameters "tilewidth": 120, # width of each tile in mm, (tile height will be auto calculated) "printres": 0.4, # resolution (horizontal) of 3D printer in mm, should be your NOZZLE size or just a bit less! # Using something like 0.01 will NOT print out a super detailed version as you slicer will remove # super fine details anyway! You'll just wait a long time and get a super large STL file! "ntilesx": 1, # number of tiles in x "ntilesy": 1, # number of tiles in y "basethick": 0.6, # thickness (in mm) of printed base "zscale": 2, # elevation (vertical) scaling "fileformat": "STLb", # format of 3D model files: "obj" wavefront obj (ascii), # "STLa" ascii STL or "STLb" binary STL. # To export just the (untiled) raster (no mesh), use "GeoTiff" "zip_file_name": "myterrain", # base name of zipfile, .zip will be added # Expert settings "tile_centered": False, # True-> all tiles are centered around 0/0, False, all tiles "fit together" "CPU_cores_to_use" : 0, # 0: use all available cores, None: don't use multiprocessing (single core only) # multi-core will be much faster for more than 1 tile "max_cells_for_memory_only" : 5000^2, # if number of raster cells is bigger than this, use temp_files instead of memory. # set this very high to force use of memory and lower it if you run out of memory "no_bottom": False, # omit bottom triangles? Most slicers still work and it makes smaller files "no_normal": True, # Don't calculate normals for triangles. This is significantly faster but some 3D model viewers may need them. "bottom_image": None, # "stuff/TouchTerrain_bottom_example.png", # 1 band greyscale image used for bottom relief "ignore_leq": None, # set all values <= this to NaN so they don't print "lower_leq": None, # e.g. [0.0, 2.0] values <= 0.0 will be lowered by 2mm in the final model "unprojected": False, # don't project to UTM (for EE rasters only) "projection": None, # None means use the closest UTM zone. Can be a EPSG number (int!) instead but not all work. "only" : None, # if not None: list with x and y tile index (1 based) of the only tile to process # e.g. [1,1] will only process the tile in upper left corner, [2,1] the tile right to it, etc. "importedGPX": [], # list of gpx path file(s) to be use (optional: see next cell) } ######################################################## # if we want to work on a local raster, get the full pathname to it if args["importedDEM"] != None: from os.path import abspath args["importedDEM"]= abspath(args["importedDEM"]) print("reading in local DEM:", args["importedDEM"]) print("settings stored, ready to process") ``` -------------------------------- ### Configure GPX Path Files Source: https://github.com/chharding/touchterrain_for_cageo/blob/main/TouchTerrain_jupyter_starters_binder.ipynb Define GPX file paths and styling parameters for terrain draping. Set importedGPX to None to disable GPX imports. ```python args["gpxPathHeight"] = 5 args["gpxPixelsBetweenPoints"] = 20 args["gpxPathThickness"] = 2 # Comment out one of the following two lines #args["importedGPX"] = ["stuff/gpx-test/DLRTnML.gpx", "stuff/gpx-test/DonnerToFrog.gpx", "stuff/gpx-test/CinTwistToFrog.gpx"] # list of GPX files args["importedGPX"] = None # Do not use any GPX path files ``` -------------------------------- ### Configure Tile Centering (tile_centered) Source: https://github.com/chharding/touchterrain_for_cageo/blob/main/ReadMe.md Determines how tiles are positioned in a 3D viewer. `false` offsets tiles to fit together seamlessly. `true` centers each tile around 0/0, causing overlap but making each tile ready for separate printing. ```python tile_centered: (default: `false`) - `false`: All tiles are offset so they all "fit together" when they all are loaded into a 3D viewer, such as Meshlab or Meshmixer. - `true`: each tile is centered around 0/0. This means they will all overlap in a 3D viewer but each tile is already centered on the buildplate, ready to be printed separately. ``` -------------------------------- ### Import Required Python Packages Source: https://github.com/chharding/touchterrain_for_cageo/blob/main/TouchTerrain_jupyter_starters_colab.ipynb Imports the necessary libraries for TouchTerrain, including Earth Engine and geemap, and initializes default arguments. ```python # import packages import os.path from glob import glob from random import randint from shutil import rmtree import ee from geojson import Polygon import geemap from touchterrain.common import TouchTerrainEarthEngine as TouchTerrain from touchterrain.common.TouchTerrainGPX import * from os import getcwd, listdir args = TouchTerrain.initial_args # default args ``` -------------------------------- ### Configure GPX File Path Source: https://github.com/chharding/touchterrain_for_cageo/blob/main/TouchTerrain_jupyter_starters_colab.ipynb Set the path for imported GPX files or disable the feature by setting the argument to None. ```python # Comment out one of the following two lines #args["importedGPX"] = ["example_path.gpx"] # list of one GPX file, for more, separate them with commas (see above) args["importedGPX"] = None # Do not use any GPX path files ``` -------------------------------- ### Configure GPX Path Draping Source: https://github.com/chharding/touchterrain_for_cageo/blob/main/TouchTerrain_standalone_jupyter_notebook.ipynb Configure settings for draping one or more GPX files over a terrain model. Adjust path height, point density, and thickness. Uncomment the final line to apply these settings. ```python # Note: you must uncomment the last line in this cell to actually use these gpx settings! from touchterrain.common.TouchTerrainGPX import * gpx_args = { # Area for using the example GPX test files "bllat": 39.32205105794382, # bottom left corner lat "bllon": -120.37497608519418, # bottom left corner long "trlat": 39.45763749030933, # top right corner lat "trlon": -120.2002248034559, # top right corner long "importedGPX": # gpx example files. ["stuff/gpx-test/DLRTnML.gpx", "stuff/gpx-test/DonnerToFrog.gpx", "stuff/gpx-test/CinTwistToFrog.gpx", "stuff/gpx-test/sagehen.gpx", "stuff/gpx-test/dd-to-prosser.gpx", "stuff/gpx-test/alder-creek-to-crabtree-canyon.gpx", "stuff/gpx-test/ugly-pop-without-solvang.gpx", ], "gpxPathHeight": 10, # Currently we plot the GPX path by simply adjusting the # raster elevation at the specified lat/lon, # therefore this is in meters. Negative numbers are ok # and put a dent in the mdoel "gpxPixelsBetweenPoints" : 20, # GPX Files haves a lot of points. A higher #number will create more space between lines drawn # on the model and can have the effect of making the paths look a bit cleaner "gpxPathThickness" : 2, # Stack paralell lines on either side of primary line # to create thickness. A setting of 1 probably looks the best } # uncomment the next line if you want to use gpx_args! #args = {**args, **gpx_args}; print(args) # merge gpx_args into args, ** unrolls dicts ``` -------------------------------- ### Include Stl Viewer in HTML Source: https://github.com/chharding/touchterrain_for_cageo/blob/main/touchterrain/server/static/js/readme.txt Include the Stl Viewer script and initialize it within your HTML body. Ensure the target div exists and the model filename is correctly specified. ```html
``` -------------------------------- ### Import Python Packages Source: https://github.com/chharding/touchterrain_for_cageo/blob/main/TouchTerrain_jupyter_starters_binder.ipynb Imports necessary Python packages for TouchTerrain and Earth Engine. Ensure Earth Engine is authorized before running. ```python # import packages import os.path from glob import glob import k3d from random import randint from shutil import rmtree import zipfile from geojson import Polygon import geemap from touchterrain.common import TouchTerrainEarthEngine as TouchTerrain from touchterrain.common.TouchTerrainGPX import * args = TouchTerrain.initial_args # default args ``` -------------------------------- ### Authenticate and Initialize Earth Engine Source: https://github.com/chharding/touchterrain_for_cageo/blob/main/TouchTerrain_jupyter_starters_colab.ipynb Initializes the Earth Engine API using a project ID, falling back to authentication if the initial attempt fails. ```python # Authenticates and initializes Earth Engine import ee project = "demoproject-418722" # replace with your project ID try: ee.Initialize(project=project) except Exception as e: # if the initialization didn't work, web authenticate first ee.Authenticate() ee.Initialize(project=project) if ee.data._credentials: print("Earth Engine is initialized.") else: print("Earth Engine is not initialized.") ``` -------------------------------- ### Display Interactive Map with Geemap Source: https://github.com/chharding/touchterrain_for_cageo/blob/main/TouchTerrain_standalone_jupyter_notebook.ipynb Initializes an interactive geemap for visualizing terrain and GPX data. Requires the `geemap` module. The map displays a hillshaded DEM and optionally GPX layers. ```python # Geemap import geemap # Create an interactive map and center on default area center_lat = (args["trlat"] + args["bllat"]) / 2 center_lon = (args["trlon"] + args["bllon"]) / 2 Map = geemap.Map(center=(center_lat, center_lon), zoom=7) # make a hillshade layer and add it to map dem = ee.Image(args["DEM_name"]) # DEM source hs = ee.Terrain.hillshade(dem, 315, 35) # sun azimuth and angle vis_params = {'min': 0,'max': 255,} # greyscale color ramp Map.addLayer(hs, vis_params, 'hillshade', shown=True, opacity=0.5) # semi transparent overlay # if GPX files were used, add them to the map if args["importedGPX"] != None and len(args["importedGPX"]) > 0: gpx = ee.Feature(convert_to_GeoJSON(args["importedGPX"])) Map.addLayer(gpx, {"color":'00FFFF', "strokeWidth":"1"}, "GPX line", opacity=0.9) # show the currently defined bounding box # I'm commenting this out b/c I think geemap users don't really need to see that # given that they probably use geemap to interactively select that box. But, if you do # want to see it for some reason, uncomment the block below #rect = ee.Geometry.Rectangle( # args["bllon"], args["bllat"], args["trlon"], args["trlat"]) #rect_feature = ee.Feature(rect) #Map.addLayer(rect_feature, {"color": 'FF0000'}, "bounding box", opacity=0.5) Map # makes the interactive map show up as output of this cell ``` -------------------------------- ### GPX Path Configuration Source: https://github.com/chharding/touchterrain_for_cageo/blob/main/ReadMe.md Configure how GPX files are imported and rendered as paths on the terrain model. ```APIDOC ## GPX Path Configuration ### Description Configure parameters for importing and plotting GPX files onto the generated terrain model. These settings control the height, density, and thickness of the plotted paths. ### Parameters #### Request Body Parameters - **importedGPX** (list of strings | null) - Optional - A list of file paths to GPX files to be plotted on the model. Defaults to null (no GPX files imported). - **gpxPathHeight** (integer) - Optional - The height in meters to adjust the raster elevation along the GPX path. Negative values create a depression. Defaults to 40. - **gpxPixelsBetweenPoints** (integer) - Optional - Controls the spacing between points along the GPX path in pixels. Higher values result in fewer lines and a cleaner look, at the expense of precision. Defaults to 20. - **gpxPathThickness** (integer) - Optional - The number of parallel lines to draw on either side of the primary path line to create thickness. Defaults to 5. ### Request Example ```json { "importedGPX": ["path/to/your/file.gpx"], "gpxPathHeight": 50, "gpxPixelsBetweenPoints": 30, "gpxPathThickness": 7 } ``` ### Response #### Success Response (200) - **message** (string) - Confirmation of GPX path configuration. #### Response Example ```json { "message": "GPX path configuration applied." } ``` ``` -------------------------------- ### Set Output Zip File Name (zip_file_name) Source: https://github.com/chharding/touchterrain_for_cageo/blob/main/ReadMe.md Defines the prefix for the output filename when using stand-alone mode. The '.zip' extension is automatically appended. ```python zip_file_name: default: "terrain" Prefix of the output filename for stand-alone. (.zip is added) ``` -------------------------------- ### Programmatic Terrain Processing Source: https://context7.com/chharding/touchterrain_for_cageo/llms.txt Demonstrates how to use the `get_zipped_tiles` function for programmatic terrain generation with different DEM resolutions. ```APIDOC ## Programmatic Terrain Processing ### Description This section shows how to use the `TouchTerrain.get_zipped_tiles` function to generate terrain models with different Digital Elevation Model (DEM) sources and resolutions. ### Method `TouchTerrain.get_zipped_tiles(**args)` ### Parameters #### Request Body (args dictionary) - **DEM_name** (string) - Required - The name of the DEM source (e.g., "USGS/3DEP/10m", "USGS/GMTED2010"). - **zip_file_name** (string) - Required - The base name for the output zip file. - **base_args** (dict) - Required - A dictionary containing base arguments for processing (e.g., output format, tiling parameters). ### Request Example ```python # Assuming base_args is defined elsewhere # Example 1: High resolution for US locations args = {**base_args, "DEM_name": "USGS/3DEP/10m", "zip_file_name": "grand_canyon_10m"} TouchTerrain.get_zipped_tiles(**args) # Example 2: Lower resolution for comparison args = {**base_args, "DEM_name": "USGS/GMTED2010", "zip_file_name": "grand_canyon_230m"} TouchTerrain.get_zipped_tiles(**args) ``` ``` -------------------------------- ### TouchTerrain Configuration Options Source: https://github.com/chharding/touchterrain_for_cageo/blob/main/ReadMe.md This section details the various configuration options available for the TouchTerrain API, allowing for fine-grained control over terrain mesh generation. ```APIDOC ## TouchTerrain Configuration Options This document outlines the parameters available for configuring the TouchTerrain API to generate custom 3D terrain models. ### Data Input and Format - **`__GeoTiff__`**: Stores the raster used for mesh files as a GeoTIFF within the zip file. This is a faster option for downloading larger areas. It saves a projected raster at print resolution, ignoring other settings like z-scale. - **`importedDEM`** (default: `null`): If `null`, a GeoTIFF is fetched from Earth Engine. If set to a filename, this file is used as the DEM. In this case, `DEM_name`, `bllat`, `bllon`, `trlat`, and `trlon` are ignored, but other parameters are still used. GDAL raster file formats are supported. Set `printres` to -1 to use the file's intrinsic resolution. Non-georeferenced rasters are assumed to have a cell size of 1. Undefined cells (e.g., -9999999) are omitted, allowing for organic boundaries. ### Hole Filling and Elevation Filtering - **`fill_holes`** (default: `null`): Specifies the number of iterations and neighbor threshold to fill holes. `-1` iterations continue until no more holes are found. Defaults to 7 neighbors in a 3x3 footprint with elevation > 0 to fill a hole with the average of the footprint. *e.g. [10, 7]* - **`ignore_leq`** (default: `null`): Ignores cells with elevation less than or equal to the specified value (e.g., 0.0). Useful for omitting offshore cells. Experiment with values like 0.5 for sharper coastlines. - **`lower_leq`** (default: `null`): An alternative to `ignore_leq`. Given a list `[threshold, offset]`, cells less than or equal to `threshold` are lowered by `offset` (in mm). This helps emphasize coastlines and is unaffected by z-scale. ### Mesh Generation and Output Control - **`max_cells_for_memory_only`** (default: `1000000`): If the number of raster cells exceeds this value, temporary files are used, which is slower but less memory-intensive. Lowering this value can help if your machine runs out of memory. - **`min_elev`** (default: `null`): The minimum elevation to start the model height at after `basethick`. If `null`, the minimum elevation found in the DEM is used. - **`no_bottom`** (default: `false`): Omits bottom triangles, storing only the top surface and walls. This creates smaller files. For simple cases, the bottom mesh is two triangles; this setting is mainly useful for polygon outlines. - **`no_normals`** (default: `true`): Does not calculate normals for STL files, setting them to 0,0,0 for faster processing. Set to `false` if calculated normals are required in the STL file. ### Tiling and Sub-region Processing - **`ntilesx`**: Divides the x-axis evenly among the specified number of tiles. Useful for printing areas too large for the printer's bed. - **`ntilesy`**: See `ntilesx`. - **`only`** (default: `null`): If given a list `[x,y]`, processes only that tile index (e.g., `[1,1]` for the upper-left tile). This allows downloading large models by processing one tile at a time. Combining tiles from separate downloads can create a single model. Ensure `tile_centered` is `false` for seamless fitting in viewers. ``` -------------------------------- ### Configure KML Outline Source: https://github.com/chharding/touchterrain_for_cageo/blob/main/TouchTerrain_jupyter_for_starters.ipynb Sets the path to a KML file for defining the area boundary. ```python # Comment out either this line: args["poly_file"] = None # Don't use a kml file # or both of these lines: #args["poly_file"] = "stuff/polygon_example.kml" # location of kml file to use #args["polygon"] = None # ensure that any gee polygon you might have digitized is not used ``` -------------------------------- ### Define TouchTerrain configuration in JSON Source: https://github.com/chharding/touchterrain_for_cageo/blob/main/ReadMe.md The standard JSON format for configuring processing parameters. Note that Python users should map null to None, true to True, and false to False. ```json { "CPU_cores_to_use": 0, "DEM_name": "USGS/3DEP/10m", "basethick": 1, "bllat": 44.50185267072875, "bllon": -108.25427910156247, "bottom_image": null, "clean_diags": false, "fileformat": "STLb", "fill_holes": null, "ignore_leq": null, "lower_leq": null, "importedDEM": null, "max_cells_for_memory_only": 1000000, "min_elev": null, "no_bottom": false, "no_normals": true, "ntilesx": 1, "ntilesy": 1, "only": null, "printres": 0.5, "tile_centered": false, "tilewidth": 80, "trlat": 44.69741706507476, "trlon": -107.97962089843747, "unprojected": false, "zip_file_name": "terrain", "zscale": 1.0 } ``` -------------------------------- ### Utility Functions Source: https://context7.com/chharding/touchterrain_for_cageo/llms.txt Documentation for helper functions used in raster processing, visualization, and file operations. ```APIDOC ## Utility Functions ### Description Helper functions for raster processing, visualization, and file operations used throughout the TouchTerrain pipeline. ### Functions #### `fillHoles(raster, num_iters=-1, num_neighbors=7)` - **Description**: Fills holes (represented by negative values) in elevation data using an iterative averaging method. - **Parameters**: - **raster** (numpy.ndarray) - Required - The input elevation data. - **num_iters** (integer) - Optional - Number of iterations for filling. -1 means until no more holes are found. - **num_neighbors** (integer) - Optional - Number of neighbors to consider for averaging. - **Returns**: numpy.ndarray - The raster with holes filled. #### `clean_up_diags(raster_with_nans)` - **Description**: Cleans diagonal patterns (e.g., `[[1, NaN], [NaN, 1]]`) in the raster that can cause non-manifold geometry in 3D models. - **Parameters**: - **raster_with_nans** (numpy.ndarray) - Required - The input raster, potentially containing NaN values. - **Returns**: numpy.ndarray - The cleaned raster. #### `dilate_array(raster, source_raster=None)` - **Description**: Dilates the array to fill NaN boundaries, creating smoother transitions at undefined areas. Can use values from a source raster if provided. - **Parameters**: - **raster** (numpy.ndarray) - Required - The input raster to dilate. - **source_raster** (numpy.ndarray) - Optional - A source raster whose values are used for dilation. - **Returns**: numpy.ndarray - The dilated raster. #### `save_tile_as_image(raster, filename_prefix)` - **Description**: Saves a raster mask as an image file for debugging purposes. - **Parameters**: - **raster** (numpy.ndarray) - Required - The raster data to save. - **filename_prefix** (string) - Required - The prefix for the output image file (e.g., "tile_preview" will create "tile_preview.png"). #### `k3d_render_to_html(stl_files, output_folder, buffer=False)` - **Description**: Creates an interactive K3D HTML preview from a list of STL files. - **Parameters**: - **stl_files** (list of strings) - Required - A list of paths to STL files. - **output_folder** (string) - Required - The folder where the HTML file will be saved. - **buffer** (boolean) - Optional - Whether to use a buffer for rendering. - **Returns**: string - The path to the generated HTML file. ### Request Example (fillHoles) ```python import numpy as np from touchterrain.common.utils import fillHoles raster = np.array([ [10, 10, 10, 10], [10, -1, -1, 10], # -1 represents holes (elevation < 0) [10, 10, 10, 10], ]) filled = fillHoles(raster, num_iters=-1, num_neighbors=7) # Result: holes filled with average of surrounding cells ``` ### Request Example (clean_up_diags) ```python import numpy as np from touchterrain.common.utils import clean_up_diags raster_with_nans = np.array([ [1, np.nan, 1], [np.nan, 1, np.nan], [1, np.nan, 1], ]) cleaned = clean_up_diags(raster_with_nans) ``` ### Request Example (dilate_array) ```python import numpy as np from touchterrain.common.utils import dilate_array raster_with_nans = np.array([ [1, np.nan, 1], [np.nan, 1, np.nan], [1, np.nan, 1], ]) dilated = dilate_array(raster_with_nans) # Uses 3x3 nanmean # dilated = dilate_array(raster_with_nans, source_raster) # Uses source values ``` ### Request Example (save_tile_as_image) ```python from touchterrain.common.utils import save_tile_as_image raster = np.array([[1, 2], [3, 4]]) save_tile_as_image(raster, "tile_preview") # Creates tile_preview.png ``` ### Request Example (k3d_render_to_html) ```python from touchterrain.common.utils import k3d_render_to_html stl_files = ["tile_1_1.stl", "tile_1_2.stl"] html_path = k3d_render_to_html(stl_files, "output_folder", buffer=False) # Creates output_folder/k3d_plot.html with interactive 3D view ``` ``` -------------------------------- ### Connect to Google Drive (alternative) Source: https://github.com/chharding/touchterrain_for_cageo/blob/main/TouchTerrain_jupyter_starters_colab.ipynb This cell provides an alternative way to connect your Google Drive, making it visible in the file tab. It's useful for accessing or saving notebook edits and data. ```python # If you want to connect this notebook to your google drive, run this cell # You should see your google drive folder as drive/MyDrive in the File tab on the left from google.colab import drive drive.mount('/content/drive') ``` -------------------------------- ### Visualize STL Files with k3d Source: https://github.com/chharding/touchterrain_for_cageo/blob/main/TouchTerrain_standalone_jupyter_notebook.ipynb Loads STL files from the extracted folder and displays them in a 3D plot using the k3d library. ```python import k3d from glob import glob # get all stl files (tiles) in that folder mesh_files = glob(folder + os.sep + "*.STL") plot = k3d.plot() # Add all tiles with a random color from random import randint for m in mesh_files: col = (randint(0,255) << 16) + (randint(0,255) << 8) + randint(0,255) # random rgb color as hex print("adding to viewer:", m, hex(col)) buf = open(m, 'rb').read() plot += k3d.stl(buf, color=col) plot.display() ``` -------------------------------- ### Test Export via cURL Source: https://context7.com/chharding/touchterrain_for_cageo/llms.txt Simulate a POST request to the /export endpoint to trigger terrain processing and download generation. ```bash # Example curl request to test export: # curl -X POST http://localhost:5000/export \ # -F "DEM_name=USGS/3DEP/10m" \ # -F "trlat=44.7" -F "trlon=-107.9" \ # -F "bllat=44.5" -F "bllon=-108.2" \ # -F "printres=0.4" -F "tilewidth=100" \ # -F "basethick=1" -F "zscale=1.0" \ # -F "fileformat=STLb" -F "ntilesx=1" -F "ntilesy=1" ``` -------------------------------- ### Set DEM Source (Local GeoTIFF or Online) Source: https://github.com/chharding/touchterrain_for_cageo/blob/main/TouchTerrain_jupyter_starters_binder.ipynb Configures the DEM source for TouchTerrain. Set 'importedDEM' to a local GeoTIFF file path or None to use online DEMs. Ensure the GeoTIFF is uploaded via the File Manager if using a local file. ```python # Comment out one of following two lines: #args["importedDEM"] = "stuff/pyramid.tif" # path of local geotiff file to use args["importedDEM"] = None # no file used, use online DEM rasters instead # convert into an absolute path for later if args["importedDEM"] != None: args["importedDEM"]= os.path.abspath(args["importedDEM"]) print("importedDEM", args["importedDEM"]) ``` -------------------------------- ### Configure KML File for Polygon Outline Source: https://github.com/chharding/touchterrain_for_cageo/blob/main/TouchTerrain_jupyter_starters_binder.ipynb Sets the path to a KML file for defining the terrain model's outline. Comment out to disable KML usage and rely on digitized polygons or other methods. Ensure the KML file is uploaded to the project directory. ```python # Comment out either this line: args["poly_file"] = None # Don't use a kml file # or both of these lines: #args["poly_file"] = "stuff/polygon_example.kml" # location of kml file to use #args["polygon"] = None # ensures that any gee polygon you might have digitized is not used ``` -------------------------------- ### Mask Terrain with Local KML File Source: https://context7.com/chharding/touchterrain_for_cageo/llms.txt Use a local KML file to define the polygon boundary for terrain generation. Ensure the KML file path is correctly specified. ```python args = { "DEM_name": "JAXA/ALOS/AW3D30/V3_2", # 30m global DEM "trlat": 46.8, "trlon": 8.1, "bllat": 46.6, "bllon": 7.5, "poly_file": "my_boundary.kml", # Local KML file path "printres": 0.4, "tilewidth": 120, "basethick": 1.0, "zscale": 1.5, "fileformat": "STLb", "zip_file_name": "swiss_alps_masked", } totalsize, zipfile = TouchTerrain.get_zipped_tiles(**args) ``` -------------------------------- ### Add Bottom Relief Image Source: https://context7.com/chharding/touchterrain_for_cageo/llms.txt Incorporate a grayscale image to the bottom of the 3D model for decorative relief. Ensure `basethick` is greater than 0.5mm and `no_bottom` is `False`. ```python from touchterrain.common import TouchTerrainEarthEngine as TouchTerrain args = { "DEM_name": "USGS/3DEP/10m", "trlat": 40.8, "trlon": -111.7, "bllat": 40.5, "bllon": -112.0, "printres": 0.4, "tilewidth": 100, "basethick": 2.0, # Must be > 0.5mm for bottom image "zscale": 1.5, "fileformat": "STLb", "zip_file_name": "terrain_with_logo", # Bottom relief image (8-bit grayscale) "bottom_image": "my_logo.png", # Black = high relief, white = flat "no_bottom": False, # Must be False to use bottom_image } totalsize, zipfile = TouchTerrain.get_zipped_tiles(**args) ``` -------------------------------- ### Import Earth Engine Module Source: https://github.com/chharding/touchterrain_for_cageo/blob/main/TouchTerrain_jupyter_starters_binder.ipynb Import the Earth Engine API module. This is a prerequisite for using Google Earth Engine data. ```python import ee # import module for earthengine-api ```