@trailstash/ultra 4.2.4 → 4.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Examples/postpass.ultra +4 -3
- package/build-examples-images.js +20 -16
- package/components/style-picker.js +55 -21
- package/docs/yaml.md +7 -0
- package/lib/queryProviders/postpass.js +3 -18
- package/mkdocs.yml +4 -0
- package/package.json +2 -1
package/Examples/postpass.ultra
CHANGED
|
@@ -6,6 +6,7 @@ options:
|
|
|
6
6
|
zoom: 15
|
|
7
7
|
type: postpass
|
|
8
8
|
---
|
|
9
|
-
SELECT osm_id,
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
SELECT osm_id, osm_type, tags, geom
|
|
10
|
+
FROM postpass_point
|
|
11
|
+
WHERE tags->>'amenity'='fast_food'
|
|
12
|
+
AND geom && ST_MakeEnvelope({{wsen}},4326)
|
package/build-examples-images.js
CHANGED
|
@@ -1,22 +1,29 @@
|
|
|
1
1
|
import path from "path";
|
|
2
2
|
import fs from "fs";
|
|
3
3
|
import puppeteer from "puppeteer";
|
|
4
|
+
import minimist from "minimist";
|
|
4
5
|
|
|
5
|
-
const
|
|
6
|
-
|
|
6
|
+
const {
|
|
7
|
+
_: [exampleName],
|
|
8
|
+
useLocalhost,
|
|
9
|
+
height,
|
|
10
|
+
width,
|
|
11
|
+
waitTime,
|
|
12
|
+
output,
|
|
13
|
+
} = minimist(process.argv.slice(2))
|
|
7
14
|
|
|
8
15
|
const browser = await puppeteer.launch({ headless: true });
|
|
9
16
|
|
|
10
17
|
const page = await browser.newPage();
|
|
11
18
|
// set viewport and double deviceScaleFactor to get a closer shot of the map
|
|
12
19
|
await page.setViewport({
|
|
13
|
-
width: 600,
|
|
14
|
-
height: 250,
|
|
20
|
+
width: width || 600,
|
|
21
|
+
height: height || 250,
|
|
15
22
|
deviceScaleFactor: 2,
|
|
16
23
|
});
|
|
17
24
|
|
|
18
25
|
async function createImage(exampleName) {
|
|
19
|
-
if (!fs.existsSync(`./docs/assets/${path.dirname(exampleName)}`)) {
|
|
26
|
+
if (!output && !fs.existsSync(`./docs/assets/${path.dirname(exampleName)}`)) {
|
|
20
27
|
fs.mkdirSync(`./docs/assets/${path.dirname(exampleName)}`);
|
|
21
28
|
}
|
|
22
29
|
|
|
@@ -35,31 +42,28 @@ async function createImage(exampleName) {
|
|
|
35
42
|
// Wait for map to load, then wait two more seconds for images, etc. to load.
|
|
36
43
|
try {
|
|
37
44
|
//await page.waitForFunction('map.loaded()');
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
await new Promise((resolve) => setTimeout(resolve, waitTime));
|
|
45
|
+
console.log(`waiting for ${waitTime || 4000} ms`);
|
|
46
|
+
await new Promise((resolve) => setTimeout(resolve, waitTime || 4000));
|
|
41
47
|
} catch (err) {
|
|
42
48
|
// map.loaded() does not evaluate to true within 3 seconds, it's probably an animated example.
|
|
43
49
|
// In this case we take the screenshot immediately.
|
|
44
50
|
console.log(`Timed out waiting for map load on ${exampleName}.`);
|
|
45
51
|
}
|
|
46
52
|
|
|
53
|
+
const filename = output || `./docs/assets/${exampleName.replace(".ultra", ".png")}`;
|
|
54
|
+
|
|
47
55
|
await page
|
|
48
56
|
.screenshot({
|
|
49
|
-
path:
|
|
57
|
+
path: filename,
|
|
50
58
|
type: "png",
|
|
51
59
|
clip: {
|
|
52
60
|
x: 0,
|
|
53
61
|
y: 0,
|
|
54
|
-
width: 600,
|
|
55
|
-
height: 250,
|
|
62
|
+
width: width || 600,
|
|
63
|
+
height: height || 250,
|
|
56
64
|
},
|
|
57
65
|
})
|
|
58
|
-
.then(() =>
|
|
59
|
-
console.log(
|
|
60
|
-
`Created ./docs/assets/${exampleName.replace(".ultra", ".png")}`,
|
|
61
|
-
),
|
|
62
|
-
)
|
|
66
|
+
.then(() => console.log(`Created ${filename}`))
|
|
63
67
|
.catch((err) => {
|
|
64
68
|
console.log(err);
|
|
65
69
|
});
|
|
@@ -2,31 +2,54 @@ import { h, t } from "../lib/dom.js";
|
|
|
2
2
|
import { style as buttonCSS } from "./button.js";
|
|
3
3
|
import { normalizeCSS } from "../lib/normalize.js";
|
|
4
4
|
|
|
5
|
-
const
|
|
5
|
+
const css = new CSSStyleSheet();
|
|
6
|
+
css.replaceSync(`
|
|
7
|
+
h3 {
|
|
8
|
+
margin: .5em 0 0;
|
|
9
|
+
}
|
|
10
|
+
h3 a {
|
|
11
|
+
color: black;
|
|
12
|
+
text-decoration: none;
|
|
13
|
+
}
|
|
14
|
+
button {
|
|
15
|
+
margin: 0.25em;
|
|
16
|
+
display: inline-block;
|
|
17
|
+
}
|
|
18
|
+
button img {
|
|
19
|
+
height: 125px;
|
|
20
|
+
width: 125px;
|
|
21
|
+
}
|
|
22
|
+
h3 img {
|
|
23
|
+
height: 2em;
|
|
24
|
+
width: 2em;
|
|
25
|
+
vertical-align: middle;
|
|
26
|
+
object-fit: contain;
|
|
27
|
+
}
|
|
28
|
+
`);
|
|
6
29
|
|
|
7
30
|
const styles = [
|
|
8
31
|
[
|
|
9
|
-
"
|
|
32
|
+
"Liberty",
|
|
10
33
|
"https://tiles.openfreemap.org/styles/liberty",
|
|
11
34
|
`<a href="https://openfreemap.org/">OpenFreeMap</a>`,
|
|
12
35
|
],
|
|
13
36
|
[
|
|
14
|
-
"
|
|
37
|
+
"Bright",
|
|
15
38
|
"https://tiles.openfreemap.org/styles/bright",
|
|
16
39
|
`<a href="https://openfreemap.org/">OpenFreeMap</a>`,
|
|
17
40
|
],
|
|
18
41
|
[
|
|
19
|
-
"
|
|
42
|
+
"Positron",
|
|
20
43
|
"https://tiles.openfreemap.org/styles/positron",
|
|
21
44
|
`<a href="https://openfreemap.org/">OpenFreeMap</a>`,
|
|
22
45
|
],
|
|
23
46
|
[
|
|
24
|
-
"
|
|
47
|
+
"Vectortiles",
|
|
25
48
|
"https://trailstash.github.io/naturalearthtiles/maps/natural_earth.vector.json",
|
|
26
49
|
`<a href="https://github.com/trailstash/naturalearthtiles">Natural Earth</a>`,
|
|
27
50
|
],
|
|
28
51
|
[
|
|
29
|
-
"
|
|
52
|
+
"Demo Tiles",
|
|
30
53
|
"https://demotiles.maplibre.org/style.json",
|
|
31
54
|
`<a href="https://github.com/maplibre/demotiles">MapLibre</a>`,
|
|
32
55
|
],
|
|
@@ -47,7 +70,7 @@ export class StylePicker extends HTMLElement {
|
|
|
47
70
|
return;
|
|
48
71
|
}
|
|
49
72
|
|
|
50
|
-
const div = h("div", { slot: "modal-content" });
|
|
73
|
+
const div = h("div", { slot: "modal-content", style: "max-width: 1055px;" });
|
|
51
74
|
const button = h(
|
|
52
75
|
"button-modal",
|
|
53
76
|
{ text: "Pick Style", icon: "paintbrush" },
|
|
@@ -55,23 +78,34 @@ export class StylePicker extends HTMLElement {
|
|
|
55
78
|
);
|
|
56
79
|
this.refs = { button, div };
|
|
57
80
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
81
|
+
const stylesByProvider = {};
|
|
82
|
+
for (const [name, value, provider] of this.styles) {
|
|
83
|
+
if (!stylesByProvider[provider]) {
|
|
84
|
+
stylesByProvider[provider] = [];
|
|
85
|
+
}
|
|
86
|
+
stylesByProvider[provider].push({name, value});
|
|
87
|
+
}
|
|
88
|
+
for (const [provider, styles] of Object.entries(stylesByProvider)) {
|
|
89
|
+
const div2 = h("div", {style:"display:inline-block;margin-right:1.25em;"});
|
|
90
|
+
div.appendChild(div2);
|
|
91
|
+
div2.appendChild(h("h3", {}, provider));
|
|
92
|
+
for (const {name, value} of styles) {
|
|
93
|
+
const styleButton = h(
|
|
94
|
+
"button",
|
|
95
|
+
{},
|
|
96
|
+
name,
|
|
70
97
|
);
|
|
71
|
-
|
|
72
|
-
|
|
98
|
+
styleButton.addEventListener("click", (e) => {
|
|
99
|
+
button.toggle();
|
|
100
|
+
this.dispatchEvent(
|
|
101
|
+
new CustomEvent("change", { detail: { value: value } }),
|
|
102
|
+
);
|
|
103
|
+
});
|
|
104
|
+
div2.appendChild(styleButton);
|
|
105
|
+
}
|
|
73
106
|
}
|
|
74
107
|
|
|
108
|
+
shadow.adoptedStyleSheets.push(css);
|
|
75
109
|
shadow.appendChild(button);
|
|
76
110
|
}
|
|
77
111
|
}
|
package/docs/yaml.md
CHANGED
|
@@ -254,6 +254,13 @@ Detected if
|
|
|
254
254
|
An SQL query to be executed on a [Postpass](https://github.com/woodpeck/postpass) server. Server
|
|
255
255
|
results are modified to have the same structure as [overpass](#overpass)
|
|
256
256
|
|
|
257
|
+
!!! warning
|
|
258
|
+
|
|
259
|
+
Postpass is in very early stages of development, so Ultra may lag behind as new versions of the
|
|
260
|
+
API are released. This provider defaults to the version 0.2 of the [GeoFabrik Postpass
|
|
261
|
+
API](https://github.com/woodpeck/postpass-ops) &
|
|
262
|
+
[Schema](https://github.com/woodpeck/postpass-ops/blob/main/SCHEMA.md)
|
|
263
|
+
|
|
257
264
|
## `options`
|
|
258
265
|
|
|
259
266
|
When an Ultra query is run in "interactive map" mode, you can specify the
|
|
@@ -3,14 +3,6 @@ import { setQueryBounds } from "../bounds.js";
|
|
|
3
3
|
|
|
4
4
|
import { layers, popupTemplate, popupContextBuilder } from "./osm.js";
|
|
5
5
|
|
|
6
|
-
const nonTags = {
|
|
7
|
-
osm_id: true,
|
|
8
|
-
tags: true,
|
|
9
|
-
// yes... these are not tags... but they are useful! so we're keeping them.
|
|
10
|
-
// way_area: true,
|
|
11
|
-
// z_order: true,
|
|
12
|
-
};
|
|
13
|
-
|
|
14
6
|
const flattenPropertiesAndInferIdAndType = (geoJSON) => {
|
|
15
7
|
// prety major assumption basked into this as Postpass executes arbitrary SQL so the returned
|
|
16
8
|
// data could be anything. This assumes that the query returns un-renamed columns.
|
|
@@ -18,12 +10,7 @@ const flattenPropertiesAndInferIdAndType = (geoJSON) => {
|
|
|
18
10
|
const properties = {};
|
|
19
11
|
if (f.properties.osm_id) {
|
|
20
12
|
properties["@id"] = f.properties.osm_id;
|
|
21
|
-
|
|
22
|
-
properties["@id"] = -properties["@id"];
|
|
23
|
-
properties["@type"] = "relation";
|
|
24
|
-
} else {
|
|
25
|
-
properties["@type"] = f.geometry.type === "Point" ? "node" : "way";
|
|
26
|
-
}
|
|
13
|
+
properties["@type"] = f.properties.osm_type;
|
|
27
14
|
}
|
|
28
15
|
if (f.properties.tags) {
|
|
29
16
|
for (const [k, v] of Object.entries(f.properties.tags)) {
|
|
@@ -31,9 +18,7 @@ const flattenPropertiesAndInferIdAndType = (geoJSON) => {
|
|
|
31
18
|
}
|
|
32
19
|
}
|
|
33
20
|
for (const [k, v] of Object.entries(f.properties)) {
|
|
34
|
-
|
|
35
|
-
properties[k] = v;
|
|
36
|
-
}
|
|
21
|
+
properties[k] = v;
|
|
37
22
|
}
|
|
38
23
|
return {
|
|
39
24
|
...f,
|
|
@@ -46,7 +31,7 @@ const flattenPropertiesAndInferIdAndType = (geoJSON) => {
|
|
|
46
31
|
const postpass = {
|
|
47
32
|
source: async function (query, controller, { server, bounds }) {
|
|
48
33
|
if (!server) {
|
|
49
|
-
server = "https://postpass.geofabrik.de/api/0.
|
|
34
|
+
server = "https://postpass.geofabrik.de/api/0.2/interpreter";
|
|
50
35
|
}
|
|
51
36
|
const resp = await fetch(server, {
|
|
52
37
|
method: "POST",
|
package/mkdocs.yml
CHANGED
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "4.2.
|
|
6
|
+
"version": "4.2.6",
|
|
7
7
|
"description": "A web based tool for making MapLibre GL maps with data from sources such as Overpass, GeoJSON, GPX, KML, TCX, etc",
|
|
8
8
|
"main": "index.js",
|
|
9
9
|
"scripts": {
|
|
@@ -47,6 +47,7 @@
|
|
|
47
47
|
"esbuild-jest": "^0.5.0",
|
|
48
48
|
"jest": "^29.7.0",
|
|
49
49
|
"jest-environment-jsdom": "^29.7.0",
|
|
50
|
+
"minimist": "^1.2.8",
|
|
50
51
|
"prettier": "^3.3.3",
|
|
51
52
|
"puppeteer": "^23.4.0",
|
|
52
53
|
"svg2png": "^4.1.1",
|