mirror of
https://github.com/protomaps/PMTiles.git
synced 2026-02-04 02:41:09 +00:00
New viewer 4 (#559)
app: viewer improvements [#49] * show missing id when feature id is undefined instead of 0 * improve point symbology for dense point tilesets * show lon,lat in popup * better wrapping for long popup value strings
This commit is contained in:
@@ -1,9 +1,9 @@
|
|||||||
import { For } from "solid-js";
|
import { For, Show } from "solid-js";
|
||||||
|
|
||||||
export interface InspectableFeature {
|
export interface InspectableFeature {
|
||||||
layerName: string;
|
layerName: string;
|
||||||
type: number;
|
type: number;
|
||||||
id: number;
|
id: number | undefined;
|
||||||
properties: { [key: string]: string | number | boolean };
|
properties: { [key: string]: string | number | boolean };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -15,21 +15,28 @@ const intToGeomType = (n: number) => {
|
|||||||
|
|
||||||
export const FeatureTable = (props: { features: InspectableFeature[] }) => {
|
export const FeatureTable = (props: { features: InspectableFeature[] }) => {
|
||||||
return (
|
return (
|
||||||
<div class="max-h-120 overflow-y-scroll divide-y app-divide">
|
<div class="max-h-120 overflow-y-scroll max-w-200 divide-y app-divide">
|
||||||
<For each={props.features}>
|
<For each={props.features}>
|
||||||
{(f) => (
|
{(f) => (
|
||||||
<div class="p-2">
|
<div class="p-2">
|
||||||
<div>
|
<div>
|
||||||
{f.layerName} {intToGeomType(f.type)}
|
{f.layerName}{" "}
|
||||||
|
<span class="app-text-light">{intToGeomType(f.type)}</span>
|
||||||
|
</div>
|
||||||
|
<div class="text-xs font-mono app-text-light">
|
||||||
|
<Show when={f.id !== undefined} fallback={"missing ID"}>
|
||||||
|
ID {f.id}
|
||||||
|
</Show>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-xs font-mono app-text-light">ID {f.id}</div>
|
|
||||||
<table class="font-mono table-auto border-separate border-spacing-x-2">
|
<table class="font-mono table-auto border-separate border-spacing-x-2">
|
||||||
<tbody>
|
<tbody>
|
||||||
<For each={Object.entries(f.properties)}>
|
<For each={Object.entries(f.properties)}>
|
||||||
{([key, value]) => (
|
{([key, value]) => (
|
||||||
<tr>
|
<tr>
|
||||||
<td class="text-right app-text-light">{key}</td>
|
<td class="text-right app-text-light break-keep">
|
||||||
<td>
|
{key}
|
||||||
|
</td>
|
||||||
|
<td class="break-all">
|
||||||
{typeof value === "boolean"
|
{typeof value === "boolean"
|
||||||
? JSON.stringify(value)
|
? JSON.stringify(value)
|
||||||
: value.toString()}
|
: value.toString()}
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ function MapView(props: {
|
|||||||
return hoveredFeatures().map((h) => {
|
return hoveredFeatures().map((h) => {
|
||||||
return {
|
return {
|
||||||
layerName: h.sourceLayer || "unknown",
|
layerName: h.sourceLayer || "unknown",
|
||||||
id: (h.id as number) || 0,
|
id: h.id ? (h.id as number) : undefined,
|
||||||
properties: h.properties,
|
properties: h.properties,
|
||||||
type: h._vectorTileFeature.type,
|
type: h._vectorTileFeature.type,
|
||||||
};
|
};
|
||||||
@@ -169,7 +169,8 @@ function MapView(props: {
|
|||||||
"source-layer": vectorLayer,
|
"source-layer": vectorLayer,
|
||||||
paint: {
|
paint: {
|
||||||
"circle-color": colorForIdx(i),
|
"circle-color": colorForIdx(i),
|
||||||
"circle-radius": 3,
|
"circle-radius": ["interpolate", ["linear"], ["zoom"], 4, 2, 12, 4],
|
||||||
|
"circle-opacity": 0.5,
|
||||||
"circle-stroke-color": "white",
|
"circle-stroke-color": "white",
|
||||||
"circle-stroke-width": [
|
"circle-stroke-width": [
|
||||||
"case",
|
"case",
|
||||||
@@ -355,6 +356,7 @@ function MapView(props: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (const hoveredFeature of hoveredFeatures()) {
|
for (const hoveredFeature of hoveredFeatures()) {
|
||||||
|
if (hoveredFeature.id === undefined) continue;
|
||||||
map.setFeatureState(hoveredFeature, { hover: false });
|
map.setFeatureState(hoveredFeature, { hover: false });
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -367,6 +369,7 @@ function MapView(props: {
|
|||||||
features = features.filter((feature) => feature.source === "tileset");
|
features = features.filter((feature) => feature.source === "tileset");
|
||||||
|
|
||||||
for (const feature of features) {
|
for (const feature of features) {
|
||||||
|
if (feature.id === undefined) continue;
|
||||||
map.setFeatureState(feature, { hover: true });
|
map.setFeatureState(feature, { hover: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -387,7 +390,7 @@ function MapView(props: {
|
|||||||
<div>
|
<div>
|
||||||
<FeatureTable features={inspectableFeatures()} />
|
<FeatureTable features={inspectableFeatures()} />
|
||||||
<a
|
<a
|
||||||
class="block text-xs btn-primary mt-2 text-center"
|
class="block text-xs btn-primary mt-2 text-center px-2"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
href={tileInspectUrl(props.tileset().getStateUrl(), [
|
href={tileInspectUrl(props.tileset().getStateUrl(), [
|
||||||
@@ -398,6 +401,9 @@ function MapView(props: {
|
|||||||
>
|
>
|
||||||
Tile {z}/{tileX}/{tileY}
|
Tile {z}/{tileX}/{tileY}
|
||||||
</a>
|
</a>
|
||||||
|
<div class="text-xs text-center mt-2 font-mono">
|
||||||
|
{e.lngLat.lng.toFixed(4)},{e.lngLat.lat.toFixed(4)}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
),
|
),
|
||||||
hiddenRef,
|
hiddenRef,
|
||||||
|
|||||||
Reference in New Issue
Block a user