aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--components/map.tsx53
-rw-r--r--package-lock.json16
-rw-r--r--package.json1
-rw-r--r--public/natural-earth.pmtilesbin0 -> 104266420 bytes
-rw-r--r--public/style-dark.json187
-rw-r--r--public/style-light.json187
6 files changed, 415 insertions, 29 deletions
diff --git a/components/map.tsx b/components/map.tsx
index 5a17d9d..a3ba8e4 100644
--- a/components/map.tsx
+++ b/components/map.tsx
@@ -1,12 +1,26 @@
-
-"use client"
+"use client";
import { useRef } from 'react';
import MapGL, { Marker, MapRef } from 'react-map-gl/maplibre';
-import maplibregl from 'maplibre-gl';
+import maplibregl, { type StyleSpecification } from 'maplibre-gl';
import 'maplibre-gl/dist/maplibre-gl.css';
+import { Protocol } from 'pmtiles';
+
+import styleDark from '@/public/style-dark.json';
-const KARLSRUHE: { longitude: number, latitude: number } = { longitude: 8.4037, latitude: 49.0069 };
+const KARLSRUHE = { longitude: 8.4037, latitude: 49.0069 };
+const mapStyle = styleDark as unknown as StyleSpecification;
+
+if (typeof window !== 'undefined') {
+ const globalForProtocol = globalThis as typeof globalThis & {
+ __maplibrePmtilesProtocol?: Protocol;
+ };
+
+ if (!globalForProtocol.__maplibrePmtilesProtocol) {
+ globalForProtocol.__maplibrePmtilesProtocol = new Protocol({ metadata: true });
+ maplibregl.addProtocol('pmtiles', globalForProtocol.__maplibrePmtilesProtocol.tile);
+ }
+}
export default function Map() {
const mapRef = useRef<MapRef>(null);
@@ -14,8 +28,8 @@ export default function Map() {
const onMapLoad = () => {
mapRef.current?.flyTo({
center: [KARLSRUHE.longitude, KARLSRUHE.latitude],
- zoom: 10,
- speed: 0.5,
+ zoom: 8,
+ speed: 0.8,
curve: 1,
essential: true
});
@@ -36,33 +50,14 @@ export default function Map() {
initialViewState={{
longitude: KARLSRUHE.longitude,
latitude: KARLSRUHE.latitude,
- zoom: 2
+ zoom: 3
}}
style={{ width: "100%", height: "100%" }}
- mapStyle={{
- version: 8,
- sources: {
- "carto-dark": {
- type: "raster",
- tiles: ["https://a.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png"],
- tileSize: 256,
- attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>, &copy; <a href="https://carto.com/attributions">CARTO</a>',
- },
- },
- layers: [
- {
- id: "carto-dark-layer",
- type: "raster",
- source: "carto-dark",
- minzoom: 0,
- maxzoom: 22,
- },
- ],
- }}
+ mapStyle={mapStyle}
attributionControl={false}
>
- <Marker longitude={KARLSRUHE.longitude} latitude={KARLSRUHE.latitude} color="red">
- <div style={{width:'12px',height:'12px',background:'var(--background)',borderRadius:'50%',border:'2px solid var(--foreground)',boxShadow:'0 0 10px rgba(0,0,0,0.5)'}} />
+ <Marker longitude={KARLSRUHE.longitude} latitude={KARLSRUHE.latitude}>
+ <div className="h-3 w-3 rounded-full border-2 border-foreground bg-background shadow-[0_0_10px_rgba(0,0,0,0.5)]" />
</Marker>
</MapGL>
</div>
diff --git a/package-lock.json b/package-lock.json
index a888705..1936fc2 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -19,6 +19,7 @@
"next-contentlayer2": "^0.5.8",
"next-plausible": "^3.12.5",
"next-themes": "^0.4.6",
+ "pmtiles": "^4.3.2",
"react": "19.2.3",
"react-dom": "19.2.3",
"react-map-gl": "^8.1.0",
@@ -5695,6 +5696,12 @@
"url": "https://github.com/sponsors/wooorm"
}
},
+ "node_modules/fflate": {
+ "version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz",
+ "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==",
+ "license": "MIT"
+ },
"node_modules/file-entry-cache": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz",
@@ -9053,6 +9060,15 @@
"url": "https://github.com/sponsors/jonschlinkert"
}
},
+ "node_modules/pmtiles": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/pmtiles/-/pmtiles-4.3.2.tgz",
+ "integrity": "sha512-Ath2F2U2E37QyNXjN1HOF+oLiNIbdrDYrk/K3C9K4Pgw2anwQX10y4WYWEH9O75vPiu0gBbSWIAbSG19svyvZg==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "fflate": "^0.8.2"
+ }
+ },
"node_modules/possible-typed-array-names": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz",
diff --git a/package.json b/package.json
index c991444..feb6dd9 100644
--- a/package.json
+++ b/package.json
@@ -20,6 +20,7 @@
"next-contentlayer2": "^0.5.8",
"next-plausible": "^3.12.5",
"next-themes": "^0.4.6",
+ "pmtiles": "^4.3.2",
"react": "19.2.3",
"react-dom": "19.2.3",
"react-map-gl": "^8.1.0",
diff --git a/public/natural-earth.pmtiles b/public/natural-earth.pmtiles
new file mode 100644
index 0000000..c5c2a63
--- /dev/null
+++ b/public/natural-earth.pmtiles
Binary files differ
diff --git a/public/style-dark.json b/public/style-dark.json
new file mode 100644
index 0000000..1c8494b
--- /dev/null
+++ b/public/style-dark.json
@@ -0,0 +1,187 @@
+{
+ "version": 8,
+ "name": "Natural Earth (shadcn dark)",
+ "glyphs": "https://demotiles.maplibre.org/font/{fontstack}/{range}.pbf",
+ "sources": {
+ "ne": {
+ "type": "vector",
+ "url": "pmtiles:///natural-earth.pmtiles",
+ "attribution": "Natural Earth"
+ }
+ },
+ "layers": [
+ {
+ "id": "background",
+ "type": "background",
+ "paint": {
+ "background-color": "#000000"
+ }
+ },
+ {
+ "id": "countries-fill",
+ "type": "fill",
+ "source": "ne",
+ "source-layer": "ne_10m_admin_0_countries",
+ "paint": {
+ "fill-color": "#0f0f10",
+ "fill-opacity": 1
+ }
+ },
+ {
+ "id": "countries-outline",
+ "type": "line",
+ "source": "ne",
+ "source-layer": "ne_10m_admin_0_boundary_lines_land",
+ "paint": {
+ "line-color": "#2a2a2e",
+ "line-opacity": 0.8,
+ "line-width": ["interpolate", ["linear"], ["zoom"], 0, 0.35, 3, 0.7, 6, 1.1, 8, 1.6]
+ }
+ },
+ {
+ "id": "country-labels-major",
+ "type": "symbol",
+ "source": "ne",
+ "source-layer": "ne_10m_admin_0_countries",
+ "minzoom": 0,
+ "maxzoom": 4,
+ "filter": ["<=", ["get", "SCALERANK"], ["step", ["zoom"], 2, 1, 3, 2, 4, 3, 5]],
+ "layout": {
+ "text-field": ["coalesce", ["get", "NAME_EN"], ["get", "NAME"]],
+ "text-font": ["Noto Sans Regular"],
+ "text-transform": "uppercase",
+ "text-letter-spacing": 0.08,
+ "text-size": ["interpolate", ["linear"], ["zoom"], 0, 10, 2, 12, 4, 14],
+ "symbol-placement": "point",
+ "text-allow-overlap": false
+ },
+ "paint": {
+ "text-color": "#d6d6d6",
+ "text-halo-color": "#000000",
+ "text-halo-width": 1.4,
+ "text-opacity": 0.9
+ }
+ },
+ {
+ "id": "country-labels-minor",
+ "type": "symbol",
+ "source": "ne",
+ "source-layer": "ne_10m_admin_0_countries",
+ "minzoom": 2,
+ "filter": ["<=", ["get", "SCALERANK"], ["step", ["zoom"], 3, 3, 5, 4, 7, 5, 9]],
+ "layout": {
+ "text-field": ["coalesce", ["get", "NAME_EN"], ["get", "NAME"]],
+ "text-font": ["Noto Sans Regular"],
+ "text-size": ["interpolate", ["linear"], ["zoom"], 2, 9, 4, 11, 6, 12],
+ "symbol-placement": "point",
+ "text-allow-overlap": false
+ },
+ "paint": {
+ "text-color": "#b7b7b7",
+ "text-halo-color": "#000000",
+ "text-halo-width": 1.25,
+ "text-opacity": 0.85
+ }
+ },
+ {
+ "id": "continents",
+ "type": "symbol",
+ "source": "ne",
+ "source-layer": "continents",
+ "minzoom": 0,
+ "maxzoom": 3,
+ "layout": {
+ "text-field": ["get", "NAME"],
+ "text-font": ["Noto Sans Regular"],
+ "text-transform": "uppercase",
+ "text-letter-spacing": 0.14,
+ "text-size": ["interpolate", ["linear"], ["zoom"], 0, 12, 1, 14, 2, 16, 3, 18],
+ "text-allow-overlap": true,
+ "text-ignore-placement": true
+ },
+ "paint": {
+ "text-color": "#8a8a90",
+ "text-halo-color": "#000000",
+ "text-halo-width": 1.8,
+ "text-opacity": ["interpolate", ["linear"], ["zoom"], 0, 0.65, 1, 0.7, 2, 0.45, 3, 0]
+ }
+ },
+ {
+ "id": "capitals",
+ "type": "symbol",
+ "source": "ne",
+ "source-layer": "ne_10m_capitals",
+ "minzoom": 1.5,
+ "layout": {
+ "text-field": ["coalesce", ["get", "NAME_EN"], ["get", "NAME"], ["get", "NAMEASCII"]],
+ "text-font": ["Noto Sans Regular"],
+ "text-size": ["interpolate", ["linear"], ["zoom"], 0, 11, 2, 12, 4, 14, 8, 16],
+ "text-anchor": "top",
+ "text-offset": [0, 0.6],
+ "symbol-sort-key": 30,
+ "text-allow-overlap": false
+ },
+ "paint": {
+ "text-color": "#ffffff",
+ "text-halo-color": "#000000",
+ "text-halo-width": 1.4,
+ "text-opacity": ["interpolate", ["linear"], ["zoom"], 1.5, 0, 2, 0.98, 8, 0.98]
+ }
+ },
+ {
+ "id": "roads",
+ "type": "line",
+ "source": "ne",
+ "source-layer": "ne_10m_roads",
+ "minzoom": 4,
+ "paint": {
+ "line-color": "#ffffff",
+ "line-opacity": ["interpolate", ["linear"], ["zoom"], 3.9, 0, 4, 0, 4.5, 0.25, 5, 0.55, 8, 0.55],
+ "line-width": ["interpolate", ["linear"], ["zoom"], 4, 0.2, 6, 0.7, 8, 1.8]
+ }
+ },
+ {
+ "id": "railroads",
+ "type": "line",
+ "source": "ne",
+ "source-layer": "ne_10m_railroads",
+ "minzoom": 4,
+ "paint": {
+ "line-color": "#b3b3b3",
+ "line-opacity": ["interpolate", ["linear"], ["zoom"], 3.9, 0, 4, 0, 4.5, 0.2, 5, 0.45, 8, 0.45],
+ "line-width": ["interpolate", ["linear"], ["zoom"], 4, 0.15, 6, 0.5, 8, 1.2],
+ "line-dasharray": [2, 2]
+ }
+ },
+ {
+ "id": "places",
+ "type": "symbol",
+ "source": "ne",
+ "source-layer": "ne_10m_populated_places",
+ "minzoom": 2,
+ "filter": [
+ "all",
+ ["!=", ["get", "ADM0CAP"], 1],
+ [
+ "<=",
+ ["get", "SCALERANK"],
+ ["step", ["zoom"], 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8]
+ ]
+ ],
+ "layout": {
+ "text-field": ["coalesce", ["get", "NAME"], ["get", "NAME_EN"], ["get", "NAMEASCII"]],
+ "text-font": ["Noto Sans Regular"],
+ "text-size": ["interpolate", ["linear"], ["zoom"], 2, 10, 4, 12, 8, 15],
+ "text-anchor": "top",
+ "text-offset": [0, 0.6],
+ "text-allow-overlap": false
+ },
+ "paint": {
+ "text-color": "#ffffff",
+ "text-halo-color": "#000000",
+ "text-halo-width": 1.25,
+ "text-opacity": ["interpolate", ["linear"], ["zoom"], 2, 0, 2.5, 0.35, 3, 0.95, 8, 0.95]
+ }
+ }
+ ]
+}
diff --git a/public/style-light.json b/public/style-light.json
new file mode 100644
index 0000000..676a214
--- /dev/null
+++ b/public/style-light.json
@@ -0,0 +1,187 @@
+{
+ "version": 8,
+ "name": "Natural Earth (shadcn light)",
+ "glyphs": "https://demotiles.maplibre.org/font/{fontstack}/{range}.pbf",
+ "sources": {
+ "ne": {
+ "type": "vector",
+ "url": "pmtiles://build/all.pmtiles",
+ "attribution": "Natural Earth"
+ }
+ },
+ "layers": [
+ {
+ "id": "background",
+ "type": "background",
+ "paint": {
+ "background-color": "#ffffff"
+ }
+ },
+ {
+ "id": "countries-fill",
+ "type": "fill",
+ "source": "ne",
+ "source-layer": "ne_10m_admin_0_countries",
+ "paint": {
+ "fill-color": "#ffffff",
+ "fill-opacity": 1
+ }
+ },
+ {
+ "id": "countries-outline",
+ "type": "line",
+ "source": "ne",
+ "source-layer": "ne_10m_admin_0_boundary_lines_land",
+ "paint": {
+ "line-color": "#cfcfd4",
+ "line-opacity": 1,
+ "line-width": ["interpolate", ["linear"], ["zoom"], 0, 0.35, 3, 0.7, 6, 1.1, 8, 1.6]
+ }
+ },
+ {
+ "id": "country-labels-major",
+ "type": "symbol",
+ "source": "ne",
+ "source-layer": "ne_10m_admin_0_countries",
+ "minzoom": 0,
+ "maxzoom": 4,
+ "filter": ["<=", ["get", "SCALERANK"], ["step", ["zoom"], 2, 1, 3, 2, 4, 3, 5]],
+ "layout": {
+ "text-field": ["coalesce", ["get", "NAME_EN"], ["get", "NAME"]],
+ "text-font": ["Noto Sans Regular"],
+ "text-transform": "uppercase",
+ "text-letter-spacing": 0.08,
+ "text-size": ["interpolate", ["linear"], ["zoom"], 0, 10, 2, 12, 4, 14],
+ "symbol-placement": "point",
+ "text-allow-overlap": false
+ },
+ "paint": {
+ "text-color": "#2a2a2e",
+ "text-halo-color": "#ffffff",
+ "text-halo-width": 1.4,
+ "text-opacity": 0.85
+ }
+ },
+ {
+ "id": "country-labels-minor",
+ "type": "symbol",
+ "source": "ne",
+ "source-layer": "ne_10m_admin_0_countries",
+ "minzoom": 2,
+ "filter": ["<=", ["get", "SCALERANK"], ["step", ["zoom"], 3, 3, 5, 4, 7, 5, 9]],
+ "layout": {
+ "text-field": ["coalesce", ["get", "NAME_EN"], ["get", "NAME"]],
+ "text-font": ["Noto Sans Regular"],
+ "text-size": ["interpolate", ["linear"], ["zoom"], 2, 9, 4, 11, 6, 12],
+ "symbol-placement": "point",
+ "text-allow-overlap": false
+ },
+ "paint": {
+ "text-color": "#4a4a4f",
+ "text-halo-color": "#ffffff",
+ "text-halo-width": 1.25,
+ "text-opacity": 0.8
+ }
+ },
+ {
+ "id": "continents",
+ "type": "symbol",
+ "source": "ne",
+ "source-layer": "continents",
+ "minzoom": 0,
+ "maxzoom": 3,
+ "layout": {
+ "text-field": ["get", "NAME"],
+ "text-font": ["Noto Sans Regular"],
+ "text-transform": "uppercase",
+ "text-letter-spacing": 0.14,
+ "text-size": ["interpolate", ["linear"], ["zoom"], 0, 12, 1, 14, 2, 16, 3, 18],
+ "text-allow-overlap": true,
+ "text-ignore-placement": true
+ },
+ "paint": {
+ "text-color": "#6a6a70",
+ "text-halo-color": "#ffffff",
+ "text-halo-width": 1.8,
+ "text-opacity": ["interpolate", ["linear"], ["zoom"], 0, 0.55, 1, 0.6, 2, 0.4, 3, 0]
+ }
+ },
+ {
+ "id": "capitals",
+ "type": "symbol",
+ "source": "ne",
+ "source-layer": "ne_10m_capitals",
+ "minzoom": 1.5,
+ "layout": {
+ "text-field": ["coalesce", ["get", "NAME_EN"], ["get", "NAME"], ["get", "NAMEASCII"]],
+ "text-font": ["Noto Sans Regular"],
+ "text-size": ["interpolate", ["linear"], ["zoom"], 0, 11, 2, 12, 4, 14, 8, 16],
+ "text-anchor": "top",
+ "text-offset": [0, 0.6],
+ "symbol-sort-key": 30,
+ "text-allow-overlap": false
+ },
+ "paint": {
+ "text-color": "#000000",
+ "text-halo-color": "#ffffff",
+ "text-halo-width": 1.4,
+ "text-opacity": ["interpolate", ["linear"], ["zoom"], 1.5, 0, 2, 0.95, 8, 0.95]
+ }
+ },
+ {
+ "id": "roads",
+ "type": "line",
+ "source": "ne",
+ "source-layer": "ne_10m_roads",
+ "minzoom": 4,
+ "paint": {
+ "line-color": "#111111",
+ "line-opacity": ["interpolate", ["linear"], ["zoom"], 3.9, 0, 4, 0, 4.5, 0.25, 5, 0.55, 8, 0.55],
+ "line-width": ["interpolate", ["linear"], ["zoom"], 4, 0.2, 6, 0.7, 8, 1.8]
+ }
+ },
+ {
+ "id": "railroads",
+ "type": "line",
+ "source": "ne",
+ "source-layer": "ne_10m_railroads",
+ "minzoom": 4,
+ "paint": {
+ "line-color": "#6b6b6b",
+ "line-opacity": ["interpolate", ["linear"], ["zoom"], 3.9, 0, 4, 0, 4.5, 0.2, 5, 0.45, 8, 0.45],
+ "line-width": ["interpolate", ["linear"], ["zoom"], 4, 0.15, 6, 0.5, 8, 1.2],
+ "line-dasharray": [2, 2]
+ }
+ },
+ {
+ "id": "places",
+ "type": "symbol",
+ "source": "ne",
+ "source-layer": "ne_10m_populated_places",
+ "minzoom": 2,
+ "filter": [
+ "all",
+ ["!=", ["get", "ADM0CAP"], 1],
+ [
+ "<=",
+ ["get", "SCALERANK"],
+ ["step", ["zoom"], 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8]
+ ]
+ ],
+ "layout": {
+ "text-field": ["coalesce", ["get", "NAME"], ["get", "NAME_EN"], ["get", "NAMEASCII"]],
+ "text-font": ["Noto Sans Regular"],
+ "text-size": ["interpolate", ["linear"], ["zoom"], 2, 10, 4, 12, 8, 15],
+ "text-anchor": "top",
+ "text-offset": [0, 0.6],
+ "text-allow-overlap": false
+ },
+ "paint": {
+ "text-color": "#000000",
+ "text-halo-color": "#ffffff",
+ "text-halo-width": 1.25,
+ "text-opacity": ["interpolate", ["linear"], ["zoom"], 2, 0, 2.5, 0.35, 3, 0.95, 8, 0.95]
+ }
+ }
+ ]
+}