Skip to content

Instantly share code, notes, and snippets.

@shreyasborse
Created May 16, 2024 20:35
Show Gist options
  • Save shreyasborse/1b9e57a4a9c52d308ff6be79807ef53f to your computer and use it in GitHub Desktop.
Save shreyasborse/1b9e57a4a9c52d308ff6be79807ef53f to your computer and use it in GitHub Desktop.
#!/bin/bash
# Update and upgrade system packages
sudo apt update
sudo apt upgrade -y
# Install required packages
sudo apt install -y wget git build-essential cmake libprotobuf-dev protobuf-compiler libsqlite3-dev zlib1g-dev osmium-tool nodejs npm nginx
# Download OSM data for Berlin
wget http://download.geofabrik.de/europe/germany/berlin-latest.osm.pbf -O berlin.osm.pbf
# Clone and build tippecanoe for creating vector tiles
git clone https://github.com/mapbox/tippecanoe.git
cd tippecanoe
make -j
sudo make install
cd ..
# Convert OSM data to GeoJSON
osmium export berlin.osm.pbf -o berlin.geojson
# Generate vector tiles from GeoJSON using tippecanoe with multiple layers
tippecanoe -o berlin.mbtiles --read-parallel --layer=buildings --layer=roads --layer=landuse --maximum-zoom=14 --minimum-zoom=0 berlin.geojson
# Install tileserver-gl-light to serve vector tiles
sudo npm install -g tileserver-gl-light
# Create a directory to store the tileserver configuration and data
mkdir -p /var/www/tileserver
cp berlin.mbtiles /var/www/tileserver/
# Create a tileserver-gl-light configuration file
echo '{
"options": {
"paths": {
"root": "/var/www/tileserver"
}
},
"layers": [{
"options": {
"minzoom": 0,
"maxzoom": 14
},
"source": "mbtiles://berlin.mbtiles",
"name": "berlin"
}]
}' | sudo tee /var/www/tileserver/config.json
# Create a systemd service file for tileserver-gl-light
echo "[Unit]
Description=tileserver-gl-light
After=network.target
[Service]
ExecStart=/usr/bin/tileserver-gl-light --config /var/www/tileserver/config.json
Restart=always
User=nobody
Group=nogroup
Environment=NODE_ENV=production
WorkingDirectory=/var/www/tileserver
[Install]
WantedBy=multi-user.target" | sudo tee /etc/systemd/system/tileserver-gl-light.service
# Enable and start the tileserver-gl-light service
sudo systemctl enable tileserver-gl-light
sudo systemctl start tileserver-gl-light
# Configure Nginx to proxy requests to tileserver-gl-light
echo "server {
listen 80;
server_name _;
location /data {
proxy_pass http://localhost:8080/;
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
}
}" | sudo tee /etc/nginx/sites-available/tileserver
# Enable the Nginx configuration
sudo ln -s /etc/nginx/sites-available/tileserver /etc/nginx/sites-enabled/
sudo systemctl restart nginx
# Create the HTML file to use MapLibre GL JS
sudo mkdir -p /var/www/html/map
echo "<!DOCTYPE html>
<html>
<head>
<meta charset=\"utf-8\">
<title>MapLibre GL JS Example</title>
<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">
<script src=\"https://unpkg.com/maplibre-gl@latest/dist/maplibre-gl.js\"></script>
<link href=\"https://unpkg.com/maplibre-gl@latest/dist/maplibre-gl.css\" rel=\"stylesheet\" />
<style>
body { margin: 0; padding: 0; }
#map { position: absolute; top: 0; bottom: 0; width: 100%; }
</style>
</head>
<body>
<div id=\"map\"></div>
<script>
var map = new maplibregl.Map({
container: 'map', // container id
style: {
\"version\": 8,
\"sources\": {
\"osm\": {
\"type\": \"vector\",
\"url\": \"http://18.219.190.33/data/berlin.json\"
}
},
\"layers\": [{
\"id\": \"buildings-layer\",
\"type\": \"fill\",
\"source\": \"osm\",
\"source-layer\": \"buildings\",
\"paint\": {
\"fill-color\": \"#888\",
\"fill-opacity\": 0.4
}
}, {
\"id\": \"roads-layer\",
\"type\": \"line\",
\"source\": \"osm\",
\"source-layer\": \"roads\",
\"layout\": {
\"line-join\": \"round\",
\"line-cap\": \"round\"
},
\"paint\": {
\"line-color\": \"#888\",
\"line-width\": 2
}
}, {
\"id\": \"landuse-layer\",
\"type\": \"fill\",
\"source\": \"osm\",
\"source-layer\": \"landuse\",
\"paint\": {
\"fill-color\": \"#aaa\",
\"fill-opacity\": 0.5
}
}]
},
center: [13.4050, 52.5200], // starting position [lng, lat]
zoom: 12 // starting zoom
});
</script>
</body>
</html>" | sudo tee /var/www/html/map/index.html
# Print completion message
echo "Setup complete. You can access the map at http://18.219.190.33:8080/data/v3/#8.74/47.3785/8.255"
@shreyasborse
Copy link
Author

For AWS instance (optional)

  1. Create a new instance with Ubuntu 24.04 LTS
  2. Open ports HTTP, HTTPS and 8080
  3. Add sufficient memory and processing power t2.medium + server
  4. Add sufficient Hard disk space

All instructions are tested on Ubuntu 24.04 LTS

Steps are as follows

  1. Install required packages
  2. Download OSM data for specific cities or if the server resources allow download it for the world. (Tiles are made using an efficient C++ program so don't) worry about efficiency.
  3. It is a Postgres-free process, Postgres is not used anywhere.
  4. Convert OSM data to vector GeoJSON format using Osmium tools
  5. Install Tippecanoe and generate vector tiles using Tippecanoe
    https://github.com/mapbox/tippecanoe
    (It is an old but very efficient tool)
  6. Install tileserver-gl-light t server vector tiles
    Note tileserver-gl can be used for advanced modifications and stylings but in most cases lightweight version is better.
  7. Install Nginx to serve html file and proxied tile server.
  8. Run the following script which is tested on Ubuntu 24.04 LTS

***Change IP wherever applicable ***

I made a gist file here
https://gist.github.com/shreyasborse/1b9e57a4a9c52d308ff6be79807ef53f

1.Create a file in the /tmp folder setup_vector_tiles.sh
2. Give appropriate permissions to run

sudo chmod +x setup_vector_tiles.sh
3. run the file
./setup_vector_tiles.sh

View it here
http://18.219.190.33:8080/data/v3/#8.74/47.3785/8.255

Right now there are some settings issue with MAPlibre GL JS,
but main task of creating and service vecotr tiles is completed.
and tiles can be seen through Tileserver light http://18.219.190.33:8080/

@shreyasborse
Copy link
Author

shreyasborse commented May 16, 2024

If the tileserver is not running, run this command again

sudo tileserver-gl-light --config /var/www/tileserver/config.json

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment