-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
335 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
/build | ||
/public/tiles |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# Preview Website | ||
|
||
The code in this folder powers the [preview website](https://osm-regions.netlify.app/). | ||
|
||
It installs tippecanoe, downloads the OSM regions vector tileset, and extracts | ||
the individual tiles (`.pbf` files) up to zoom level 8 using | ||
[tile-join](https://github.com/mapbox/tippecanoe#tile-join). | ||
This generates about 24k files; adding more tiles with zoom levels 9 or 10 would make the | ||
build time out on Netlify. | ||
|
||
This approach makes it possible to preview the content of `regions.mbtiles` without | ||
maintaining a tile server in the back-end, and without storing the individual `.pbf` | ||
anywhere else. | ||
|
||
The deployment on Netlify is configured to run `build.sh` and then publish the content | ||
of the `public` folder. | ||
|
||
## Run locally | ||
|
||
- Run `build.sh` | ||
- Start a web server in the `public` folder and check the result |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
#!/bin/bash | ||
set -o errexit | ||
set -o nounset | ||
|
||
# Enter directory of build script, so relative paths below are working | ||
cd $(dirname "$0") | ||
|
||
# Build tippecanoe | ||
( | ||
mkdir -p build/tippecanoe | ||
cd build/tippecanoe | ||
curl -L https://github.com/mapbox/tippecanoe/archive/1.35.0.tar.gz | tar xz --strip-components=1 | ||
make -j | ||
) | ||
|
||
# Download and extract tileset | ||
curl -L -o build/regions.zip https://github.com/nzzdev/osm-regions/releases/download/v0.1.0/regions-v0.1.0.zip | ||
unzip build/regions.zip -d build | ||
|
||
# Extract tiles | ||
./build/tippecanoe/tile-join \ | ||
--no-tile-compression \ | ||
--no-tile-size-limit \ | ||
--maximum-zoom=8 \ | ||
--output-to-directory=public/tiles \ | ||
build/regions.mbtiles | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<meta charset="utf-8" /> | ||
<meta name="viewport" content="width=device-width" /> | ||
<title>OSM Regions Preview</title> | ||
<link | ||
rel="stylesheet" | ||
href="https://unpkg.com/[email protected]/dist/mapbox-gl.css" | ||
integrity="sha384-UZ+LVvoKDw3Z1M+G8PTJnK15pz8bkHYawBRgjnu8G6HOF6m1Sswa8NmgIRHBwl6W" | ||
crossorigin="anonymous" | ||
/> | ||
<style> | ||
html, | ||
body, | ||
#map { | ||
height: 100%; | ||
margin: 0; | ||
} | ||
|
||
#menu { | ||
background: #fff; | ||
position: absolute; | ||
z-index: 1; | ||
top: 10px; | ||
right: 10px; | ||
border-radius: 3px; | ||
width: 200px; | ||
border: 1px solid rgba(0, 0, 0, 0.4); | ||
font-family: "Open Sans", sans-serif; | ||
} | ||
|
||
#menu a { | ||
font-size: 13px; | ||
color: #404040; | ||
display: block; | ||
margin: 0; | ||
padding: 0; | ||
padding: 10px; | ||
text-decoration: none; | ||
border-bottom: 1px solid rgba(0, 0, 0, 0.25); | ||
text-align: center; | ||
} | ||
|
||
#menu a:last-child { | ||
border: none; | ||
} | ||
|
||
#menu a:hover { | ||
background-color: #f8f8f8; | ||
color: #404040; | ||
} | ||
|
||
#menu a.active { | ||
background-color: #3887be; | ||
color: #ffffff; | ||
} | ||
|
||
#menu a.active:hover { | ||
background: #3074a4; | ||
} | ||
|
||
#forkongithub { | ||
position: fixed; | ||
display: none; | ||
top: 0; | ||
left: 0; | ||
width: 200px; | ||
height: 200px; | ||
z-index: 9999; | ||
pointer-events: none; | ||
} | ||
#forkongithub a { | ||
width: 200px; | ||
position: absolute; | ||
top: 60px; | ||
left: -60px; | ||
transform: rotate(-45deg); | ||
background: #000; | ||
color: #fff; | ||
box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.8); | ||
text-decoration: none; | ||
font-family: arial, sans-serif; | ||
text-align: center; | ||
font-weight: bold; | ||
padding: 5px 40px; | ||
font-size: 1rem; | ||
line-height: 2rem; | ||
transition: 0.5s; | ||
pointer-events: all; | ||
} | ||
#forkongithub a:hover { | ||
background: #c11; | ||
color: #fff; | ||
} | ||
#forkongithub a::before, | ||
#forkongithub a::after { | ||
content: ""; | ||
width: 100%; | ||
display: block; | ||
position: absolute; | ||
top: 1px; | ||
left: 0; | ||
height: 1px; | ||
background: #fff; | ||
} | ||
#forkongithub a::after { | ||
bottom: 1px; | ||
top: auto; | ||
} | ||
#forkongithub svg { | ||
width: 16px; | ||
height: 16px; | ||
vertical-align: middle; | ||
fill-rule: evenodd; | ||
clip-rule: evenodd; | ||
stroke-linejoin: round; | ||
stroke-miterlimit: 2; | ||
} | ||
@media screen and (min-width: 400px) { | ||
#forkongithub { | ||
display: block; | ||
} | ||
} | ||
</style> | ||
</head> | ||
|
||
<body> | ||
<span id="forkongithub" | ||
><a href="https://github.com/nzzdev/osm-regions" | ||
>Fix, Fork, Contribute | ||
<svg viewBox="0 0 136 133"> | ||
<g transform="matrix(3.92891,0,0,3.92891,67.867,129.125)"> | ||
<path | ||
d="M0,-31.904C-8.995,-31.904 -16.288,-24.611 -16.288,-15.614C-16.288,-8.417 -11.621,-2.312 -5.148,-0.157C-4.333,-0.008 -4.036,-0.511 -4.036,-0.943C-4.036,-1.329 -4.05,-2.354 -4.058,-3.713C-8.589,-2.729 -9.545,-5.897 -9.545,-5.897C-10.286,-7.779 -11.354,-8.28 -11.354,-8.28C-12.833,-9.29 -11.242,-9.27 -11.242,-9.27C-9.607,-9.155 -8.747,-7.591 -8.747,-7.591C-7.294,-5.102 -4.934,-5.821 -4.006,-6.238C-3.858,-7.29 -3.438,-8.008 -2.972,-8.415C-6.589,-8.826 -10.392,-10.224 -10.392,-16.466C-10.392,-18.244 -9.757,-19.698 -8.715,-20.837C-8.883,-21.249 -9.442,-22.905 -8.556,-25.148C-8.556,-25.148 -7.188,-25.586 -4.076,-23.478C-2.777,-23.84 -1.383,-24.02 0.002,-24.026C1.385,-24.02 2.779,-23.84 4.08,-23.478C7.19,-25.586 8.555,-25.148 8.555,-25.148C9.444,-22.905 8.885,-21.249 8.717,-20.837C9.761,-19.698 10.392,-18.244 10.392,-16.466C10.392,-10.208 6.583,-8.831 2.954,-8.428C3.539,-7.925 4.06,-6.931 4.06,-5.411C4.06,-3.234 4.04,-1.477 4.04,-0.943C4.04,-0.507 4.333,0 5.16,-0.159C11.628,-2.318 16.291,-8.419 16.291,-15.614C16.291,-24.611 8.997,-31.904 0,-31.904" | ||
fill="#fff" | ||
/> | ||
</g></svg></a | ||
></span> | ||
<div id="map"></div> | ||
<nav id="menu"></nav> | ||
<script | ||
src="https://unpkg.com/[email protected]/dist/mapbox-gl.js" | ||
integrity="sha384-hp+60VBsp8hgihZyl1uif2hLBscBslPIeSwzMRsL94kJt8g38xaDKAXOXsle5EDW" | ||
crossorigin | ||
></script> | ||
<script src="preview-tiles.js"></script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
const map = new mapboxgl.Map({ | ||
container: document.getElementById("map"), | ||
hash: true, | ||
style: | ||
"https://api.maptiler.com/maps/positron/style.json?key=qdSqvQdaTpTPAsu0YByB", | ||
}); | ||
|
||
map.on("load", () => { | ||
const baseUrl = `${window.location.protocol}//${window.location.host}`; | ||
|
||
// Add regions as source | ||
map.addSource("regions", { | ||
maxzoom: 8, | ||
promoteId: "wikidata", | ||
type: "vector", | ||
tiles: [`${baseUrl}/tiles/{z}/{x}/{y}.pbf`], | ||
}); | ||
|
||
["countries", "subdivisions"].forEach((regionType, i) => { | ||
const visibility = ["visible", "none"][i]; | ||
|
||
// Fill polygons blue, with highlight on mouseover | ||
map.addLayer({ | ||
id: `${regionType}-area`, | ||
type: "fill", | ||
source: "regions", | ||
"source-layer": regionType, | ||
paint: { | ||
"fill-color": [ | ||
"case", | ||
["boolean", ["feature-state", "mouseover"], false], | ||
"#fad250", | ||
"steelblue", | ||
], | ||
"fill-opacity": [ | ||
"case", | ||
["boolean", ["feature-state", "mouseover"], false], | ||
0.4, | ||
0.1, | ||
], | ||
}, | ||
layout: { visibility }, | ||
}); | ||
|
||
// Add blue outline | ||
map.addLayer({ | ||
id: `${regionType}-outline`, | ||
type: "line", | ||
source: "regions", | ||
"source-layer": regionType, | ||
paint: { | ||
"line-width": 1, | ||
"line-color": "steelblue", | ||
}, | ||
layout: { visibility }, | ||
}); | ||
|
||
// Show attributes on mouseover | ||
const popup = new mapboxgl.Popup({ | ||
closeButton: false, | ||
closeOnClick: false, | ||
}); | ||
|
||
let oldFeatures = []; | ||
|
||
map.on("mousemove", `${regionType}-area`, ({ features, lngLat }) => { | ||
if (features.length) { | ||
map.getCanvas().style.cursor = "pointer"; | ||
|
||
// Update highlighting of features | ||
setMouseoverState(oldFeatures, false); | ||
setMouseoverState(features, true); | ||
oldFeatures = features; | ||
|
||
// Show popup at mouse location | ||
const wikidataIds = features.map( | ||
({ properties: { wikidata } }) => wikidata | ||
); | ||
popup | ||
.setLngLat(lngLat) | ||
.setHTML(`<div>${wikidataIds.join(", ")}</div>`) | ||
.addTo(map); | ||
} | ||
}); | ||
|
||
map.on("mouseleave", `${regionType}-area`, ({ features }) => { | ||
map.getCanvas().style.cursor = ""; | ||
|
||
// Remove highlighting from features | ||
setMouseoverState(oldFeatures, false); | ||
|
||
popup.remove(); | ||
}); | ||
}); | ||
|
||
// Adapted from https://docs.mapbox.com/mapbox-gl-js/example/toggle-layers/ | ||
const toggleableLayers = { | ||
countries: "Countries", | ||
subdivisions: "Subdivisions", | ||
}; | ||
Object.entries(toggleableLayers).forEach(([id, name]) => { | ||
const link = document.createElement("a"); | ||
link.href = "#"; | ||
link.id = id; | ||
link.textContent = name; | ||
if (map.getLayoutProperty(`${id}-area`, "visibility") !== "none") { | ||
link.className = "active"; | ||
} | ||
|
||
link.onclick = function (event) { | ||
event.preventDefault(); | ||
event.stopPropagation(); | ||
|
||
const visibility = map.getLayoutProperty(`${this.id}-area`, "visibility"); | ||
|
||
if (visibility === "none") { | ||
this.className = "active"; | ||
map.setLayoutProperty(`${this.id}-area`, "visibility", "visible"); | ||
map.setLayoutProperty(`${this.id}-outline`, "visibility", "visible"); | ||
} else { | ||
map.setLayoutProperty(`${this.id}-area`, "visibility", "none"); | ||
map.setLayoutProperty(`${this.id}-outline`, "visibility", "none"); | ||
this.className = ""; | ||
} | ||
}; | ||
|
||
const layers = document.getElementById("menu"); | ||
layers.appendChild(link); | ||
}); | ||
}); | ||
|
||
function setMouseoverState(features, state) { | ||
features.forEach((feature) => { | ||
map.setFeatureState(feature, { mouseover: state }); | ||
}); | ||
} |