Skip to content

Commit

Permalink
Add preview website
Browse files Browse the repository at this point in the history
  • Loading branch information
rkaravia committed Jun 19, 2020
1 parent 3f63141 commit 2f1e1a4
Show file tree
Hide file tree
Showing 5 changed files with 335 additions and 0 deletions.
2 changes: 2 additions & 0 deletions preview-website/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/build
/public/tiles
21 changes: 21 additions & 0 deletions preview-website/README.md
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
27 changes: 27 additions & 0 deletions preview-website/build.sh
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

149 changes: 149 additions & 0 deletions preview-website/public/index.html
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>
136 changes: 136 additions & 0 deletions preview-website/public/preview-tiles.js
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 });
});
}

0 comments on commit 2f1e1a4

Please sign in to comment.