From 2ac1ad17767a65a6121e5e5572045980a5174006 Mon Sep 17 00:00:00 2001 From: Brandon Liu Date: Wed, 4 Jan 2023 16:35:29 +0800 Subject: [PATCH] inspector: toggle maplibre options in menu [#49] --- app/src/MaplibreMap.tsx | 101 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 94 insertions(+), 7 deletions(-) diff --git a/app/src/MaplibreMap.tsx b/app/src/MaplibreMap.tsx index 68e64132..9f114350 100644 --- a/app/src/MaplibreMap.tsx +++ b/app/src/MaplibreMap.tsx @@ -18,6 +18,29 @@ const PopupContainer = styled("div", { const FeatureRow = styled("div", { marginBottom: "0.5em", + "&:not(:last-of-type)": { + borderBottom: "1px solid black", + }, +}); + +const Hamburger = styled("div", { + position: "absolute", + top: "10px", + right: "10px", + width: 40, + height: 40, + backgroundColor: "#444", + cursor: "pointer", + zIndex: 9999, +}); + +const Options = styled("div", { + position: "absolute", + backgroundColor: "#444", + top: "50px", + right: "10px", + padding: "$1", + zIndex: 9999, }); const FeaturesProperties = (props: { features: MapGeoJSONFeature[] }) => { @@ -36,7 +59,9 @@ const FeaturesProperties = (props: { features: MapGeoJSONFeature[] }) => { return ( -
{(f.layer as any)["source-layer"]}
+
+ {(f.layer as any)["source-layer"]} +
{rows}
); @@ -116,6 +141,7 @@ const vectorStyle = async (file: PMTiles): Promise => { }); } } else if (tilestats) { + // TODO deprecate me... for (let [i, layer] of tilestats.layers.entries()) { if (layer.geometry === "Polygon") { layers.push({ @@ -153,6 +179,13 @@ const vectorStyle = async (file: PMTiles): Promise => { } } + for (let layer of layers) { + if (layer["source-layer"] == "mask") { + layer.paint["fill-color"] = "black"; + layer.paint["fill-opacity"] = 0.8; + } + } + return { version: 8, sources: { @@ -169,14 +202,36 @@ const vectorStyle = async (file: PMTiles): Promise => { function MaplibreMap(props: { file: PMTiles }) { let mapContainerRef = useRef(null); - let map: maplibregl.Map; + let [hamburgerOpen, setHamburgerOpen] = useState(true); + let [showAttributes, setShowAttributes] = useState(false); + let [showTileBoundaries, setShowTileBoundaries] = useState(false); + const mapRef = useRef(null); + + // make it accessible in hook + const showAttributesRef = useRef(showAttributes); + useEffect(() => { + showAttributesRef.current = showAttributes; + }); + + const toggleHamburger = () => { + setHamburgerOpen(!hamburgerOpen); + }; + + const toggleShowAttributes = () => { + setShowAttributes(!showAttributes); + }; + + const toggleShowTileBoundaries = () => { + setShowTileBoundaries(!showTileBoundaries); + mapRef.current!.showTileBoundaries = !showTileBoundaries; + }; useEffect(() => { let protocol = new Protocol(); maplibregl.addProtocol("pmtiles", protocol.tile); protocol.add(props.file); // this is necessary for non-HTTP sources - map = new maplibregl.Map({ + const map = new maplibregl.Map({ container: mapContainerRef.current!, hash: "map", zoom: 0, @@ -187,8 +242,7 @@ function MaplibreMap(props: { file: PMTiles }) { layers: [], }, }); - map.showTileBoundaries = true; - map.addControl(new maplibregl.NavigationControl({})); + map.addControl(new maplibregl.NavigationControl({}), "bottom-left"); map.on("load", map.resize); const popup = new maplibregl.Popup({ @@ -196,7 +250,13 @@ function MaplibreMap(props: { file: PMTiles }) { closeOnClick: false, }); + mapRef.current = map; + map.on("mousemove", (e) => { + if (!showAttributesRef.current) { + popup.remove(); + return; + } var bbox = e.point; var features = map.queryRenderedFeatures(bbox); map.getCanvas().style.cursor = features.length ? "pointer" : ""; @@ -218,7 +278,8 @@ function MaplibreMap(props: { file: PMTiles }) { useEffect(() => { let initStyle = async () => { - if (map) { + if (mapRef.current) { + let map = mapRef.current; let header = await props.file.getHeader(); map.fitBounds( @@ -245,7 +306,33 @@ function MaplibreMap(props: { file: PMTiles }) { initStyle(); }, []); - return ; + return ( + +
+ menu + {hamburgerOpen ? ( + +

Filter

+

Popup

+ + +

Tiles

+ + +
+ ) : null} +
+ ); } export default MaplibreMap;