User:Ff5722/How to create and host tilesets from GeoTIFF images

From OpenStreetMap Wiki
Jump to navigation Jump to search

Mapbox Studio

If you have only a few tiles to use, this is the most convenient method. You can also overlay your different tilesets and choose a background layer for empty areas. The downside is that it requires uploading a 500 MB tile to Mapbox, which may take a while depending on your internet connection. The free plan has a limited bandwidth and storage size as well (maximum of about 10 Sentinel-2 tilesets).


  • Very easy to use without experience
  • Easy to share imagery with others
  • Add customizable background imagery styles


  • Storage and bandwidth limitations for free version
  • Need to upload to Mapbox
  • You depend on the customization options offered by Mapbox


  1. Sign up for Mapbox Studio here [1]
  2. Log in and go to tilesets > New tileset > Upload > upload your geoTIFF
  3. Then go to Styles > new style > pick any ('satellite', 'empty', or 'black' work best).
  4. Go to your new style, then go to > edit > new layer > under 'source' select tileset > select your uploaded tileset. I recommend to give it a descriptive name
  5. Go back to your style, on the right click Share & use, go to the 'use' tab, and select 'third party'. For JOSM, copy the WMTS URL. For iD, use the CARTO URL, but you need to change one thing, which is remove the '@2x' from your URL. For example:{z}/{x}/{y}@2x?access_token=pk.eyJ1IjoiaGluZGJhZXIiL

Thanks to 7thgrade for guiding me through the processing method

Tileserver-php method


  • Fast to use
  • Relatively easy


  • Cannot expand coverage of the same layer after rendering
  • Have to render in advance
  • Need to setup and run web server first


This only needs to be done once.

  1. If you haven't done so yet, install QGIS from
  2. Install a local web server such as WampServer or XAMPP
  3. Follow the instructions here to set up TileServer-php to be hosted on your local server (so, place the tileserver folder in the 'www' or 'htdocs' folder of Wamp or XAMPP, for example C:\wamp64\www\tileserver\tileserver.php.
  4. Start the Apache server and go to the tileserver page (http://localhost/tileserver).
  5. Right click the WMTS link on the right side and copy the URL. In JOSM add this URL as a WMTS server (for example http://localhost/tileserver/wmts).
  6. Open QGIS and go to Plugins > Manage and install plugins. In the Plugins window, go to Settings and enable 'Show also experimental plugins'. Click reload repository. If you use QGIS3, install the Qtiles3 plugin by alexbruy. If you use QGIS2, install the Qtiles plugin by Nextgis.

*In some cases it might be required to redirect your localhost domain to a virtual domain. [2] This is because editors may not accept background imagery hosted at localhost. Add a line examplename.domain to your hosts file.


  1. Render the image in QGIS, see: User:Ff5722/Using_Sentinel-2_imagery#Using_QGIS
  2. Go to Plugins > QTiles and open the QTiles window. Refer to the table below to see which settings to use.
  3. Rename the JSON file to metadata.json and place it in the same folder as the tiles. (like \tileserver\London\metadata.json)
  4. Start the local web server
  5. In JOSM, select your custom WMTS server and start tracing.
  6. If the tileset doesn't appear in the JOSM 'Select WMTS layer' window, you need to delete the WMTS cache. To do so, go to JOSM advanced preferences (in expert mode), and enter 'wmts' in the search field. Delete the value for your tileserver domain. Alternatively, go to C:\Users\%USER%\AppData\Local\JOSM\cache and delete the cache for your tileserver. If you don't want to do this again, I recommend to search for the settings key 'wmts.capabilities.cache.max_age' and set its value to '1'.
Option Recommended setting
Tileset name Name of area in tileset, cannot contain non-Latin script
Output Directory: Should be your tileserver top level folder e.g. 'C:/wamp64/www/tileserver'
Extent Choose 'layer extent' in most cases. Choose 'full extent' if you want to render multiple images as one tileset, for example connecting satellite imagery.
Zoom Minimum zoom: 0
Maximum zoom: 15 (or higher if using high-res images)
Tile width
Tile height
Background transparency
Leave at default. You can choose to render tiles in JPG if storage is a concern. JPG tiles will show an annoying error message in JOSM though.
Make lines less jagged Off, unnecessary for imagery
Use TMS convention Leave at default (off)
Render tiles outside extents I recommend turning this on. Renders whitespace around your data, makes it easy to find on the map, but will overlap if you use other layers.
Write .json metadata Turn on (important)
Write overview image file Leave at default (off)

Geoserver method

This is the go-to method if you want to use coverage of a large area consisting of many tiles.


  • Can easily expand coverage
  • Everything in one layer


  • Not very intuitive
  • Higher requirements for CPU and RAM (don't try this on a low power laptop)


  1. Download Geoserver and extract the folder to desired location (e.g. /Documents/Geoserver)
  2. Run /bin/startup.bat
  3. Open localhost:8080/geoserver/web/
  4. Log in with username admin, password geoserver
  5. Save the GeoTIFF imagery you want to use in any folder
  6. Create a new workspace
  7. Create a new store with type 'Raster Data Sources' > 'ImageMosaic'
  8. Select the folder where you stored imagery
  9. Create layer
  10. Click the Geoserver logo to go home and you can copy the WMS/WMTS/TMS endpoints.
  11. To refresh tiles in the same folder, follow the instructions here: [3]
    curl -v -u admin:geoserver -XPOST -H "Content-type: text/plain" -d "file:///path/to/the/mosaic/folder" "http://localhost:8080/geoserver/rest/workspaces/WORKSPACE NAME/coveragestores/COVERAGE NAME/external.imagemosaic"
    Simply run the above code in a command/terminal. For convenience, it can be useful to save the code in a batch or bash file. The output will be something like this:
    *   Trying ::1...
    * TCP_NODELAY set
    * Connected to localhost (::1) port 8080 (#0)
    * Server auth using Basic with user 'admin'
    > POST /geoserver/rest/workspaces/main/coveragestores/sentinel/external.imagemosaic HTTP/1.1
    > Host: localhost:8080
    > Authorization: Basic YWRtaW46Z2Vvc2VydmVy
    > User-Agent: curl/7.55.1
    > Accept: */*
    > Content-type: text/plain
    > Content-Length: 30
    * upload completely sent off: 30 out of 30 bytes
    < HTTP/1.1 202 Accepted
    < X-Frame-Options: SAMEORIGIN
    < Content-Length: 0
    < Server: Jetty(9.4.18.v20190429)
    * Connection #0 to host localhost left intact
  12. Sometimes the code won't work, the other option is then to delete the store, delete the config files in the data directory and remake the store and layer with the same name