mirror of
https://github.com/protomaps/PMTiles.git
synced 2026-02-04 19:01:08 +00:00
improve metadata view [#49]
This commit is contained in:
@@ -4,6 +4,7 @@ import { styled } from "./stitches.config";
|
|||||||
|
|
||||||
import Inspector from "./Inspector";
|
import Inspector from "./Inspector";
|
||||||
import MaplibreMap from "./MaplibreMap";
|
import MaplibreMap from "./MaplibreMap";
|
||||||
|
import Metadata from "./Metadata";
|
||||||
|
|
||||||
import { MagnifyingGlassIcon, ImageIcon } from "@radix-ui/react-icons";
|
import { MagnifyingGlassIcon, ImageIcon } from "@radix-ui/react-icons";
|
||||||
import * as ToolbarPrimitive from "@radix-ui/react-toolbar";
|
import * as ToolbarPrimitive from "@radix-ui/react-toolbar";
|
||||||
@@ -59,13 +60,6 @@ const StyledToggleItem = styled(ToolbarPrimitive.ToggleItem, {
|
|||||||
"&[data-state=on]": { backgroundColor: "$primary", color: "$primaryText" },
|
"&[data-state=on]": { backgroundColor: "$primary", color: "$primaryText" },
|
||||||
});
|
});
|
||||||
|
|
||||||
const MetadataButton = styled(DialogPrimitive.Trigger, {
|
|
||||||
backgroundColor:"$primary",
|
|
||||||
color:"$primaryText",
|
|
||||||
padding:"$1",
|
|
||||||
cursor: "pointer"
|
|
||||||
})
|
|
||||||
|
|
||||||
const StyledOverlay = styled(DialogPrimitive.Overlay, {
|
const StyledOverlay = styled(DialogPrimitive.Overlay, {
|
||||||
backgroundColor: "black",
|
backgroundColor: "black",
|
||||||
position: "fixed",
|
position: "fixed",
|
||||||
@@ -87,23 +81,6 @@ const StyledContent = styled(DialogPrimitive.Content, {
|
|||||||
"&:focus": { outline: "none" },
|
"&:focus": { outline: "none" },
|
||||||
});
|
});
|
||||||
|
|
||||||
const MetadataTable = styled("table", {
|
|
||||||
tableLayout:"fixed",
|
|
||||||
width:"100%"
|
|
||||||
});
|
|
||||||
|
|
||||||
const MetadataKey = styled("td", {
|
|
||||||
padding: "0 $1"
|
|
||||||
});
|
|
||||||
|
|
||||||
const MetadataValue = styled("td", {
|
|
||||||
fontFamily:"monospace",
|
|
||||||
});
|
|
||||||
|
|
||||||
const JsonValue = styled(MetadataValue, {
|
|
||||||
overflowX:"scroll"
|
|
||||||
})
|
|
||||||
|
|
||||||
const Toolbar = StyledToolbar;
|
const Toolbar = StyledToolbar;
|
||||||
const ToolbarLink = StyledLink;
|
const ToolbarLink = StyledLink;
|
||||||
const ToolbarToggleGroup = StyledToggleGroup;
|
const ToolbarToggleGroup = StyledToggleGroup;
|
||||||
@@ -111,41 +88,16 @@ const ToolbarToggleItem = StyledToggleItem;
|
|||||||
|
|
||||||
function Loader(props: { file: PMTiles }) {
|
function Loader(props: { file: PMTiles }) {
|
||||||
let [tab, setTab] = useState("maplibre");
|
let [tab, setTab] = useState("maplibre");
|
||||||
let [metadata, setMetadata] = useState<[string, string][]>([]);
|
|
||||||
let [modalOpen, setModalOpen] = useState<boolean>(false);
|
|
||||||
|
|
||||||
let view;
|
let view;
|
||||||
if (tab === "maplibre") {
|
if (tab === "maplibre") {
|
||||||
view = <MaplibreMap file={props.file} />;
|
view = <MaplibreMap file={props.file} />;
|
||||||
} else {
|
} else if (tab === "inspector") {
|
||||||
view = <Inspector file={props.file} />;
|
view = <Inspector file={props.file} />;
|
||||||
|
} else {
|
||||||
|
view = <Metadata file={props.file} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
let pmtiles = props.file;
|
|
||||||
const fetchData = async () => {
|
|
||||||
let m = await pmtiles.getMetadata();
|
|
||||||
let tmp: [string, string][] = [];
|
|
||||||
for (var key in m) {
|
|
||||||
tmp.push([key, m[key]]);
|
|
||||||
}
|
|
||||||
setMetadata(tmp);
|
|
||||||
};
|
|
||||||
fetchData();
|
|
||||||
}, [props.file]);
|
|
||||||
|
|
||||||
const metadataRows = metadata.map((d, i) => {
|
|
||||||
let Cls = (d[0] === 'json') ? JsonValue : MetadataValue
|
|
||||||
return <tr key={i}>
|
|
||||||
<MetadataKey>{d[0]}</MetadataKey>
|
|
||||||
<Cls>{d[1]}</Cls>
|
|
||||||
</tr>
|
|
||||||
});
|
|
||||||
|
|
||||||
const closeModal = () => {
|
|
||||||
setModalOpen(false);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Toolbar aria-label="Formatting options">
|
<Toolbar aria-label="Formatting options">
|
||||||
@@ -162,35 +114,13 @@ function Loader(props: { file: PMTiles }) {
|
|||||||
<ToolbarToggleItem value="inspector" aria-label="Left aligned">
|
<ToolbarToggleItem value="inspector" aria-label="Left aligned">
|
||||||
<MagnifyingGlassIcon /> Tile Inspector
|
<MagnifyingGlassIcon /> Tile Inspector
|
||||||
</ToolbarToggleItem>
|
</ToolbarToggleItem>
|
||||||
|
<ToolbarToggleItem value="metadata" aria-label="Left aligned">
|
||||||
|
Metadata
|
||||||
|
</ToolbarToggleItem>
|
||||||
</ToolbarToggleGroup>
|
</ToolbarToggleGroup>
|
||||||
<ToolbarLink css={{ marginRight: 10 }}>
|
<ToolbarLink css={{ marginRight: 10 }}>
|
||||||
{props.file.source.getKey()}
|
{props.file.source.getKey()}
|
||||||
</ToolbarLink>
|
</ToolbarLink>
|
||||||
<DialogPrimitive.Root open={modalOpen}>
|
|
||||||
<MetadataButton onClick={() => setModalOpen(true)}>
|
|
||||||
Metadata
|
|
||||||
</MetadataButton>
|
|
||||||
<DialogPrimitive.Portal>
|
|
||||||
<StyledOverlay />
|
|
||||||
<StyledContent
|
|
||||||
onEscapeKeyDown={closeModal}
|
|
||||||
onPointerDownOutside={closeModal}
|
|
||||||
>
|
|
||||||
<DialogPrimitive.Title />
|
|
||||||
<DialogPrimitive.Description />
|
|
||||||
<MetadataTable>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>key</th>
|
|
||||||
<th>value</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>{metadataRows}</tbody>
|
|
||||||
</MetadataTable>
|
|
||||||
<DialogPrimitive.Close />
|
|
||||||
</StyledContent>
|
|
||||||
</DialogPrimitive.Portal>
|
|
||||||
</DialogPrimitive.Root>
|
|
||||||
</Toolbar>
|
</Toolbar>
|
||||||
|
|
||||||
{view}
|
{view}
|
||||||
|
|||||||
63
app/src/Metadata.tsx
Normal file
63
app/src/Metadata.tsx
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
import { useState, useEffect, useRef } from "react";
|
||||||
|
import { PMTiles, TileType } from "../../js";
|
||||||
|
import { Protocol } from "../../js/adapters";
|
||||||
|
import { styled } from "./stitches.config";
|
||||||
|
|
||||||
|
const MetadataTable = styled("table", {
|
||||||
|
tableLayout: "fixed",
|
||||||
|
width: "100%",
|
||||||
|
});
|
||||||
|
|
||||||
|
const MetadataKey = styled("td", {
|
||||||
|
padding: "0 $1",
|
||||||
|
});
|
||||||
|
|
||||||
|
const MetadataValue = styled("td", {
|
||||||
|
fontFamily: "monospace",
|
||||||
|
});
|
||||||
|
|
||||||
|
const JsonValue = styled(MetadataValue, {
|
||||||
|
overflowX: "scroll",
|
||||||
|
});
|
||||||
|
|
||||||
|
function Metadata(props: { file: PMTiles }) {
|
||||||
|
let [metadata, setMetadata] = useState<[string, string][]>([]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
let pmtiles = props.file;
|
||||||
|
const fetchData = async () => {
|
||||||
|
let m = await pmtiles.getMetadata();
|
||||||
|
let tmp: [string, string][] = [];
|
||||||
|
for (var key in m) {
|
||||||
|
let val = m[key];
|
||||||
|
tmp.push([key, JSON.stringify(val)]);
|
||||||
|
}
|
||||||
|
setMetadata(tmp);
|
||||||
|
};
|
||||||
|
fetchData();
|
||||||
|
}, [props.file]);
|
||||||
|
|
||||||
|
const metadataRows = metadata.map((d, i) => {
|
||||||
|
let Cls = d[0] === "json" ? JsonValue : MetadataValue;
|
||||||
|
return (
|
||||||
|
<tr key={i}>
|
||||||
|
<MetadataKey>{d[0]}</MetadataKey>
|
||||||
|
<Cls>{d[1]}</Cls>
|
||||||
|
</tr>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<MetadataTable>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>key</th>
|
||||||
|
<th>value</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>{metadataRows}</tbody>
|
||||||
|
</MetadataTable>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Metadata;
|
||||||
15
js/index.ts
15
js/index.ts
@@ -799,21 +799,6 @@ export class PMTiles {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async root_entries() {
|
|
||||||
const header = await this.cache.getHeader(this.source);
|
|
||||||
|
|
||||||
// V2 COMPATIBILITY
|
|
||||||
if (header.specVersion < 3) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
return await this.cache.getDirectory(
|
|
||||||
this.source,
|
|
||||||
header.rootDirectoryOffset,
|
|
||||||
header.rootDirectoryLength,
|
|
||||||
header
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
async getHeader() {
|
async getHeader() {
|
||||||
return await this.cache.getHeader(this.source);
|
return await this.cache.getHeader(this.source);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user