rtnf’s Diary | Self-hosted vector tiles.
Impressed by this video, i wish to make my very own self-hosted vector tiles.
First, put together a number of geojson file through the use of JOSM. Every geojson file will function a “layer”. We are able to specify the fashion for every layer. I made three layer (mainroad, suburb, jalan_rest), with this specification
- mainroad :
freeway= (secondary | major | trunk | tertiary)
- suburb :
place=suburb
- jalan_rest :
freeway= (* && not secondary && not major && not trunk && not tertiary)
Use JOSM, create overpass question, save as .geojson, repeat.
Second, convert these geojson file to mbtile format through the use of tippecanoe. Putting in tippecanoe on MacOS / Linux is fairly easy. However, putting in on Home windows wants a quick-hack. I adopted this information , it really works.
Then mix all these geojson file into one mbtile file through the use of tippecanoe.
Then, convert that mbtile file to pmtile through the use of go-pmtiles
Now, let’s show that mbtile and do some styling.
Index.html, first, let’s import maplibre-gl and pmtiles javascript library.
<script src="https://www.openstreetmap.org/consumer/rtnf/diary/maplibre-gl.js"></script>
<hyperlink href="maplibre-gl.css" rel="stylesheet" />
<script src="pmtiles-2.5.0.js"></script>
Then, outline the map
let protocol = new pmtiles.Protocol();
maplibregl.addProtocol("pmtiles",protocol.tile);
console.log(maplibregl)
var map = new maplibregl.Map({
container: 'map',
fashion: 'kinds/maptiler-basic.json',
heart: [106.99811303126697,-6.295502009348816],
zoom: 11
});
The remainder of the configurations are saved on that “maptiler-basic.json”.
Let’s configure the pmtiles file
"sources": {
"openmaptiles": {
"kind": "vector",
"url": "pmtiles://bks2.pmtiles"
}
}
Then, configure the fonts file
"glyphs": "fonts-gh-pages/{fontstack}/{vary}.pbf"
Lastly, configure the precise map fashion. Match the “layer” from tippecanoe’s output to “source-layer” tag.
Mainroad layer fashion :
{
"id": "road_major_motorway",
"kind": "line",
"supply": "openmaptiles",
"source-layer": "mainroad",
"structure": {"line-cap": "spherical", "line-join": "spherical"},
"paint": {
"line-color": "hsl(0, 0%, 100%)",
"line-offset": 0,
"line-width": {"base": 1.4, "stops": [[8, 1], [16, 10]]}
}
}
Suburb layer fashion
{
"id": "place_label_city",
"kind": "image",
"supply": "openmaptiles",
"source-layer": "suburb",
"maxzoom": 16,
"structure": {
"text-field": "{title}",
"text-font": ["Open Sans Regular"],
"text-max-width": 10,
"text-size": {"stops": [[3, 12], [8, 16]]}
},
"paint": {
"text-color": "hsl(0, 0%, 0%)",
"text-halo-blur": 0,
"text-halo-color": "hsla(0, 0%, 100%, 0.75)",
"text-halo-width": 2
}
}
Jalan-rest layer fashion
{
"id": "road_minor",
"kind": "line",
"supply": "openmaptiles",
"source-layer": "jalan_rest",
"minzoom": 13,
"structure": {"line-cap": "spherical", "line-join": "spherical"},
"paint": {
"line-color": "hsl(0, 0%, 97%)",
"line-width": {"base": 1.55, "stops": [[4, 0.25], [20, 30]]}
}
}
Highway label configuration
{
"id": "road_major_label",
"kind": "image",
"supply": "openmaptiles",
"source-layer": "mainroad",
"minzoom": 13,
"structure": {
"symbol-placement": "line",
"text-field": "{title}",
"text-font": ["Open Sans Regular"],
"text-letter-spacing": 0.1,
"text-rotation-alignment": "map",
"text-size": {"base": 1.4, "stops": [[10, 8], [20, 14]]},
"text-transform": "uppercase",
"visibility": "seen"
},
"paint": {
"text-color": "#000",
"text-halo-color": "hsl(0, 0%, 100%)",
"text-halo-width": 2
}
},
{
"id": "road_minor_label",
"kind": "image",
"supply": "openmaptiles",
"source-layer": "jalan_rest",
"minzoom": 13,
"structure": {
"symbol-placement": "line",
"text-field": "{title}",
"text-font": ["Open Sans Regular"],
"text-letter-spacing": 0.1,
"text-rotation-alignment": "map",
"text-size": {"base": 1.4, "stops": [[10, 8], [20, 14]]},
"text-transform": "uppercase",
"visibility": "seen"
},
"paint": {
"text-color": "#000",
"text-halo-color": "hsl(0, 0%, 100%)",
"text-halo-width": 2
}
}
Performed!