Farmsim Forensics: Real World Terrains (a.k.a. DEMs)

Kim Brandwijk
Farmsim Forensics
Published in
9 min readJan 7, 2021

Today we look at what many consider to be the holy grail of Farming Simulator map making: obtaining accurate real world terrain data, or in modders lingo ‘making a DEM’. I’ve made many of these for many different people, and over time, continued to improve and simplify the process. And while I have plans to create a set of more comprehensive and user-friendly tools, I’d like to share my current process with the community at this point, because the older tutorials and walkthroughs are either very complicated, outdated, or both.

Note: although this article is quite long, this is mainly because I go into every little step of the process in great detail, and provide a lot of background information.

The process to create a DEM from start to finish for most easily accessible sources normally takes less than 5 minutes though, once you’ve done it a couple of times.

A little background

Before we dive into the process, let’s have a quick look at what it is that we need. Farming Simulator uses a heightmap image to generate the terrain elevation. A heightmap is a greyscale image, and every pixel in the image represents the height of that point in the terrain.

The resolution of this image affects the level of detail in the terrain, and the bit-depth of this image affects the level of detail for the elevation. Very simply put, the more information we are able to put in this image, the more detailed the terrain will look. A 16-bit file is ideal, because you can store 65535 elevation levels in it, compared to only 255 levels in an 8-bit file.

By default, Farming Simulator uses a resolution of 2 meter per pixel. As we have seen in my previous article about map sizes, this setting (unitsPerPixel) is adjustable in GIANTS Editor. If you are unfamiliar with this setting, I recommend you to read up on it there.

The location

Now that we know what we need, we can take a look at the location. I’m going to assume that you have a location in mind, and you also have a size in mind for your map (for more information on the specifics on map sizes, check out my article on them!). There’s not too many restrictions here, except for two:

  • Not all places on Earth have high resolution elevation data available. While there is a global dataset with 30m per pixel accuracy, ideally we should be using more accurate sources for a better result.
  • The GIANTS engine supports a maximum elevation on your map of about 500 meters. Anything above that, and weird things start to happen (camera clipping). Keep this in mind if you have your eye on a particularly mountainous region.

For this article, we’ve settled on a nice 2x2 km area on the Colorado River outside of Grand Junction, CO.

For downloading and processing the DEM tiles later on, it’s good to make sure we have accurate coordinates for the bounding box (so the top left and bottom right coordinates). I usually start out with the top left coordinates from the map, in this case: 39°07'37.0"N 108°20'03.7"W, or in decimal notation (lon, lat): [-108.334368,39.126934]. Google maps will show you these coordinates in both formats when you click on a spot on the map.

To calculate the coordinates for the opposite corner, I use a little Python script that uses pyproj so make sure you install that first (pip install pyproj should work for most environments):

This will output: -108.311245, 39.108917

Finding elevation data

Now that we have picked our location, and retrieved the coordinates for its bounding box, we need to find the elevation data. Unfortunately, there’s no single method that works for every place on Earth. At least, not if we want to get the highest quality data that’s available. In this example, we use a location in the USA, but at the end of the article, I’ll describe the method for some other countries as well. It won’t be an extensive list, so if you don’t see your country in the list, and you know of a good DEM source, let me know in the comments and I will add it to the list.

For the USA, the best place to start is the USGS TNM Download website: https://viewer.nationalmap.gov/basic/#/

On this screen, first select ‘Elevation Products (3DEP)’ on the left, and click the ‘Show Availability’ and ‘Show Legend’ buttons. Next, click the little keyboard button on the top, and enter the coordinates from the previous step.

If you skipped ahead to this step, because you are still looking for a nice location, you can also just navigate around the map, or search for a place in the bottom right.

After locating our area on the map, it turns out we’re lucky, and the highest resolution data (1 meter DEM) is available. Select this subcategory on the left (this will filter the results on the next screen) and click ‘Search Products’.

It looks like we got lucky again. Our entire desired map area is covered by a single DEM tile. Go ahead and download that tile using the ‘Download TIF’ button. If you picked a location that needs two or more tiles, download all of them. If a one meter DEM is not available for your location, download the next best one (1/9 arc second is about 3.5 meter per pixel, 1/3 is about 10 meter pixel). If you try to open the files to view them, they will appear all white. Don’t worry, nothing’s wrong, the data is stored in a way that doesn’t translate well into visible colors. Think about these TIF files as large spreadsheets, where every pixel stores a lot of information about a little piece of the world.

Processing the DEM tiles

To recap, we picked a location, grabbed its coordinates, and downloaded one or more DEM tiles that cover our area. The last step is to crop these to the bouding box of our area, and convert them into the format that GIANTS expects. For all this, we use a single command line tool, called gdal. It’s an industry standard tool for working with geospatial data.

On Windows, the easiest way to get it installed properly is using Anaconda: https://anaconda.org/conda-forge/gdal. The website provides installation instructions. Either way, make sure to have it installed before continuing.

Stitching tiles together (optionally)

If you had to download more than one tile in the previous step, we will need to stitch these together first. From the Anaconda command prompt, in the folder where you downloaded the tiles, run:

> gdalwarp tile1.tif tile2.tif merged.tif

Reprojecting

