Install
Helm block.
- name: tileserver
namespace: kosmos-data
createNamespace: true
wait: true
chart: ../../tileserver/tileserver
skipDeps: true
labels:
app: tileserver
values:
- ../../tileserver/values.yaml
- ingress:
hosts:
- host: tileserver.{{ .StateValues.domain }}
paths:
- path: /
pathType: Prefix
tls:
- hosts:
- tileserver.{{ .StateValues.domain }}
secretName: tileserver-tls
Tileserver starts with default Zurich sample tiles.
Use custom tiles​
As said above, default deployment only includes a Zurich sample map. In order to use your desired maps, you must follow theses steps :
Create an Anonymous Bucket​
Due to their large size of .pmtiles files cannot be mounted as ConfigMap and would also "pollute" git repositories. They must therefore be stored in a specific S3 bucket.
This bucket should contain the whole Tileserver's configuration, including data/, icons/, sprites/, styles/ folders as well as the configuration file config.json.
Anonymous buckets allow non authenticated users to access files in read only mode.
- Go to S3 console and log in as admin.
- On the left sidebar click on Buckets under Administrator.
- On the right upper corner click on
Create Bucket. - Choose a name like
tileserver-publicthen validate. This will bring you back to the list of existing buckets. - Click on the newly created bucket.
- Click on
Anonymous. - Click on
Add Access Rule. - You can choose a prefix, if you want to give access to the whole bucket, enter
/. Make sure that Access is set toreadonly. - Click on
Save. - You will see the rule.
- Navigate to the bucket browser to drop your files.
Since we will be serving these files directly via HTTP, make sure to update the paths in your style.json files to add the url to them.
Convert then Import your .pmtiles into S3​
Before being able to access tiles, you will need to convert your mbtiles to pmtiles then
push your tiles to S3 via GUI and make your bucket anonymous.
mbtiles is a serialized sqlite database and so very inefficient for serving over the network.
This is why we will convert them to a more appropriate format; pmtiles.
To do so we need to download the pmtiles standalone binary for conversion. Download the official binary
Uncompress the downloaded archive then run the following command for compression:
chmod +x pmtiles
./pmtiles convert mytiles.mbtiles mytiles.pmtiles
If you need to change the temporary dir location you can use:
chmod +x pmtiles
./pmtiles convert --tmpdir=/path/to/custom/tmpdir mytiles.mbtiles mytiles.pmtiles
Finally, simply upload them under the data/ folder.
Make the S3 API ingress URL available inside the cluster​
To make your s3 api ingress url available inside the cluster, add the following bloc (if missing) in the rke2-coredns-rke2-coredns Configmap from the kube-system namespace :
s3-api.[PH.DOMAIN]:53 {
errors
health {
lameduck 5s
}
ready
rewrite name s3-api.[PH.DOMAIN] rke2-ingress-nginx-controller.kube-system.svc.cluster.local
kubernetes cluster.local cluster.local in-addr.arpa ip6.arpa {
pods insecure
fallthrough in-addr.arpa ip6.arpa
ttl 30
}
cache 30
reload
loadbalance
}
Replace the placeholder [PH.DOMAIN] with your current domain.
Define your configuration file (config.json)​
The config.json file contain three main sections:
options: Every configuration possible for Tileserver itself. In our case it defines paths for the different resource types.styles: Declares which styles will be effectively applied and available for users.- The keys used are considered unique identifier for your styles and used for mapping between raw tiles and styles. (eg:
basic-preview)
- The keys used are considered unique identifier for your styles and used for mapping between raw tiles and styles. (eg:
data: Declare the raw tiles data Declares maps and their associated.pmtilesfile.- The keys used are considered unique identifier for your raw tiles and used for mapping between raw tiles and styles. (eg:
v3)
- The keys used are considered unique identifier for your raw tiles and used for mapping between raw tiles and styles. (eg:
Both Styles and tiles can be served by S3 (and should be when size increase) and should use a URL using the following format : https://s3-api.[PH.DOMAIN]/[PH_BUCKET]/[PH_PATH_IN_BUCKET].
Use the external URLs when trying to access the S3-API, as some call will be made from your browser.
Here is an example using remote tiles and style for the Zurich map :
{
"options": {
"paths": {
"root": "/usr/src/app/node_modules/tileserver-gl-styles",
"fonts": "fonts",
"styles": "styles",
"pmtiles": "/data"
}
},
"serveAllFonts": true,
"allowRemoteMarkerIcons": true,
"styles": {
"basic-preview": {
"style": "https://s3-api.[PH.DOMAIN]/tileserver-public/styles/my.style.json",
"tilejson": {
"bounds": [
8.275,
47.225,
8.8,
47.533
]
}
}
},
"data": {
"v3": {
"pmtiles": "https://s3-api.[PH.DOMAIN]/tileserver-public/zurich.pmtiles"
}
}
}
This configuration file tells Tileserver to :
- retrieve the raw tiles data from your s3 in the
tileserver-publicbucket from a file namedzurich.pmtilesat the root of the bucket. - retrieve the style configuration from your s3 in the
tileserver-publicbucket from a file namedstyles/my.style.jsonat the root of the bucket. - do some previewing for the
basic-previewstyle through the.tilejson.boundsfield - look up in:
- the
/data/folder for local.pmtiles - the
/usr/src/app/node_modules/tileserver-gl-styles/styles/folder for local styles - the
/usr/src/app/node_modules/tileserver-gl-styles/fonts/folder for local fonts
- the
Please note that you're responsible for the validity of your configuration file, including the existence of the remote file you reference. Invalid configuration file causes the Tileserver to crash.
For more information on TileServer's configuration file, please consult tileserver-gl's online documentation
Define your style (style.json)​
Styles are an important part of Tileserver as they provide a user-friendly visual layer to your maps. HTTP requests to Tileserver can request a specific style.
Styles are applied to a unique .pmtiles file. The mapping between a style and a file is done through an identifier defined as following in the JSON file :
{
"version":8,
"name":"Basic preview",
"metadata":{
"openmaptiles:version":"3.x"
},
"sources":{
"openmaptiles":{
"type":"vector",
"url":"pmtiles://{v3}"
}
},
"glyphs":"{fontstack}/{range}.pbf",
"layers": [],
"id": "basic-preview"
}
- The
idfield highlighted should match the id present in theconfig.jsonconfiguration file in thestyleskey. (eg: in our case.styles.basic-preview) - The
urlfield highlighted references{v3}, which means the raw tiles data described by the.data.v3field in theconfig.jsonwill be matched to this style file.
This style.json is matched with the previous config.json file
As styles are very long and complex JSON files, it is advised to use already-existing ones as much as possible.
If you want to use the same style for multiple .pmtiles, the easiest way is to duplicate the JSON style file and change
the identifier and declare a new style in your config.json that point to this file.
All styles will not work with every kind of tiles. sources and layers depend heavily on the tiles themselves.
Some styles should already exist under the local styles folder, notably klokantech-basic and osm-bright.
For more information on styles application, please consult tileserver-gl's documentation
Using sprites uploaded in S3​
Sprites are bundles of icon & symbols that a style.json may reference. A sprite is made up of 2 kinds of files :
- a bundle of icon on a single png file
- the expected extensions are
.png&@2x.png
- the expected extensions are
- a metadata file that gives the id and position of every icon in the png file
- the expected extensions are
.json&@2x.json
- the expected extensions are
In the following high resolution exemple, we define 4 icons (circle-11, oneway, star-11, wood-pattern) that may be used in the style.json :
{
"circle-11": {
"height": 34,
"pixelRatio": 2,
"width": 34,
"x": 164,
"y": 0
},
"oneway": {
"height": 36,
"pixelRatio": 2,
"width": 36,
"x": 128,
"y": 0
},
"star-11": {
"height": 34,
"pixelRatio": 2,
"width": 34,
"x": 198,
"y": 0
},
"wood-pattern": {
"height": 128,
"pixelRatio": 2,
"width": 128,
"x": 0,
"y": 0
}
}
@2x and resolutionThe file with the @2x suffix are meant to be used on screen with high DPI (phone, tablet, ...) and are high resolution files with double the pixel dimensions.
The browser will request a resolution that match the screen DPI.
In order to add a sprite bundle & metadata you should use the sprite field in the style.json.
Contrary to other ressources in S3, you should not point directly to a single file.
Instead, you should provide a "prefix" and Tileserver will try to append 4 différents suffix to it to try and retrieve the sprite bundle & metadata. The suffix are :
.json&@2x.jsonfor the metadata file.png&@2x.pngfor the png file
In the exemple below we :
- Define a sprite URL that try to find the following files in the
tileserver-publicbucket :sprites/sprite.jsonsprites/sprite.pngsprites/sprite@2x.jsonsprites/sprite@2x.png
- Define a layer
housenumberthat make use of the iconcircle-11defined in thesprite.json/sprite@2x.jsonfile
{
"version":8,
"name":"Basic preview",
"metadata":{
"openmaptiles:version":"3.x"
},
"sources":{
"openmaptiles":{
"type":"vector",
"url":"pmtiles://{v3}"
}
},
"glyphs":"{fontstack}/{range}.pbf",
"sprite": "https://s3-api.[PH.DOMAIN]/tileserver-public/sprites/sprite",
"layers":[
[...],
{
"filter":[
"==",
"$type",
"Point"
],
"id":"housenumber",
"layout":{
"icon-image": "circle-11",
"icon-size": 10,
"text-field":"{housenumber}",
"text-font":[
"Noto Sans Regular"
],
"text-justify": "left",
"text-offset": [0.5, 0.2],
"text-size":10,
"text-transform": "uppercase",
"visibility": "visible"
},
"minzoom":17,
"paint":{
"icon-opacity": 0.7,
"text-color": "rgb(101,101,101)",
"text-halo-blur": 1,
"text-halo-color": "rgba(0,0,0,0.7)",
"text-halo-width": 1
},
"source":"openmaptiles",
"source-layer":"housenumber",
"type":"symbol"
},
[...]
],
"id":"basic-preview"
}
Override configuration in Tileserver chart and install/restart it​
Either with a values files:
- name: tileserver
namespace: kosmos-data
createNamespace: true
wait: true
chart: ../../tileserver/tileserver
skipDeps: true
labels:
app: tileserver
values:
- ../../tileserver/values.yaml
- ../../tileserver/override-conf.yaml
or by directly injecting values:
- name: tileserver
namespace: kosmos-data
createNamespace: true
wait: true
chart: ../../tileserver/tileserver
skipDeps: true
labels:
app: tileserver
values:
- ../../tileserver/values.yaml
- config:
styles:
basic:
style: "http://minio.kosmos-s3/<bucket>/style.json"
tiles:
mytiles:
pmtiles: "http://minio.kosmos-s3/<bucket>/mytiles.pmtiles"
Then install Tileserver.
If Tileserver is already deployed, restart its Deployment :
kubectl --namespace kosmos-data rollout restart deployment tileserver
After deploying your Tileserver instance, an initJob will verify whether all URLs are valid or not. Tileserver will not start until all URLs (styles and tiles) are reachable. This is useful for avoiding crashes if very large tiles are still being downloaded.
Update your configuration​
Modify your desired file in Tileserver's S3 bucket, modify your values file override-conf.yaml
Then upgrade the Tileserver helm installation
helm --namespace kosmos-data upgrade --install tileserver tileserver -f values.yaml -f override-conf.yaml
or
helmfile -n kosmos-data sync -l app=tileserver