TouchTerrain_for_CAGEO

TouchTerrain (version 3.6)

TouchTerrain converts digital elevation data into digital model files (STL or OBJ) suitable for 3D printing. It comes as a standalone version and as a server version for a web application. To see the server version in action, go to http://touchterrain.org or http://touchterrain.geol.iastate.edu

TouchTerrain is developed by Chris Harding (Iowa State University) and Franek Hasiuk (Kansas Geological Survey). For questions email Geofablab AT gmail DOT com.

For more in-depth information:

Getting Started

TouchTerrain reads Digital Elevation model (DEM) data within a geographical extent (downloaded from Earth Engine or from a local raster file) and from it creates a 3D mesh model file suitable for 3D printing. Online data from EE is automatically UTM projected and adaptively downsampled. The 3D model (STL or OBJ format), possibly consisting of several files (tiles), is saved in a zip file along with a log file with details about the process steps.

For most users, the web app version will most likely meet their requirements. Iowa State University offers the web app here: http://touchterrain.org or http://touchterrain.geol.iastate.edu

Standalone mode

Standalone mode offers a different approach to processing than the web app. Standalone mode uses Python code, either TouchTerrain_standalone.py or a Jupyter notebook to define processing parameters in code and then processes a local DEM raster file or online DEM data from Earth Engine (google account required to authenticate). After processing the resulting zip file is stored locally. A few aspect of TouchTerrain are only exposed via the stand alone version. It also offers a way around around server processing quotas, that make it impossible to create some very large (> ~150 Mb) 3D models as all he processing is done locally (some Google Earth Engine imposed limitations still apply, see Appendix).

Although a pip setup.py file (and requirements.txt) are provided, note that it can be non-trivial to get all the required Python libraries to install locally, especially those that are wrappers around C/C++, such as GDAL. It may therefore be easier to run Touchterrain inside a docker container (see touchterrain_jupyter docker container) or to use a jupyter notebook on Colab or Binder (see below).

TouchTerrain_standalone.py

This defines the processing parameters either directly inside the file (parameters are basically values in a dictionary) of via a JSON file it reads in. An example of such a JSON config is *example_config.json- in the stuff folder. See Processing Parameters below for details. TouchTerrain_standalone.py has only one argument, the path to the JSON file, e.g. python TouchTerrain_standalone.py stuff/example_config.json would run the example configuration. Running it without an argument will create a default JSON file (same as the example) that you can then modify. TouchTerrain_standalone.py can be used in conjuction with shell scripts for batch processing (e.g. see https://github.com/ansonl/DEM2STL)

The recommended way to run the standalone version is to use our touchterrain_jupyter docker container.

To use touchterrain in standalone mode (i.e. not via a web server), either run TouchTerrain_standalone.py or TouchTerrain_standalone_jupyter_notebook.ipynb. Both sit in the project root folder and require that the touchterrain module has been installed.

The jupyter notebook version of standalone also

Jupyter Notebook version for standalone

For most users, espcially those new to Python, the preferred way to run the standalone version of TouchTerrain is via a jupyter notebook file. Inside the notebook, the same processing parameters described in the JSON config file are defined in Python (as a dictionary). The parameters are explained below for the JSON file version but the python syntax is very similar to JSON. After processing the DEM and saving the model(s) in a zip file. All notebooks offers a map interface (geemap) for digitizing the area of the model, either as box, circle or polygon.

We have created four versions of notebooks:

1) TouchTerrain_standalone_jupyter_notebook.ipynb is meant to be run locally or via a docker container and is meant for those familiar with Python. The setup part is now somewhat outdated but the notebook may still form a useful basis. It allow the preview of the model for k3d. 2) TouchTerrain_jupyter_for_starters.ipynb is a modification of 1) meant for Python beginners. It tries to walk a beginner through the process in much more detail by providing a template (workflow) for all major parameters. As such is may be unnecessarily verbose for non-beginners. It also can preview the model via k3d and is again meant to be run locally on via a docker container. 3) TouchTerrain_jupyter_for_starters_colab.ipynb is a modification of 2) specifically for running on colab (free but Google account required). To run it just click on this badge: Open In Colab and follow the instructions! With some caveats, this is by far the easiest and fastest way to process DEM data with TouchTerrain standalone! The free runtime environment has plenty CPU power and disk space and, as most of the required Python packages are already installed, installation (despite being a bit quirky) is usually done under a minute. Sadly, k3d cannot be run and so it has no model preview. 4) TouchTerrain_jupyter_for_starters_binder.ipynb is similar to 3) but tailored to run on Binder Binder Binder sets up a free docker container within a slick web interface (nice!) and uses JupyterLab. But, in my experience the installation phase is slower and less reliable than Colab. As lots of Python packages have to be installed (more than 750 Mb!), installation can take 10 - 15 minutes, with long paused w/o progress indication. Refreshing the browser sometimes helps but I’ve had cases where the installation simply stopped and never finished. In addition, a created instance seems to time out quite quickly, meaning that if your don’t use it right away after its lengthy installation, the instance will shut down, requiring a new installation.

