72 lines
2.0 KiB
TypeScript
72 lines
2.0 KiB
TypeScript
import Image from "next/image";
|
|
import { parseWmsUrl } from "../utils/wms";
|
|
|
|
export function MapLegend({
|
|
parsed,
|
|
width = 600,
|
|
}: {
|
|
parsed: ReturnType<typeof parseWmsUrl>;
|
|
width: number;
|
|
}) {
|
|
if (!parsed?.baseUrl || !parsed?.params?.layers) return null;
|
|
|
|
const layers = String(parsed.params.layers)
|
|
.split(",")
|
|
.map((l) => l.trim())
|
|
.filter(Boolean);
|
|
|
|
const styles = parsed.params.styles
|
|
? String(parsed.params.styles)
|
|
.split(",")
|
|
.map((s) => s.trim())
|
|
: [];
|
|
|
|
return (
|
|
<div className="pointer-events-none absolute left-3 bottom-3 z-[1001]">
|
|
<div className="pointer-events-auto bg-white/90 backdrop-blur rounded-md border shadow p-2 max-w-[min(90vw,360px)]">
|
|
{layers.map((layer, i) => {
|
|
const style = styles[i];
|
|
const url = buildLegendUrl(parsed, layer, style);
|
|
return (
|
|
<div key={layer} className="mb-2 last:mb-0">
|
|
<div style={{ maxWidth: width }}>
|
|
<Image
|
|
src={url}
|
|
alt={`Legend ${layer}`}
|
|
width={0}
|
|
height={0}
|
|
sizes={`${width}px`}
|
|
style={{ width: "100%", height: "auto" }}
|
|
className="object-cover"
|
|
/>
|
|
</div>
|
|
</div>
|
|
);
|
|
})}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
// local function
|
|
function buildLegendUrl(
|
|
parsed: ReturnType<typeof parseWmsUrl> | null | undefined,
|
|
layer: string,
|
|
style?: string
|
|
) {
|
|
if (!parsed?.baseUrl) {
|
|
return "";
|
|
}
|
|
const u = new URL(parsed.baseUrl);
|
|
u.searchParams.set("SERVICE", "WMS");
|
|
u.searchParams.set("REQUEST", "GetLegendGraphic");
|
|
u.searchParams.set("VERSION", parsed.params.version || "1.1.1");
|
|
u.searchParams.set("FORMAT", "image/png");
|
|
u.searchParams.set("TRANSPARENT", "true");
|
|
u.searchParams.set("LAYER", layer);
|
|
if (style) u.searchParams.set("STYLE", style); // if use specific style
|
|
u.searchParams.set("SLD_VERSION", "1.1.0");
|
|
|
|
return u.toString();
|
|
}
|