mirror of
https://github.com/protomaps/PMTiles.git
synced 2026-02-04 10:51:07 +00:00
app improvements (#258)
* viewer app: improve type safety and visibility of overlay features. * correct basemap attribution. * prettier
This commit is contained in:
1
app/package-lock.json
generated
1
app/package-lock.json
generated
@@ -28,6 +28,7 @@
|
|||||||
"react-use": "^17.4.0"
|
"react-use": "^17.4.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@maplibre/maplibre-gl-style-spec": "^19.3.1",
|
||||||
"@types/d3-path": "^3.0.0",
|
"@types/d3-path": "^3.0.0",
|
||||||
"@types/d3-scale-chromatic": "^3.0.0",
|
"@types/d3-scale-chromatic": "^3.0.0",
|
||||||
"@types/leaflet": "^1.7.9",
|
"@types/leaflet": "^1.7.9",
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
"react-use": "^17.4.0"
|
"react-use": "^17.4.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@maplibre/maplibre-gl-style-spec": "^19.3.1",
|
||||||
"@types/d3-path": "^3.0.0",
|
"@types/d3-path": "^3.0.0",
|
||||||
"@types/d3-scale-chromatic": "^3.0.0",
|
"@types/d3-scale-chromatic": "^3.0.0",
|
||||||
"@types/leaflet": "^1.7.9",
|
"@types/leaflet": "^1.7.9",
|
||||||
|
|||||||
@@ -8,10 +8,18 @@ import { MapGeoJSONFeature } from "maplibre-gl";
|
|||||||
import "maplibre-gl/dist/maplibre-gl.css";
|
import "maplibre-gl/dist/maplibre-gl.css";
|
||||||
import { schemeSet3 } from "d3-scale-chromatic";
|
import { schemeSet3 } from "d3-scale-chromatic";
|
||||||
import base_theme from "protomaps-themes-base";
|
import base_theme from "protomaps-themes-base";
|
||||||
|
import {
|
||||||
|
StyleSpecification,
|
||||||
|
LayerSpecification,
|
||||||
|
} from "@maplibre/maplibre-gl-style-spec";
|
||||||
|
|
||||||
const INITIAL_ZOOM = 0;
|
const INITIAL_ZOOM = 0;
|
||||||
const INITIAL_LNG = 0;
|
const INITIAL_LNG = 0;
|
||||||
const INITIAL_LAT = 0;
|
const INITIAL_LAT = 0;
|
||||||
|
const BASEMAP_URL =
|
||||||
|
"https://api.protomaps.com/tiles/v3/{z}/{x}/{y}.mvt?key=1003762824b9687f";
|
||||||
|
const BASEMAP_ATTRIBUTION =
|
||||||
|
'Basemap <a href="https://github.com/protomaps/basemaps">Protomaps</a> © <a href="https://openstreetmap.org">OpenStreetMap</a>';
|
||||||
|
|
||||||
maplibregl.setRTLTextPlugin(
|
maplibregl.setRTLTextPlugin(
|
||||||
"https://unpkg.com/@mapbox/mapbox-gl-rtl-text@0.2.3/mapbox-gl-rtl-text.min.js",
|
"https://unpkg.com/@mapbox/mapbox-gl-rtl-text@0.2.3/mapbox-gl-rtl-text.min.js",
|
||||||
@@ -169,14 +177,13 @@ const LayersVisibilityController = (props: {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const rasterStyle = async (file: PMTiles): Promise<any> => {
|
const rasterStyle = async (file: PMTiles): Promise<StyleSpecification> => {
|
||||||
let header = await file.getHeader();
|
let header = await file.getHeader();
|
||||||
let metadata = await file.getMetadata();
|
let metadata = await file.getMetadata();
|
||||||
let layers: any[] = [];
|
let layers: LayerSpecification[] = [];
|
||||||
|
|
||||||
if (metadata.type !== "baselayer") {
|
if (metadata.type !== "baselayer") {
|
||||||
layers = base_theme("basemap", "black");
|
layers = base_theme("basemap", "black");
|
||||||
layers[0].paint["background-color"] = "black";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
layers.push({
|
layers.push({
|
||||||
@@ -196,10 +203,9 @@ const rasterStyle = async (file: PMTiles): Promise<any> => {
|
|||||||
},
|
},
|
||||||
basemap: {
|
basemap: {
|
||||||
type: "vector",
|
type: "vector",
|
||||||
tiles: [
|
tiles: [BASEMAP_URL],
|
||||||
"https://api.protomaps.com/tiles/v3/{z}/{x}/{y}.mvt?key=1003762824b9687f",
|
maxzoom: 15,
|
||||||
],
|
attribution: BASEMAP_ATTRIBUTION,
|
||||||
maxzoom: 14,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
glyphs: "https://cdn.protomaps.com/fonts/pbf/{fontstack}/{range}.pbf",
|
glyphs: "https://cdn.protomaps.com/fonts/pbf/{fontstack}/{range}.pbf",
|
||||||
@@ -207,18 +213,24 @@ const rasterStyle = async (file: PMTiles): Promise<any> => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const vectorStyle = async (file: PMTiles): Promise<any> => {
|
const vectorStyle = async (
|
||||||
|
file: PMTiles
|
||||||
|
): Promise<{
|
||||||
|
style: StyleSpecification;
|
||||||
|
layersVisibility: LayerVisibility[];
|
||||||
|
}> => {
|
||||||
let header = await file.getHeader();
|
let header = await file.getHeader();
|
||||||
let metadata = await file.getMetadata();
|
let metadata = await file.getMetadata();
|
||||||
let layers: any[] = [];
|
let layers: LayerSpecification[] = [];
|
||||||
|
let baseOpacity = 0.35;
|
||||||
|
|
||||||
if (metadata.type !== "baselayer") {
|
if (metadata.type !== "baselayer") {
|
||||||
layers = base_theme("basemap", "black");
|
layers = base_theme("basemap", "black");
|
||||||
layers[0].paint["background-color"] = "black";
|
baseOpacity = 0.9;
|
||||||
}
|
}
|
||||||
|
|
||||||
var tilestats: any;
|
var tilestats: any;
|
||||||
var vector_layers: any;
|
var vector_layers: LayerSpecification[];
|
||||||
if (metadata.json) {
|
if (metadata.json) {
|
||||||
let j = JSON.parse(metadata.json);
|
let j = JSON.parse(metadata.json);
|
||||||
tilestats = j.tilestats;
|
tilestats = j.tilestats;
|
||||||
@@ -240,14 +252,14 @@ const vectorStyle = async (file: PMTiles): Promise<any> => {
|
|||||||
"fill-opacity": [
|
"fill-opacity": [
|
||||||
"case",
|
"case",
|
||||||
["boolean", ["feature-state", "hover"], false],
|
["boolean", ["feature-state", "hover"], false],
|
||||||
0.35,
|
baseOpacity,
|
||||||
0.2,
|
baseOpacity - 0.15,
|
||||||
],
|
],
|
||||||
"fill-outline-color": [
|
"fill-outline-color": [
|
||||||
"case",
|
"case",
|
||||||
["boolean", ["feature-state", "hover"], false],
|
["boolean", ["feature-state", "hover"], false],
|
||||||
"hsl(0,100%,90%)",
|
"hsl(0,100%,90%)",
|
||||||
"rgba(0,0,0,0)",
|
"rgba(0,0,0,0.2)",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
filter: ["==", ["geometry-type"], "Polygon"],
|
filter: ["==", ["geometry-type"], "Polygon"],
|
||||||
@@ -287,14 +299,12 @@ const vectorStyle = async (file: PMTiles): Promise<any> => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let layer of layers) {
|
const bounds: [number, number, number, number] = [
|
||||||
if (layer["source-layer"] === "mask" && layer["type"] === "fill") {
|
header.minLon,
|
||||||
layer.paint["fill-color"] = "black";
|
header.minLat,
|
||||||
layer.paint["fill-opacity"] = 0.8;
|
header.maxLon,
|
||||||
}
|
header.maxLat,
|
||||||
}
|
];
|
||||||
|
|
||||||
const bounds = [header.minLon, header.minLat, header.maxLon, header.maxLat];
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
style: {
|
style: {
|
||||||
@@ -309,17 +319,16 @@ const vectorStyle = async (file: PMTiles): Promise<any> => {
|
|||||||
},
|
},
|
||||||
basemap: {
|
basemap: {
|
||||||
type: "vector",
|
type: "vector",
|
||||||
tiles: [
|
tiles: [BASEMAP_URL],
|
||||||
"https://api.protomaps.com/tiles/v3/{z}/{x}/{y}.mvt?key=1003762824b9687f",
|
maxzoom: 15,
|
||||||
],
|
|
||||||
maxzoom: 14,
|
|
||||||
bounds: bounds,
|
bounds: bounds,
|
||||||
|
attribution: BASEMAP_ATTRIBUTION,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
glyphs: "https://cdn.protomaps.com/fonts/pbf/{fontstack}/{range}.pbf",
|
glyphs: "https://cdn.protomaps.com/fonts/pbf/{fontstack}/{range}.pbf",
|
||||||
layers: layers,
|
layers: layers,
|
||||||
},
|
},
|
||||||
layersVisibility: vector_layers.map((l: any) => ({
|
layersVisibility: vector_layers.map((l: LayerSpecification) => ({
|
||||||
id: l.id,
|
id: l.id,
|
||||||
visible: true,
|
visible: true,
|
||||||
})),
|
})),
|
||||||
@@ -455,7 +464,7 @@ function MaplibreMap(props: { file: PMTiles; mapHashPassed: boolean }) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let style: any; // TODO maplibre types (not any)
|
let style: StyleSpecification;
|
||||||
if (
|
if (
|
||||||
header.tileType === TileType.Png ||
|
header.tileType === TileType.Png ||
|
||||||
header.tileType === TileType.Webp ||
|
header.tileType === TileType.Webp ||
|
||||||
|
|||||||
Reference in New Issue
Block a user