Before we continue to crop our area of interest, there is one important step we need to take first. Different DEM sources use different coordinate projections. This is because each one of them picks the projection that projects their area of interest the best. For example, the ‘regular’ mercator projection causes lots of distortion the higher the latitude. However, Google uses the same projection everywhere for their satellite imagery (WGS 84). This means that if you don’t make sure your DEM uses that same projection, that the terrain you generate will not match the satellite imagery.

Different projections (image source: https://www.earthdatascience.org/courses/earth-analytics/spatial-data-r/reproject-vector-data/)

To reproject, we use the following command:

> gdalwarp -t_srs CRS:84 USGS_one_meter_x73y434_CO_MesaCo_QL2_UTM12_2016.tif projected.tif

Cropping the tile

Next up, we are going to crop our projected tile (or merged tiles) to the area we need:

> gdal_translate -projwin -108.334368 39.126934 -108.311245 39.108917 -projwin_srs CRS:84 projected.tif cropped.tif

This command tells gdal to take a window with the coordinates that we specify (top left, bottom right) and put them in a new file. Because different sources use different coordinate systems and projections, we also explicitly specify that these coordinates are CRS:84 coordinates.

Elevation levels

Next up, we need to figure out what the minimum and maximum elevation is in the tile. We need this information, because we need to tell GE what the heightScale of our DEM is (in order words, how many meters of elevation does going from completely black to completely white in our heightmap represent). For this, we use gdalinfo:

> gdalinfo -mm cropped.tifDriver: GTiff/GeoTIFF
Files: cropped.tif
Size is 2058, 1941
Coordinate System is:
GEOGCRS["WGS 84",
DATUM["World Geodetic System 1984",
ELLIPSOID["WGS 84",6378137,298.257223563,
LENGTHUNIT["metre",1]]],
PRIMEM["Greenwich",0,
ANGLEUNIT["degree",0.0174532925199433]],
CS[ellipsoidal,2],
AXIS["geodetic latitude (Lat)",north,
ORDER[1],
ANGLEUNIT["degree",0.0174532925199433]],
AXIS["geodetic longitude (Lon)",east,
ORDER[2],
ANGLEUNIT["degree",0.0174532925199433]],
ID["EPSG",4326]]
Origin = (730425.000000000000000,4334247.000000000000000)
Pixel Size = (1.000000000000000,-1.000000000000000)
Metadata:
AREA_OR_POINT=Area
Image Structure Metadata:
INTERLEAVE=BAND
Corner Coordinates:
Upper Left ( 730425.000, 4334247.000) (108d20' 3.76"W, 39d 7'36.98"N)
Lower Left ( 730425.000, 4332306.000) (108d20' 6.13"W, 39d 6'34.08"N)
Upper Right ( 732483.000, 4334247.000) (108d18'38.14"W, 39d 7'35.01"N)
Lower Right ( 732483.000, 4332306.000) (108d18'40.53"W, 39d 6'32.11"N)
Center ( 731454.000, 4333276.500) (108d19'22.14"W, 39d 7' 4.55"N)
Band 1 Block=2058x1 Type=Float32, ColorInterp=Gray
Description = Layer_1
Computed Min/Max=1430.570,1687.457
NoData Value=-3.4028234663852886e+38
Metadata:
LAYER_TYPE=athematic

This command outputs a lot of information, but the bits we’re interested in are highlighted above, the minimum and maximum elevation values.

Creating the heightmap

The final command that we will use will create the actual PNG image

> gdal_translate -of PNG -ot UInt16 -scale 1400 1700 0 65535 -a_srs CRS:84 -outsize 2049 2049 cropped.tif DEM.png

We’re telling gdal that we need a PNG image, with 16-bit depth. We are also specifying that we would like an elevation range of 1400 to 1700 meters to take up the entire range from black (0) to white (65535). We also specify the projection, and the resolution of the file (2049x2049).

Note that this command outputs the size of the source data while running. It will say something like ‘Input file size is 2041, 2006’. If the input size is much smaller than your desired output size, then you’ll get better results generating a smaller DEM image, and upscaling it in a graphics editor. Make sure you preserve the 16-bit file format when doing so!

And there you have it, the heightmap for our terrain. You can clearly spot the low (dark) river, and the higher (lighter) mountains on the left and right of it. Let’s load it up in GE and see what it looks like. Don’t forget to set the heightScale to whatever range you picked (in our case: 300), and unitPerPixel to match the resolution of your image.

Other countries

Canada

Canada offers an interactive map viewer for their high resolution DEMs (HRDEM): https://open.canada.ca/data/en/fgpv_vpgf/957782bf-847c-4644-a757-e383c0057995. It works quite intuitively. Zoom in to your area. Click the tile to download it.

Belgium (Flanders)

High resolution 1 meter DEM data is available from Geopoint: http://www.geopunt.be/catalogus/datasetfolder/f52b1a13-86bc-4b64-8256-88cc0d1a8735.

Netherlands

Very high resolution 50 cm (!) per pixel DEM data is available on PDOK (in Dutch): https://downloads.pdok.nl/ahn3-downloadpage/.

Global

If you can’t find any national data sources, the global SRTM 1 arc second dataset (30 meter) is available here: https://earthexplorer.usgs.gov/

If you have any questions, or topics you would like to see in a future article, feel free to leave a comment.

Enjoy modding, enjoy gaming, and stay tuned for new articles!

--

--