EarthEngine_authentication_guide.md has some notes on how to authenticate with EarthEngine, which is required when processing their online DEM data (but not when only processing uploaded local DEM raster files!).

General Processing parameters

These parameters can be used in the JSON config file or in a python dictionary for hardingcoding them in the jupyter notebook or TouchTerrain_standalone.py. The JSON config file has the following format and default values:

{
    "DEM_name": "USGS/3DEP/10m",
    "bllat": 39.32205105794382,
    "bllon": -120.37497608519418,
    "trlat": 39.45763749030933,
    "trlon": -120.2002248034559,
    "importedDEM": null,
    "printres": 0.4,
    "ntilesx": 1,
    "ntilesy": 1,
    "tilewidth": 120,
    "basethick": 0.6,
    "zscale": 2.0,
    "fileformat": "STLb",
    "tile_centered": false,
    "zip_file_name": "myterrain",
    "CPU_cores_to_use": null,
    "max_cells_for_memory_only": 25000000,
    "no_bottom": false,
    "bottom_image": null,
    "ignore_leq": null,
    "lower_leq": null,
    "unprojected": false,
    "only": null,
    "importedGPX": [],
    "smooth_borders": true,
    "offset_masks_lower": null,
    "fill_holes": null,
    "poly_file": null,
    "min_elev": null,
    "tilewidth_scale": null,
    "clean_diags": false,
    "sqrt": false,
    "use_geo_coords": null
}

Note that for Python, None and True/False need to be different:

Python JSON
None null
True true
False false

GPX Path config

Note on using GPX files: this will simply extrude those pixels covered by a path away from the top surface, i.e. it will not insert proper 90 deg. “walls” for delineating them. To generate a “crisp” path, it may be advisable to use a much higher printres (e.g. 0.2 mm) which allows the extrusion to create steeper (but still non-90 deg.) walls that are more noticeable when 3D printed.

Offset Mask config

Unit tests (new in 3.5)

Server version

All server related files are in touchterrain/server

Running TouchTerrain_app.py starts a Flask server module, which will be run inside Apache. Contact us if you want to know about the dockerized Gunicorn version we run at ISU. The server creates a webpage, through which the user inputs the area selection and print parameters.

The server presents users with index.html (in templates), which can be styled to suit your needs, provided the various input dialogs and JavaScript remain. Starting with version 3, it is based on Bootstrap 4.

The config.py file inside the server folder contains server specific config settings:

The touchterrain/common directory contains files used by both, the standalone and server versions.

touchterrain/stuff contains, well, stuff, such as pdfs and example data files.

Appendix

Server version (web app)

The server version offers a Google Map interface to select the area and a simple GUI to specify the processing parameters. To run your own server version, an Earth Engine account is needed. It provides a setup.py file that will build and install a module called touchterrain and also install all prerequisites. We recommend using pip for the installation: run ‘pip install .’ in the same folder as the setup.py file.

More specific details on how to set up and run your own server are beyond the scope of this ReadMe. If you are interested in the nitty-gritty details on how Iowa State IT deploys the server, please contact us.

Getting large geotiffs from Google Earth Engine

// Example of exporting a raster from EE to Google Drive (Jan. 2021)

// You will need the corner coords, which you can get from the Area Selection Box display
// on the web app and the EPSG code for whatever projection you want to use. If you want
// to use a UTM zon, look at the log file from the web app.
// You also should know the source resolution of your DEM so you can set the scale parameter
// of the export to it.


// 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.
// https://developers.google.com/earth-engine/guides/exporting
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
});

// When this code is run, an export task will be created in the Code Editor Tasks tab. 
// Click the Run button next to the task to start it. 
// The image will be created in your Drive account with the specified fileFormat.