inspector: toggle maplibre options in menu [#49]

This commit is contained in:
Brandon Liu
2023-01-04 16:35:29 +08:00
parent 87c395073e
commit 2ac1ad1776

View File

@@ -18,6 +18,29 @@ const PopupContainer = styled("div", {
const FeatureRow = styled("div", { const FeatureRow = styled("div", {
marginBottom: "0.5em", 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[] }) => { const FeaturesProperties = (props: { features: MapGeoJSONFeature[] }) => {
@@ -36,7 +59,9 @@ const FeaturesProperties = (props: { features: MapGeoJSONFeature[] }) => {
return ( return (
<FeatureRow key={i}> <FeatureRow key={i}>
<div>{(f.layer as any)["source-layer"]}</div> <div>
<strong>{(f.layer as any)["source-layer"]}</strong>
</div>
<table>{rows}</table> <table>{rows}</table>
</FeatureRow> </FeatureRow>
); );
@@ -116,6 +141,7 @@ const vectorStyle = async (file: PMTiles): Promise<any> => {
}); });
} }
} else if (tilestats) { } else if (tilestats) {
// TODO deprecate me...
for (let [i, layer] of tilestats.layers.entries()) { for (let [i, layer] of tilestats.layers.entries()) {
if (layer.geometry === "Polygon") { if (layer.geometry === "Polygon") {
layers.push({ layers.push({
@@ -153,6 +179,13 @@ const vectorStyle = async (file: PMTiles): Promise<any> => {
} }
} }
for (let layer of layers) {
if (layer["source-layer"] == "mask") {
layer.paint["fill-color"] = "black";
layer.paint["fill-opacity"] = 0.8;
}
}
return { return {
version: 8, version: 8,
sources: { sources: {
@@ -169,14 +202,36 @@ const vectorStyle = async (file: PMTiles): Promise<any> => {
function MaplibreMap(props: { file: PMTiles }) { function MaplibreMap(props: { file: PMTiles }) {
let mapContainerRef = useRef<HTMLDivElement>(null); let mapContainerRef = useRef<HTMLDivElement>(null);
let map: maplibregl.Map; let [hamburgerOpen, setHamburgerOpen] = useState<boolean>(true);
let [showAttributes, setShowAttributes] = useState<boolean>(false);
let [showTileBoundaries, setShowTileBoundaries] = useState<boolean>(false);
const mapRef = useRef<maplibregl.Map | null>(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(() => { useEffect(() => {
let protocol = new Protocol(); let protocol = new Protocol();
maplibregl.addProtocol("pmtiles", protocol.tile); maplibregl.addProtocol("pmtiles", protocol.tile);
protocol.add(props.file); // this is necessary for non-HTTP sources protocol.add(props.file); // this is necessary for non-HTTP sources
map = new maplibregl.Map({ const map = new maplibregl.Map({
container: mapContainerRef.current!, container: mapContainerRef.current!,
hash: "map", hash: "map",
zoom: 0, zoom: 0,
@@ -187,8 +242,7 @@ function MaplibreMap(props: { file: PMTiles }) {
layers: [], layers: [],
}, },
}); });
map.showTileBoundaries = true; map.addControl(new maplibregl.NavigationControl({}), "bottom-left");
map.addControl(new maplibregl.NavigationControl({}));
map.on("load", map.resize); map.on("load", map.resize);
const popup = new maplibregl.Popup({ const popup = new maplibregl.Popup({
@@ -196,7 +250,13 @@ function MaplibreMap(props: { file: PMTiles }) {
closeOnClick: false, closeOnClick: false,
}); });
mapRef.current = map;
map.on("mousemove", (e) => { map.on("mousemove", (e) => {
if (!showAttributesRef.current) {
popup.remove();
return;
}
var bbox = e.point; var bbox = e.point;
var features = map.queryRenderedFeatures(bbox); var features = map.queryRenderedFeatures(bbox);
map.getCanvas().style.cursor = features.length ? "pointer" : ""; map.getCanvas().style.cursor = features.length ? "pointer" : "";
@@ -218,7 +278,8 @@ function MaplibreMap(props: { file: PMTiles }) {
useEffect(() => { useEffect(() => {
let initStyle = async () => { let initStyle = async () => {
if (map) { if (mapRef.current) {
let map = mapRef.current;
let header = await props.file.getHeader(); let header = await props.file.getHeader();
map.fitBounds( map.fitBounds(
@@ -245,7 +306,33 @@ function MaplibreMap(props: { file: PMTiles }) {
initStyle(); initStyle();
}, []); }, []);
return <MapContainer ref={mapContainerRef}></MapContainer>; return (
<MapContainer ref={mapContainerRef}>
<div ref={mapContainerRef}></div>
<Hamburger onClick={toggleHamburger}>menu</Hamburger>
{hamburgerOpen ? (
<Options>
<h4>Filter</h4>
<h4>Popup</h4>
<input
type="checkbox"
id="showAttributes"
checked={showAttributes}
onChange={toggleShowAttributes}
/>
<label htmlFor="showAttributes">show attributes</label>
<h4>Tiles</h4>
<input
type="checkbox"
id="showTileBoundaries"
checked={showTileBoundaries}
onChange={toggleShowTileBoundaries}
/>
<label htmlFor="showTileBoundaries">show tile boundaries</label>
</Options>
) : null}
</MapContainer>
);
} }
export default MaplibreMap; export default MaplibreMap;