@trailstash/ultra
Version:
A web based tool for making MapLibre GL maps with data from sources such as Overpass, GeoJSON, GPX, KML, TCX, etc
99 lines (96 loc) • 2.62 kB
JavaScript
import { fetchIfHTTP } from "./util.js";
import { PMTiles } from "pmtiles";
// Created with https://colorbrewer2.org/?type=qualitative&scheme=Set1&n=9
const colors = [
"#e41a1c",
"#377eb8",
"#4daf4a",
"#984ea3",
"#ff7f00",
"#ffff33",
"#a65628",
"#f781bf",
"#999999",
];
export default {
source: (query) => {
const source = {
type: "vector",
};
if (query.match(/{[xyz]}/)) {
source.tiles = query.split("\n").filter((x) => !!x);
} else {
source.url = query.trim();
}
return source;
},
layers: async (source, query) => {
const layers = [];
if (!query.match(/{[xyz]}/)) {
let tileJSON;
if (query.startsWith("pmtiles://")) {
const pmtiles = new PMTiles(query.slice("pmtiles://".length));
tileJSON = await pmtiles.getTileJson();
} else {
const resp = await fetch(query);
if (!resp.ok) {
return layers;
}
tileJSON = await resp.json();
}
for (const i in tileJSON.vector_layers) {
const { id } = tileJSON.vector_layers[i];
layers.push({
id: `${source}-vector-${i}-fill`,
source,
"source-layer": id,
type: "fill",
filter: ["==", ["geometry-type"], "Polygon"],
paint: {
"fill-opacity": 0.5,
"fill-color": colors[i % colors.length],
},
});
layers.push({
id: `${source}-vector-${i}-line`,
source,
"source-layer": id,
type: "line",
filter: ["==", ["geometry-type"], "LineString"],
paint: {
"line-color": colors[i % colors.length],
"line-width": 2,
},
layout: {
"line-join": "round",
"line-cap": "round",
},
});
layers.push({
id: `${source}-vector-${i}-point`,
source,
"source-layer": id,
type: "circle",
filter: ["==", ["geometry-type"], "Point"],
paint: {
"circle-color": colors[i % colors.length],
"circle-radius": 3,
},
});
}
}
return layers;
},
detect: async (query) => {
if (query.startsWith("pmtiles://")) {
const pmtiles = new PMTiles(query.slice("pmtiles://".length));
const tileJSON = await pmtiles.getTileJson();
return tileJSON.tilejson && tileJSON.vector_layers;
}
query = await fetchIfHTTP(query);
try {
const tileJSON = JSON.parse(query);
return tileJSON.tilejson && tileJSON.vector_layers;
} catch {}
},
};