@trailstash/ultra
Version:
A web based tool for making MapLibre GL maps with data from sources such as Overpass, GeoJSON, GPX, KML, TCX, etc
130 lines (126 loc) • 3.27 kB
JavaScript
import { fetchIfHTTP } from "./util.js";
const layers = (source) => [
{
id: `${source}-geojson-fill`,
type: "fill",
source,
filter: ["==", ["geometry-type"], "Polygon"],
paint: {
"fill-color": ["coalesce", ["get", "fill"], "#555"],
"fill-opacity": ["coalesce", ["get", "fill-opacity"], 0.3],
},
},
{
id: `${source}-geojson-fill-outline`,
type: "line",
source,
filter: ["==", ["geometry-type"], "Polygon"],
layout: { "line-cap": "round" },
paint: {
"line-color": ["coalesce", ["get", "stroke"], "#555"],
"line-width": ["coalesce", ["get", "stroke-width"], 2],
"line-opacity": ["coalesce", ["get", "stroke-opacity"], 1],
},
},
{
id: `${source}-geojson-line-2`,
type: "line",
source,
filter: ["==", ["geometry-type"], "LineString"],
layout: { "line-cap": "round" },
paint: {
"line-color": ["coalesce", ["get", "stroke"], "#555"],
"line-width": ["coalesce", ["get", "stroke-width"], 2],
"line-opacity": ["coalesce", ["get", "stroke-opacity"], 1],
},
},
{
id: `${source}-geojson-point`,
type: "symbol",
source,
filter: ["==", ["geometry-type"], "Point"],
layout: {
"icon-overlap": "always",
"icon-size": [
"case",
["==", ["get", "marker-size"], "large"],
1.5,
["==", ["get", "marker-size"], "medium"],
1,
["==", ["get", "marker-size"], "small"],
0.75,
1,
],
"icon-anchor": [
"case",
["!", ["has", "marker-symbol"]],
"bottom",
["==", ["get", "marker-symbol"], "marker"],
"bottom",
["==", ["get", "marker-symbol"], "marker-stroked"],
"bottom",
"center",
],
"icon-image": [
"coalesce",
["image", ["concat", "maki:", ["get", "marker-symbol"]]],
["image", "maki:marker"],
],
},
paint: {
"icon-color": ["coalesce", ["get", "marker-color"], "#555"],
"icon-halo-color": ["coalesce", ["get", "stroke-color"], "#fff"],
"icon-halo-width": [
"coalesce",
["get", "stroke-width"],
[
"case",
["==", ["get", "marker-size"], "large"],
3,
["==", ["get", "marker-size"], "medium"],
1.5,
["==", ["get", "marker-size"], "small"],
1,
1.5,
],
],
},
},
];
export default {
source: async function geojson(query, controller) {
let data;
try {
data = JSON.parse(query);
} catch {
const resp = await fetch(query, { signal: controller.signal });
data = await resp.json();
}
return { type: "geojson", data, generateId: true };
},
layers,
fitBounds: true,
detect,
};
// Local and Remote GeoJSON are detected by checking for valid GeoJSON types in a JSON document
const geoJsonTypes = [
"Feature",
"FeatureCollection",
"Geometry",
"GeometryCollection",
"Point",
"MultiPoint",
"LineString",
"MultiLineString",
"Polygon",
"MultiPolygon",
];
async function detect(query) {
query = await fetchIfHTTP(query);
try {
const json = JSON.parse(query);
if (geoJsonTypes.includes(json.type)) {
return true;
}
} catch {}
}