-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.ts
119 lines (110 loc) · 3.47 KB
/
main.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import { Map, View } from "ol";
import { ScaleLine } from "ol/control";
import { useGeographic } from "ol/proj";
import { Tile as TileLayer } from "ol/layer";
import { OSM } from "ol/source";
import defaultMapCSS from "./default.mapcss?raw";
import OverpassVectorLayer from "./OverpassVectorLayer";
import "./style.css";
import { evaluateCanvas } from "./mapcss";
useGeographic();
const vectorLayer = new OverpassVectorLayer({});
const tileLayer = new TileLayer({
source: new OSM(),
className: "ol-layer-osm",
});
const queryTextarea = document.getElementById("query") as HTMLTextAreaElement;
const mapcssTextarea = document.getElementById("mapcss") as HTMLTextAreaElement;
const defaultQuery = `
/// @subpart foreground
relation(4740507);>;out geom;
/// @subpart background
//nwr[railway=rail]({{bbox}});out geom;
/// @subpart town
/// @type geojson
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": { "name": "Gars am Kamp", "place": "town" },
"geometry": { "type": "Point", "coordinates": [15.6594592, 48.5951053] }
}
]
}
`.trim();
const store = new (class Store {
get query(): string {
return localStorage.getItem("overpass-ol.query") || defaultQuery;
}
set query(value: string) {
localStorage.setItem("overpass-ol.query", value);
this.updateURL();
}
get mapcss(): string {
return localStorage.getItem("overpass-ol.mapcss") || defaultMapCSS;
}
set mapcss(value: string) {
localStorage.setItem("overpass-ol.mapcss", value);
this.updateURL();
}
updateURL() {
location.hash = new URLSearchParams({
query: this.query,
mapcss: this.mapcss,
}).toString();
}
})();
const searchParams = new URLSearchParams(location.hash.slice(1));
store.query = searchParams.get("query") || store.query;
store.mapcss = searchParams.get("mapcss") || store.mapcss;
queryTextarea.value ||= store.query;
mapcssTextarea.value ||= store.mapcss;
queryTextarea.addEventListener(
"keydown",
(e) => (e.ctrlKey || e.metaKey) && e.key === "Enter" && executeQueryClick(),
);
mapcssTextarea.addEventListener(
"keydown",
(e) => (e.ctrlKey || e.metaKey) && e.key === "Enter" && executeStyleClick(),
);
const executeQueryButton = document.getElementById(
"executeQuery",
) as HTMLButtonElement;
executeQueryButton.addEventListener("click", executeQueryClick);
async function executeQueryClick() {
try {
executeQueryButton.className = "pending";
await vectorLayer.executeQuery(queryTextarea.value);
executeQueryButton.className = "success";
store.query = queryTextarea.value;
} catch (error) {
executeQueryButton.title = error?.message || String(error);
executeQueryButton.className = "error";
console.error(error);
}
executeStyleClick();
}
const executeStyleButton = document.getElementById(
"executeStyle",
) as HTMLButtonElement;
executeStyleButton.addEventListener("click", executeStyleClick);
async function executeStyleClick() {
try {
executeStyleButton.className = "pending";
const rules = vectorLayer.executeStyle(mapcssTextarea.value);
executeStyleButton.className = "success";
store.mapcss = mapcssTextarea.value;
evaluateCanvas(rules, tileLayer);
} catch (error) {
executeStyleButton.title = error?.message || String(error);
executeStyleButton.className = "error";
console.error(error);
}
}
export const map = new Map({
target: "map",
layers: [tileLayer, vectorLayer],
view: new View({ center: [0, 0], zoom: 0 }),
controls: [new ScaleLine()],
});