diff --git a/app/index.html b/app/index.html
index 38f3861..b0fddd7 100644
--- a/app/index.html
+++ b/app/index.html
@@ -2,9 +2,9 @@
-
+
- Vite App
+ PMTiles Viewer
diff --git a/app/src/App.tsx b/app/src/App.tsx
index 87f6fc3..fee4008 100644
--- a/app/src/App.tsx
+++ b/app/src/App.tsx
@@ -2,15 +2,13 @@ import { useState, useEffect } from "react";
import { styled, globalStyles } from "./stitches.config";
import Start from "./Start";
-import Inspector from "./Inspector";
-import LeafletMap from "./LeafletMap";
-import MaplibreMap from "./MaplibreMap";
+import Loader from "./Loader";
const Header = styled("div", {
height: "$4",
});
-const GIT_SHA = import.meta.env.VITE_GIT_SHA.substr(0,8)
+const GIT_SHA = (import.meta.env.VITE_GIT_SHA || "").substr(0,8)
function App() {
globalStyles();
@@ -30,7 +28,7 @@ function App() {
return (
pmtiles viewer | github | toggle | {GIT_SHA}
- {file ? : }
+ {file ? : }
);
}
diff --git a/app/src/Inspector.tsx b/app/src/Inspector.tsx
index ed8d352..3623dff 100644
--- a/app/src/Inspector.tsx
+++ b/app/src/Inspector.tsx
@@ -2,7 +2,7 @@ import { useState } from "react";
import { PMTiles } from "../../js";
import { styled } from "./stitches.config";
-function Inspector() {
+function Inspector(props:{file:string}) {
return (
<>
foo
diff --git a/app/src/LeafletMap.tsx b/app/src/LeafletMap.tsx
index c5dc9b8..3b25692 100644
--- a/app/src/LeafletMap.tsx
+++ b/app/src/LeafletMap.tsx
@@ -8,7 +8,7 @@ const MapContainer = styled("div", {
height: "calc(100vh - $4)",
});
-function LeafletMap(props:{file:string}) {
+function LeafletMap(props:{file:string, tileType: string | null}) {
const p = new PMTiles(
"https://protomaps-static.sfo3.digitaloceanspaces.com/osm_carto.pmtiles"
);
diff --git a/app/src/Loader.tsx b/app/src/Loader.tsx
new file mode 100644
index 0000000..7b772e8
--- /dev/null
+++ b/app/src/Loader.tsx
@@ -0,0 +1,55 @@
+import { useState, useEffect } from "react";
+import { PMTiles } from "../../js";
+import { styled } from "./stitches.config";
+
+import Inspector from "./Inspector";
+import LeafletMap from "./LeafletMap";
+import MaplibreMap from "./MaplibreMap";
+
+function Loader(props: { file: string }) {
+ let [tab, setTab] = useState("maplibre");
+ let [tileType, setTileType] = useState(null);
+
+ let view;
+ if (tab === "leaflet") {
+ view = ;
+ } else if (tab === "maplibre") {
+ view = ;
+ } else {
+ view = ;
+ }
+
+ useEffect(() => {
+ let pmtiles = new PMTiles(props.file);
+ const fetchData = async () => {
+ let metadata = await pmtiles.metadata();
+
+ let resp = await fetch(props.file, {
+ headers: { Range: "bytes=512000-512003" },
+ });
+ let magic = new DataView(await resp.arrayBuffer());
+ let b0 = magic.getUint8(0);
+ let b1 = magic.getUint8(1);
+ let b2 = magic.getUint8(2);
+ let b3 = magic.getUint8(3);
+
+ if (b0 == 0x89 && b1 == 0x50 && b2 == 0x4e && b3 == 0x47) {
+ setTileType("png");
+ } else if (b0 == 0xff && b1 == 0xd8 && b2 == 0xff && b3 == 0xe0) {
+ setTileType("jpg")
+ } else if (b0 == 0x1f && b1 == 0x8b) {
+ setTileType("mvt.gz");
+ } else {
+ setTileType("mvt");
+ }
+ };
+ fetchData();
+ }, [props.file]);
+
+ return <>
+ {props.file} | {tileType}
+ {view}
+ >;
+}
+
+export default Loader;
diff --git a/app/src/MaplibreMap.tsx b/app/src/MaplibreMap.tsx
index bc80511..2e66853 100644
--- a/app/src/MaplibreMap.tsx
+++ b/app/src/MaplibreMap.tsx
@@ -1,58 +1,87 @@
-import { useState, useEffect } from "react";
+import { useState, useEffect, useRef } from "react";
import { PMTiles, ProtocolCache } from "../../js";
import { styled } from "./stitches.config";
import maplibregl from "maplibre-gl";
-import "maplibre-gl/dist/maplibre-gl.css"
+import "maplibre-gl/dist/maplibre-gl.css";
const MapContainer = styled("div", {
height: "calc(100vh - $4)",
});
-function MaplibreMap(props:{file:string}) {
- let cache = new ProtocolCache();
- maplibregl.addProtocol("pmtiles",cache.protocol);
-
- var style = {
- "version": 8,
- "sources": {
- "zcta": {
- "type": "vector",
- "tiles": ["pmtiles://" + props.file + "/{z}/{x}/{y}"],
- "maxzoom":7
- }
+const rasterStyle = (file:string) => {
+ return {
+ version: 8,
+ sources: {
+ source: {
+ type: "raster",
+ tiles: ["pmtiles://" + file + "/{z}/{x}/{y}"],
+ maxzoom:4
},
- "layers": [
- {
- "id": "zcta_fill",
- "type": "fill",
- "source":"zcta",
- "source-layer":"zcta",
- "paint": {
- "fill-color":"white"
- }
- },
- {
- "id": "zcta_stroke",
- "type": "line",
- "source":"zcta",
- "source-layer":"zcta",
- "paint": {
- "line-color":"steelblue",
- "line-width":0.5
- }
- }
- ]
- }
+ },
+ layers: [
+ {
+ id: "raster",
+ type: "raster",
+ source: "source"
+ },
+ ],
+ };
+};
+const vectorStyle = (file:string) => {
+ return {
+ version: 8,
+ sources: {
+ source: {
+ type: "vector",
+ tiles: ["pmtiles://" + file + "/{z}/{x}/{y}"],
+ maxzoom: 7,
+ },
+ },
+ layers: [
+ {
+ id: "zcta_fill",
+ type: "fill",
+ source: "source",
+ "source-layer": "zcta",
+ paint: {
+ "fill-color": "white",
+ },
+ },
+ {
+ id: "zcta_stroke",
+ type: "line",
+ source: "source",
+ "source-layer": "zcta",
+ paint: {
+ "line-color": "steelblue",
+ "line-width": 0.5,
+ },
+ },
+ ],
+ };
+};
+
+function MaplibreMap(props: { file: string, tileType: string | null }) {
+ let mapRef = useRef(null);
useEffect(() => {
- const map = new maplibregl.Map({container:"map",zoom:3,center:[-101.43,44.34],style:style as any}); // TODO maplibre types
+ let cache = new ProtocolCache();
+ maplibregl.addProtocol("pmtiles", cache.protocol);
+
+ const map = new maplibregl.Map({
+ container: "map",
+ zoom: 0,
+ center: [0, 0],
+ style: rasterStyle(props.file) as any,
+ }); // TODO maplibre types (not any)
+ map.on("load", map.resize);
return () => {
map.remove();
};
}, []);
- return ;
+ return ;
}
export default MaplibreMap;