diff --git a/app/src/MaplibreMap.tsx b/app/src/MaplibreMap.tsx
index 090c103..68e6413 100644
--- a/app/src/MaplibreMap.tsx
+++ b/app/src/MaplibreMap.tsx
@@ -1,8 +1,10 @@
import { useState, useEffect, useRef } from "react";
+import { renderToString } from "react-dom/server";
import { PMTiles, TileType } from "../../js/index";
import { Protocol } from "../../js/adapters";
import { styled } from "./stitches.config";
import maplibregl from "maplibre-gl";
+import { MapGeoJSONFeature } from "maplibre-gl";
import "maplibre-gl/dist/maplibre-gl.css";
import { schemeSet3 } from "d3-scale-chromatic";
@@ -10,6 +12,38 @@ const MapContainer = styled("div", {
height: "calc(100vh - $4 - $4)",
});
+const PopupContainer = styled("div", {
+ color: "black",
+});
+
+const FeatureRow = styled("div", {
+ marginBottom: "0.5em",
+});
+
+const FeaturesProperties = (props: { features: MapGeoJSONFeature[] }) => {
+ const fs = props.features.map((f, i) => {
+ let tmp: [string, string][] = [];
+ for (var key in f.properties) {
+ tmp.push([key, f.properties[key]]);
+ }
+
+ const rows = tmp.map((d, i) => (
+
+ | {d[0]} |
+ {d[1]} |
+
+ ));
+
+ return (
+
+ {(f.layer as any)["source-layer"]}
+
+
+ );
+ });
+ return {fs};
+};
+
const rasterStyle = (file: PMTiles) => {
return {
version: 8,
@@ -47,7 +81,7 @@ const vectorStyle = async (file: PMTiles): Promise => {
}
if (vector_layers) {
- for (let [i,layer] of vector_layers.entries()) {
+ for (let [i, layer] of vector_layers.entries()) {
layers.push({
id: layer.id + "_fill",
type: "fill",
@@ -82,7 +116,7 @@ const vectorStyle = async (file: PMTiles): Promise => {
});
}
} else if (tilestats) {
- for (let [i,layer] of tilestats.layers.entries()) {
+ for (let [i, layer] of tilestats.layers.entries()) {
if (layer.geometry === "Polygon") {
layers.push({
id: layer.layer + "_fill",
@@ -157,6 +191,26 @@ function MaplibreMap(props: { file: PMTiles }) {
map.addControl(new maplibregl.NavigationControl({}));
map.on("load", map.resize);
+ const popup = new maplibregl.Popup({
+ closeButton: false,
+ closeOnClick: false,
+ });
+
+ map.on("mousemove", (e) => {
+ var bbox = e.point;
+ var features = map.queryRenderedFeatures(bbox);
+ map.getCanvas().style.cursor = features.length ? "pointer" : "";
+
+ let content = renderToString();
+ if (!features.length) {
+ popup.remove();
+ } else {
+ popup.setHTML(content);
+ popup.setLngLat(e.lngLat);
+ popup.addTo(map);
+ }
+ });
+
return () => {
map.remove();
};