Improve layering, update screenshot

maplibre-gl
Jake Coppinger 2023-01-05 17:06:46 +11:00
rodzic 5769ebfb2a
commit 012c211654
6 zmienionych plików z 222 dodań i 181 usunięć

Wyświetl plik

@ -1,10 +1,10 @@
Safe Cycling Map
================
Work in progress! PRs and forks very welcome :)
Work in progress! PRs and forks very welcome :)
![Screenshot of map](img/safe-cycling-map-2022-01-05.jpg)
![Screenshot of map](img/safe-cycling-map-2022-01-05-v2.jpg)
A map of bike infrastructure using [osm2streets](https://github.com/a-b-street/osm2streets) output.

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 348 KiB

Wyświetl plik

@ -63,7 +63,7 @@ h1 {
z-index: 10;
bottom: 0px;
left: 10px;
color: #19ff15bf;
color: #039f00bf;
font-size: calc(2vw + 2vh + 10px);
line-height: 0.8;
}

Wyświetl plik

@ -1,84 +0,0 @@
import mapboxgl from "mapbox-gl";
import * as http from "https";
// southern-most latitude, western-most longitude, northern-most latitude, eastern-most longitude.
export async function getOSMData(bounds: number[]): Promise<any> {
const options = {
hostname: "overpass-api.de",
port: 443,
path: "/api/interpreter",
method: "POST",
headers: {
"Content-Type": "application/json",
},
};
console.log("Started POST request...");
const boundsStr = bounds.join(",");
const request_str = `
[out:json][timeout:25];
(
// query part for: “bicycle_parking=*”
node["bicycle_parking"](${boundsStr});
way["bicycle_parking"](${boundsStr});
relation["bicycle_parking"](${boundsStr});
// query part for: “amenity=bicycle_parking”
node["amenity"="bicycle_parking"](${boundsStr});
way["amenity"="bicycle_parking"](${boundsStr});
relation["amenity"="bicycle_parking"](${boundsStr});
);
out body;
>;
out skel qt;
`;
console.log("request:", request_str);
return new Promise((resolve, reject) => {
var req = http.request(options, function (res) {
var body = "";
res.setEncoding("utf8");
res.on("data", (chunk) => (body += chunk));
res.on("end", function () {
if (res.statusCode !== 200) {
console.log("error code", res.statusCode);
reject(res.statusCode);
}
const jsonResponse = JSON.parse(body);
const bars = jsonResponse.elements;
resolve(bars);
});
});
req.on("error", function (e) {
reject(e.message);
});
req.write(request_str);
req.end();
});
}
export function drawmap(map: mapboxgl.Map): void {
map.addControl(new mapboxgl.NavigationControl());
map.addControl(new mapboxgl.FullscreenControl());
// Add geolocate control to the map.
map.addControl(
new mapboxgl.GeolocateControl({
positionOptions: {
enableHighAccuracy: true,
},
trackUserLocation: true,
})
);
map.on("moveend", function (originalEvent) {
const { lat, lng } = map.getCenter();
console.log("A moveend event occurred.");
console.log({ lat, lng });
// eg https://localhost:3000
const location = window.location.origin;
console.log({ location });
});
}
export function removeMarkers(markers: mapboxgl.Marker[]): void {
markers.map((marker) => marker.remove());
}

205
src/layers.ts 100644
Wyświetl plik

@ -0,0 +1,205 @@
function addLayer(
map: mapboxgl.Map,
type:
| "Driving"
| "Parking"
| "Sidewalk"
| "Shoulder"
| "Biking"
| "Bus"
| "SharedLeftTurn"
| "Construction"
| "LightRail"
| "Footway"
| "SharedUse",
paint: mapboxgl.FillPaint | undefined
): void {
map.addLayer({
id: type,
type: "fill",
source: "osm2streets-vector-tileserver",
"source-layer": "lanePolygons",
paint,
filter: ["==", "type", type],
// filter: ["==", "$type", "Polygon"],
}, 'road-label');
}
const colours = {
laneMarking: "white",
intersection: "#666666",
// Derived from
// https://github.com/a-b-street/osm2streets/blob/5b40c7af877d4314ca7e45c5ac35ec472845c6ca/street-explorer/www/js/layers.js#L55
Driving: "grey",
// Driving: "black",
Parking: "#333333",
Sidewalk: "#CCCCCC",
Shoulder: "#CCCCCC",
Biking: "#0F7D4B",
Bus: "#BE4A4C",
SharedLeftTurn: "black",
Construction: "#FF6D00",
LightRail: "#844204",
"Buffer(Planters)": "#555555",
Footway: "#DDDDE8",
SharedUse: "#E5E1BB",
};
export const mapOnLoad = (map: mapboxgl.Map) => () => {
const layers = map.getStyle().layers;
// Find the index of the first symbol layer in the map style.
let firstSymbolId;
for (const layer of layers) {
if (layer.type === "symbol") {
firstSymbolId = layer.id;
break;
}
}
console.log({ firstSymbolId });
console.log(
"Adding sources. If you don't seen anything check vector server logs."
);
// https://docs.mapbox.com/mapbox-gl-js/example/multiple-geometries/
// Add a new vector tile source with ID 'mapillary'.
map.addSource("osm2streets-vector-tileserver", {
type: "vector",
tiles: ["http://localhost:3000/tile/{z}/{x}/{y}"],
minzoom: 15,
maxzoom: 20,
});
// addLayer(map, "LightRail", {
// "fill-color": "yellow",
// "fill-opacity": 0.2,
// });
// map.addLayer({
// id: "geometry",
// type: "fill",
// source: "osm2streets-vector-tileserver",
// "source-layer": "geometry",
// paint: {
// // To improve!
// "fill-color": colours.Driving,
// "fill-opacity": 0.4,
// },
// filter: ["==", "$type", "Polygon"],
// });
// map.addLayer({
// id: "lanePolygons",
// type: "fill",
// source: "osm2streets-vector-tileserver",
// "source-layer": "lanePolygons",
// paint: {
// "fill-color": colours.Driving,
// "fill-opacity": 1,
// },
// filter: ["==", "$type", "Polygon"],
// });
// addLayer(map, "Biking", {
// "fill-color": colours.Biking,
// "fill-opacity": 1,
// });
addLayer(map, "SharedUse", {
"fill-color": "blue",
"fill-opacity": 0.3,
});
addLayer(map, "Shoulder", {
"fill-color": colours.Shoulder,
"fill-opacity": 0.5,
});
addLayer(map, "Sidewalk", {
"fill-color": colours.Sidewalk,
"fill-opacity": 0.9,
});
// Currently on the wrong side of ways??
addLayer(map, "Footway", {
"fill-color": colours.Footway,
"fill-opacity": 0.9,
});
addLayer(map, "Driving", {
"fill-color": colours.Driving,
"fill-opacity": 0.9,
});
addLayer(map, "Bus", {
"fill-color": colours.Bus,
"fill-opacity": 0.9,
});
addLayer(map, "Construction", {
"fill-color": colours.Construction,
"fill-opacity": 0.5,
});
map.addLayer({
id: "intersection",
type: "fill",
source: "osm2streets-vector-tileserver",
"source-layer": "geometry",
paint: {
"fill-color": colours.intersection,
"fill-opacity": 1,
},
/*
along with `type`, other attributes we could use here are:
- control": "Signed" | "Signalled" | "Uncontrolled"
*/
filter: ["==", "type", "intersection"],
}, 'road-label');
// // Currently on the wrong side of ways??
// addLayer(map, "Parking", {
// "fill-color": 'yellow',
// "fill-opacity": 0.9,
// });
map.addLayer({
id: "Biking",
type: "fill",
source: "osm2streets-vector-tileserver",
"source-layer": "lanePolygons",
paint: {
"fill-color": colours.Biking,
"fill-opacity": 1,
},
filter: ["==", "type", "Biking"],
// filter: ["==", "type", "Biking"],
}, 'road-label');
map.addLayer({
id: "intersectionMarkings",
type: "fill",
source: "osm2streets-vector-tileserver",
"source-layer": "intersectionMarkings",
paint: {
"fill-color": colours.Driving,
"fill-opacity": 0.8,
},
filter: ["==", "$type", "Polygon"],
}, 'road-label');
map.addLayer({
id: "laneMarkings",
type: "fill",
source: "osm2streets-vector-tileserver",
"source-layer": "laneMarkings",
paint: {
"fill-color": colours.laneMarking,
"fill-opacity": 1,
},
filter: ["==", "$type", "Polygon"],
}, 'road-label');
};

Wyświetl plik

@ -4,26 +4,20 @@ import React, { useRef, useEffect, useState } from "react";
// import mapboxgl from "!mapbox-gl";
import mapboxgl from "mapbox-gl";
import "./App.css";
import { mapOnLoad } from "./layers";
const MAPBOX_TOKEN =
"pk.eyJ1IjoiamFrZWMiLCJhIjoiY2tkaHplNGhjMDAyMDJybW4ybmRqbTBmMyJ9.AR_fnEuka8-cFb4Snp3upw";
mapboxgl.accessToken = MAPBOX_TOKEN;
const colours = {
road: "grey",
cycleway: "green",
laneMarking: "white",
};
type LoadingStatusType = "loading" | "success" | "429error" | "unknownerror";
export function Map() {
const mapContainer = React.useRef<HTMLDivElement>(null);
const mapRef = React.useRef<mapboxgl.Map | null>(null);
const markers = useRef<mapboxgl.Marker[]>([]);
const [lng, setLng] = useState(151.20671);
const [lat, setLat] = useState(-33.8683861);
const [zoom, setZoom] = useState(16);
const [lng, setLng] = useState(151.21084276742022);
const [lat, setLat] = useState(-33.8720286260115);
const [zoom, setZoom] = useState(17);
useEffect(() => {
// This is called on every pan
@ -36,90 +30,14 @@ export function Map() {
mapRef.current = new mapboxgl.Map({
container: mapContainer.current,
style: "mapbox://styles/mapbox/dark-v10",
style: "mapbox://styles/mapbox/streets-v12",
// style: "mapbox://styles/mapbox/dark-v10",
center: [lng, lat],
zoom: zoom,
});
const map = mapRef.current;
map.on("load", function () {
console.log(
"Adding sources. If you don't seen anything check vector server logs."
);
// https://docs.mapbox.com/mapbox-gl-js/example/multiple-geometries/
// Add a new vector tile source with ID 'mapillary'.
map.addSource("osm2streets-vector-tileserver", {
type: "vector",
tiles: ["http://localhost:3000/tile/{z}/{x}/{y}"],
minzoom: 15,
maxzoom: 22,
});
map.addLayer({
id: "geometry",
type: "fill",
source: "osm2streets-vector-tileserver",
"source-layer": "geometry",
paint: {
// To improve!
"fill-color": colours.road,
"fill-opacity": 0.4,
},
filter: ["==", "$type", "Polygon"],
});
map.addLayer({
id: "lanePolygons",
type: "fill",
source: "osm2streets-vector-tileserver",
"source-layer": "lanePolygons",
paint: {
"fill-color": colours.road,
"fill-opacity": 1,
},
filter: ["==", "$type", "Polygon"],
});
map.addLayer({
id: "bikePath",
type: "fill",
source: "osm2streets-vector-tileserver",
"source-layer": "lanePolygons",
paint: {
"fill-color": colours.cycleway,
"fill-opacity": 1,
},
filter: ["==", "type", "Biking"],
// filter: ["==", "$type", "Polygon"],
});
map.addLayer({
id: "laneMarkings",
type: "fill",
source: "osm2streets-vector-tileserver",
"source-layer": "laneMarkings",
paint: {
"fill-color": colours.laneMarking,
"fill-opacity": 1,
},
filter: ["==", "$type", "Polygon"],
});
map.addLayer({
id: "intersectionMarkings",
type: "fill",
source: "osm2streets-vector-tileserver",
"source-layer": "intersectionMarkings",
paint: {
"fill-color": colours.road,
"fill-opacity": 0.8,
},
filter: ["==", "$type", "Polygon"],
});
});
map.on("load", mapOnLoad(map));
map.addControl(new mapboxgl.NavigationControl());
map.addControl(new mapboxgl.FullscreenControl());
@ -136,6 +54,9 @@ export function Map() {
if (!map) {
return; // wait for map to initialize
}
const { lng, lat } = map.getCenter();
const zoom = map.getZoom();
console.log(lng, lat, zoom);
setLng(map.getCenter().lng);
setLat(map.getCenter().lat);
@ -143,12 +64,11 @@ export function Map() {
});
});
return (
<div>
<div className="sidebar">
<label>
A side-project by{" "}
A work in progrss side project by{" "}
<a
target="_blank"
rel="noopener noreferrer"
@ -156,7 +76,7 @@ export function Map() {
>
Jake Coppinger
</a>{" "}
| Open source (GPLv3) on{" "}
| Open source on{" "}
<a
target="_blank"
rel="noopener noreferrer"