@trailstash/ultra 5.0.3 → 6.0.0

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.
@@ -7,8 +7,8 @@ options:
7
7
  popupTemplate: >
8
8
  <h2>
9
9
  {{ type }}
10
- <a href="https://openhistoricalmap.org/{{ type }}/{{ id }}" target="_blank">{{ id }}</a>
11
- <a href="https://openhistoricalmap.org/edit?{{ type }}={{ id }}" target="_blank">✏️</a>
10
+ <a href="https://openstreetmap.org/{{ type }}/{{ id }}" target="_blank">{{ id }}</a>
11
+ <a href="https://openstreetmap.org/edit?{{ type }}={{ id }}" target="_blank">✏️</a>
12
12
  </h2>
13
13
  {% assign wikidata = tags["siren:model:wikidata"] ?? tags["model:wikidata"] %}
14
14
  {%- if wikidata %}
package/cli/build.js CHANGED
@@ -47,6 +47,11 @@ export const buildOptions = (config, watch = false) => ({
47
47
  alias: {
48
48
  "ultra-config": config,
49
49
  "node:events": "node-events", // esri-dump support
50
+ events: "node-events", // osm2geojson-ultra support (i think)
51
+ },
52
+ define: {
53
+ // esri-dump & osm2geojson-ultra support
54
+ process: "{ 'env': {}, 'browser': true, 'version': '' }",
50
55
  },
51
56
  plugins: [
52
57
  copy({
@@ -5,7 +5,7 @@ import { normalizeCSS } from "../lib/normalize.js";
5
5
  import { toQueryParams } from "../lib/queryParams.js";
6
6
  import { version } from "../package.json";
7
7
  import { version as maplibreVersion } from "maplibre-gl/package.json";
8
- import { version as osmtogeojsonVersion } from "osmtogeojson/package.json";
8
+ import { version as osmtogeojsonVersion } from "osm2geojson-ultra/package.json";
9
9
  import { version as esridumpVersion } from "esri-dump/package.json";
10
10
 
11
11
  const help = `# Introduction
@@ -131,8 +131,8 @@ export class HelpModal extends HTMLElement {
131
131
  this.queryProviders.osmxml
132
132
  ? `<li>
133
133
  Overpass &amp; OSM support powered by
134
- <a target="_blank" href="https://github.com/tyrasd/osmtogeojson"
135
- >osmtogeojson</a
134
+ <a target="_blank" href="https://github.com/dschep/osm2geojson-ultra"
135
+ >osm2geojson-ultra</a
136
136
  > <code>${osmtogeojsonVersion}</code>
137
137
  </li>`
138
138
  : ""
@@ -51,7 +51,7 @@ export class HTMLControl extends HTMLElement {
51
51
  return this._container;
52
52
  }
53
53
  onRemove() {
54
- this.container.parentNode.removeChild(this.container);
54
+ this._container.parentNode.removeChild(this._container);
55
55
  this.map = undefined;
56
56
  }
57
57
 
@@ -22,7 +22,12 @@ const defaultTemplate = `
22
22
  <br>
23
23
  {%- endfor %}
24
24
  `;
25
- const defaultContextBuilder = ({ properties }) => ({ properties });
25
+
26
+ const defaultContextBuilder = ({ properties, geometry }) => {
27
+ const context = { properties: structuredClone(properties) };
28
+ if (geometry.type === "Point") context.geometry = geometry;
29
+ return context;
30
+ };
26
31
 
27
32
  export class MapPopup extends HTMLElement {
28
33
  constructor() {
@@ -15,6 +15,7 @@ import { localStorage } from "../lib/localStorage.js";
15
15
  import { UltraMap } from "./ultra-map.js";
16
16
  import { HelpModal } from "./help-modal.js";
17
17
  import { StylePicker } from "./style-picker.js";
18
+ import { alertOnError } from "../lib/error.js";
18
19
 
19
20
  const style = new CSSStyleSheet();
20
21
  style.replaceSync(`
@@ -147,7 +148,9 @@ export class UltraIDE extends HTMLElement {
147
148
  // Get initial query and center&zoom
148
149
  try {
149
150
  this.query =
150
- (await Promise.resolve(getQueryFromQueryParams())) ||
151
+ (await Promise.resolve(getQueryFromQueryParams()).catch(
152
+ alertOnError,
153
+ )) ||
151
154
  this.queryStorage.get() ||
152
155
  this.query;
153
156
  } catch (e) {
@@ -221,7 +224,10 @@ export class UltraIDE extends HTMLElement {
221
224
  }
222
225
 
223
226
  async updateHash() {
224
- if (this.query === (await Promise.resolve(getQueryFromQueryParams())))
227
+ if (
228
+ this.query ===
229
+ (await Promise.resolve(getQueryFromQueryParams()).catch(alertOnError))
230
+ )
225
231
  return;
226
232
  // mostly cribbed from https://github.com/maplibre/maplibre-gl-js/blob/main/src/ui/hash.ts
227
233
  // not using URlSearchParams because it URL-enodes / characters
@@ -15,12 +15,8 @@ import { handleStyleImageMissing } from "../lib/sprites.js";
15
15
  import { handleMouseClick, handleMouseMove } from "../lib/queryMap.js";
16
16
  import { localStorage, optionsFromStorage } from "../lib/localStorage.js";
17
17
  import { HTMLControl } from "./html-control.js";
18
- import makeSandbox from "../lib/sandbox.js";
19
-
20
- let sandbox;
21
- try {
22
- sandbox = await makeSandbox();
23
- } catch {}
18
+ import { sandbox } from "../lib/sandbox.js";
19
+ import { alertOnError } from "../lib/error.js";
24
20
 
25
21
  const css = new CSSStyleSheet();
26
22
  css.replaceSync(`
@@ -39,7 +35,7 @@ css.replaceSync(`
39
35
  position: absolute;
40
36
  background: rgba(0,0,0,0.5);
41
37
  color: white;
42
- z-index: 1000;
38
+ z-index: 1;
43
39
  padding: 1em;
44
40
  display: none;
45
41
  }
@@ -70,6 +66,8 @@ export class UltraMap extends HTMLElement {
70
66
 
71
67
  #autoProvider;
72
68
 
69
+ #extraControls = { HTMLControl };
70
+
73
71
  static defaults = {
74
72
  loadSettingsFromQueryParams: true,
75
73
  type: "auto",
@@ -170,8 +168,8 @@ export class UltraMap extends HTMLElement {
170
168
  set controls(value) {
171
169
  this.#controls = value.map
172
170
  ? value.map(({ type, options, position }) =>
173
- type === "HTMLControl"
174
- ? { type: new HTMLControl(options), position }
171
+ this.#extraControls[type]
172
+ ? { type: new this.#extraControls[type](options), position }
175
173
  : { type, options, position },
176
174
  )
177
175
  : value;
@@ -183,6 +181,7 @@ export class UltraMap extends HTMLElement {
183
181
 
184
182
  if (this.loadSettingsFromQueryParams) {
185
183
  return Promise.resolve(getQueryFromQueryParams() || this.query)
184
+ .catch(alertOnError)
186
185
  .then(async (query) => {
187
186
  const querySettings = parseSettings(query);
188
187
  const settings = {
@@ -203,7 +202,7 @@ export class UltraMap extends HTMLElement {
203
202
  mapStyle: setBaseStyle(settings.mapStyle, this.mapStyle),
204
203
  });
205
204
 
206
- return this.#init(await getStyle(this.mapStyle));
205
+ return this.#init(await getStyle(this.mapStyle).catch(alertOnError));
207
206
  })
208
207
  .catch(alert);
209
208
  } else if (this.persistState) {
@@ -217,7 +216,7 @@ export class UltraMap extends HTMLElement {
217
216
  if (!this.mapStyle || typeof this.mapStyle === "string") {
218
217
  return this.#init(this.mapStyle);
219
218
  } else {
220
- return getStyle(this.mapStyle).then(this.#init);
219
+ return getStyle(this.mapStyle).catch(alertOnError).then(this.#init);
221
220
  }
222
221
  }
223
222
 
@@ -298,7 +297,7 @@ export class UltraMap extends HTMLElement {
298
297
  }
299
298
 
300
299
  async run(controller) {
301
- const mapStyle = await getStyle(this.mapStyle);
300
+ const mapStyle = await getStyle(this.mapStyle).catch(alertOnError);
302
301
  this.refs.mapLibre.mapStyle = mapStyle;
303
302
  const result = await this.#run(controller);
304
303
  if (this.#fitBounds) {
@@ -351,14 +350,16 @@ export class UltraMap extends HTMLElement {
351
350
  this.#cachedQuery = query;
352
351
  this.#cachedTransform = this.transform;
353
352
  this.#cachedType = this.type;
354
- let source = await queryProvider.source(query, controller, {
355
- server: this.server,
356
- bounds: this.refs.mapLibre.bounds,
357
- });
353
+ let source = await queryProvider
354
+ .source(query, controller, {
355
+ server: this.server,
356
+ bounds: this.refs.mapLibre.bounds,
357
+ })
358
+ .catch(alertOnError);
358
359
  if (this.transform) {
359
360
  if (sandbox) {
360
361
  source.data = await Promise.race([
361
- sandbox(this.transform, source.data),
362
+ sandbox("default", this.transform, source.data),
362
363
  new Promise((resolve, reject) => {
363
364
  controller.signal.onabort = () => {
364
365
  this.#cachedTransform = null;
@@ -378,7 +379,7 @@ export class UltraMap extends HTMLElement {
378
379
  layers: queryProvider.layers
379
380
  ? await Promise.resolve(queryProvider.layers("ultra", query))
380
381
  : [],
381
- });
382
+ }).catch(alertOnError);
382
383
  this.refs.mapLibre.mapStyle = mapStyle;
383
384
  return { data: this.#cachedSource.data, mapStyle };
384
385
  } finally {
package/docs/yaml.md CHANGED
@@ -81,7 +81,7 @@ See each provider for how it is auto-detected
81
81
 
82
82
  An [Overpass QL](https://wiki.openstreetmap.org/wiki/Overpass_API/Overpass_QL) query. Results
83
83
  converted into a [GeoJSON source](https://maplibre.org/maplibre-style-spec/sources/#geojson) with
84
- [`osmtogeojson`](https://github.com/tyrasd/osmtogeojson).
84
+ [`osm2geojson-ultra`](https://github.com/dschep/osm2geojson-ultra).
85
85
 
86
86
  Detected if:
87
87
 
@@ -120,7 +120,7 @@ Detected if:
120
120
 
121
121
  An [OSM XML](https://wiki.openstreetmap.org/wiki/OSM_XML) document or a URL to one. Converted into
122
122
  a [GeoJSON source](https://maplibre.org/maplibre-style-spec/sources/#geojson) with
123
- [`osmtogeojson`](https://github.com/tyrasd/osmtogeojson).
123
+ [`osm2geojson-ultra`](https://github.com/dschep/osm2geojson-ultra).
124
124
 
125
125
  Detected if:
126
126
 
@@ -132,7 +132,7 @@ Detected if:
132
132
 
133
133
  An [OSM JSON](https://wiki.openstreetmap.org/wiki/OSM_JSON) document or a URL to one. Converted
134
134
  into a [GeoJSON source](https://maplibre.org/maplibre-style-spec/sources/#geojson) with
135
- [`osmtogeojson`](https://github.com/tyrasd/osmtogeojson).
135
+ [[`osm2geojson-ultra`](https://github.com/dschep/osm2geojson-ultra).
136
136
 
137
137
  Detected if:
138
138
 
package/index.html CHANGED
@@ -29,8 +29,6 @@
29
29
  <meta name="robots" content="index,follow" />
30
30
 
31
31
  <script>
32
- addEventListener("error", ({ error }) => alert(error));
33
-
34
32
  window.sa_event =
35
33
  window.sa_event ||
36
34
  function () {
package/index.js CHANGED
@@ -22,9 +22,6 @@ import { FontAwesomeIcon } from "./components/fontawesome-icon.js";
22
22
  import { ButtonModal } from "./components/button-modal.js";
23
23
  import { MapPopup } from "./components/map-popup.js";
24
24
 
25
- // esri dump expects to be running in a node env, so add global process.env
26
- window.process = { env: {} };
27
-
28
25
  // Allow pages in new windows securely
29
26
  DOMPurify.addHook("afterSanitizeAttributes", function (node) {
30
27
  // set all elements owning target to target=_blank
package/lib/error.js ADDED
@@ -0,0 +1,4 @@
1
+ export const alertOnError = (e) => {
2
+ alert(e);
3
+ throw e;
4
+ };
@@ -12,6 +12,7 @@ import gpx from "./gpx.js";
12
12
  import tcx from "./tcx.js";
13
13
  import raw from "./raw.js";
14
14
  import esri from "./esri.js";
15
+ import javascript from "./javascript.js";
15
16
 
16
17
  export const all = {
17
18
  overpass,
@@ -33,6 +34,7 @@ export const all = {
33
34
  osmWebsite,
34
35
  osmWiki,
35
36
  taginfo,
37
+ javascript,
36
38
  };
37
39
 
38
40
  export default { auto: new AutoProvider(all), ...all };
@@ -0,0 +1,104 @@
1
+ import { sandbox } from "../sandbox.js";
2
+
3
+ const layers = (source) => [
4
+ {
5
+ id: `${source}-js-geojson-fill`,
6
+ type: "fill",
7
+ source,
8
+ filter: ["==", ["geometry-type"], "Polygon"],
9
+ paint: {
10
+ "fill-color": ["coalesce", ["get", "fill"], "#555"],
11
+ "fill-opacity": ["coalesce", ["get", "fill-opacity"], 0.3],
12
+ },
13
+ },
14
+ {
15
+ id: `${source}-js-geojson-fill-outline`,
16
+ type: "line",
17
+ source,
18
+ filter: ["==", ["geometry-type"], "Polygon"],
19
+ layout: { "line-cap": "round" },
20
+ paint: {
21
+ "line-color": ["coalesce", ["get", "stroke"], "#555"],
22
+ "line-width": ["coalesce", ["get", "stroke-width"], 2],
23
+ "line-opacity": ["coalesce", ["get", "stroke-opacity"], 1],
24
+ },
25
+ },
26
+ {
27
+ id: `${source}-js-geojson-line-2`,
28
+ type: "line",
29
+ source,
30
+ filter: ["==", ["geometry-type"], "LineString"],
31
+ layout: { "line-cap": "round" },
32
+ paint: {
33
+ "line-color": ["coalesce", ["get", "stroke"], "#555"],
34
+ "line-width": ["coalesce", ["get", "stroke-width"], 2],
35
+ "line-opacity": ["coalesce", ["get", "stroke-opacity"], 1],
36
+ },
37
+ },
38
+ {
39
+ id: `${source}-js-geojson-point`,
40
+ type: "symbol",
41
+ source,
42
+ filter: ["==", ["geometry-type"], "Point"],
43
+ layout: {
44
+ "icon-overlap": "always",
45
+ "icon-size": [
46
+ "case",
47
+ ["==", ["get", "marker-size"], "large"],
48
+ 1.5,
49
+ ["==", ["get", "marker-size"], "medium"],
50
+ 1,
51
+ ["==", ["get", "marker-size"], "small"],
52
+ 0.75,
53
+ 1,
54
+ ],
55
+ "icon-anchor": [
56
+ "case",
57
+ ["!", ["has", "marker-symbol"]],
58
+ "bottom",
59
+ ["==", ["get", "marker-symbol"], "marker"],
60
+ "bottom",
61
+ ["==", ["get", "marker-symbol"], "marker-stroked"],
62
+ "bottom",
63
+ "center",
64
+ ],
65
+ "icon-image": [
66
+ "coalesce",
67
+ ["image", ["concat", "maki:", ["get", "marker-symbol"]]],
68
+ ["image", "maki:marker"],
69
+ ],
70
+ },
71
+ paint: {
72
+ "icon-color": ["coalesce", ["get", "marker-color"], "#555"],
73
+ "icon-halo-color": ["coalesce", ["get", "stroke-color"], "#fff"],
74
+ "icon-halo-width": [
75
+ "coalesce",
76
+ ["get", "stroke-width"],
77
+ [
78
+ "case",
79
+ ["==", ["get", "marker-size"], "large"],
80
+ 3,
81
+ ["==", ["get", "marker-size"], "medium"],
82
+ 1.5,
83
+ ["==", ["get", "marker-size"], "small"],
84
+ 1,
85
+ 1.5,
86
+ ],
87
+ ],
88
+ },
89
+ },
90
+ ];
91
+
92
+ export default {
93
+ source: async function geojson(query, controller) {
94
+ return await Promise.race([
95
+ sandbox("source", query, {}),
96
+ new Promise((resolve, reject) => {
97
+ controller.signal.onabort = () => {
98
+ reject(new DOMException("", "AbortError"));
99
+ };
100
+ }),
101
+ ]);
102
+ },
103
+ layers,
104
+ };
@@ -1,4 +1,3 @@
1
- import osmtogeojson from "osmtogeojson";
2
1
  import { setQueryBounds } from "../bounds.js";
3
2
 
4
3
  import { layers, popupTemplate } from "./osm.js";
@@ -1,22 +1,4 @@
1
- import osmtogeojson from "osmtogeojson";
2
-
3
- export const flattenProperties = (geoJSON) => {
4
- geoJSON.features = geoJSON.features.map((x) => {
5
- const properties = x.properties;
6
- delete x.properties;
7
- return {
8
- properties: {
9
- "@id": properties.id,
10
- "@type": properties.type,
11
- "@meta":
12
- Object.keys(properties.meta).length > 0 ? properties.meta : undefined,
13
- ...properties.tags,
14
- },
15
- ...x,
16
- };
17
- });
18
- return geoJSON;
19
- };
1
+ import osm2geojson from "osm2geojson-ultra";
20
2
 
21
3
  export const popupTemplate = `
22
4
  {%- if type and id %}
@@ -64,9 +46,18 @@ export const popupContextBuilder = ({ properties, geometry }) => {
64
46
  const templateContext = {
65
47
  id: properties["@id"],
66
48
  type: properties["@type"],
67
- meta: JSON.parse(properties["@meta"] || null),
68
- tags: { ...properties },
49
+ tags: Object.fromEntries(
50
+ Object.entries(properties).filter(([k]) => !k.startsWith("@")),
51
+ ),
69
52
  };
53
+ const meta = Object.fromEntries(
54
+ Object.entries(properties).filter(
55
+ ([k]) => k.startsWith("@") && !["@id", "@type"].includes(k),
56
+ ),
57
+ );
58
+ if (Object.keys(meta).length > 0) {
59
+ templateContext.meta = meta;
60
+ }
70
61
  delete templateContext.tags["@type"];
71
62
  delete templateContext.tags["@id"];
72
63
  delete templateContext.tags["@meta"];
@@ -118,14 +109,17 @@ export const layers = (source) => [
118
109
  ];
119
110
 
120
111
  async function osmxmlSource(query, controller) {
121
- let doc = new window.DOMParser().parseFromString(query, "text/xml");
112
+ let text = query;
113
+ const doc = new window.DOMParser().parseFromString(text, "text/xml");
122
114
  if (doc.querySelector("parsererror")) {
123
115
  const resp = await fetch(query, { signal: controller.signal });
124
- doc = new window.DOMParser().parseFromString(await resp.text(), "text/xml");
116
+ text = await resp.text();
125
117
  }
126
- const data = flattenProperties(
127
- osmtogeojson(doc, { verbose: true, flatProperties: false }),
128
- );
118
+ const data = osm2geojson(text, {
119
+ completeFeature: true,
120
+ renderTagged: true,
121
+ excludeWay: false,
122
+ });
129
123
  return { type: "geojson", data, generateId: true };
130
124
  }
131
125
 
@@ -137,9 +131,11 @@ async function osmjsonSource(query, controller) {
137
131
  const resp = await fetch(query, { signal: controller.signal });
138
132
  json = await resp.json();
139
133
  }
140
- const data = flattenProperties(
141
- osmtogeojson(json, { verbose: true, flatProperties: false }),
142
- );
134
+ const data = osm2geojson(json, {
135
+ completeFeature: true,
136
+ renderTagged: true,
137
+ excludeWay: false,
138
+ });
143
139
  return {
144
140
  type: "geojson",
145
141
  data,
@@ -1,12 +1,7 @@
1
- import osmtogeojson from "osmtogeojson";
1
+ import osm2geojson from "osm2geojson-ultra";
2
2
  import { setQueryBounds } from "../bounds.js";
3
3
 
4
- import {
5
- flattenProperties,
6
- layers,
7
- popupTemplate,
8
- popupContextBuilder,
9
- } from "./osm.js";
4
+ import { layers, popupTemplate, popupContextBuilder } from "./osm.js";
10
5
 
11
6
  // Overpass queries are detected from common strings found in queries written in OverpassQL
12
7
  const overpassQLRegexes = [
@@ -87,25 +82,31 @@ export async function callInterpreter(
87
82
  ) {
88
83
  let geoJSON;
89
84
  if (resp.headers.get("content-type") == "application/osm3s+xml") {
90
- const dom = new window.DOMParser().parseFromString(
91
- await resp.text(),
92
- "text/xml",
93
- );
85
+ const text = await resp.text();
86
+ const dom = new window.DOMParser().parseFromString(text, "text/xml");
94
87
  if (dom.querySelector("remark")) {
95
88
  alert(dom.querySelector("remark").textContent);
96
89
  return { type: "FeatureCollection", features: [] };
97
90
  }
98
- geoJSON = osmtogeojson(dom, { flatProperties: false });
91
+ geoJSON = osm2geojson(text, {
92
+ completeFeature: true,
93
+ renderTagged: true,
94
+ excludeWay: false,
95
+ });
99
96
  } else {
100
97
  const json = await resp.json();
101
98
  if (json.remark) {
102
99
  alert(json.remark);
103
100
  return { type: "FeatureCollection", features: [] };
104
101
  }
105
- geoJSON = osmtogeojson(json, { flatProperties: false });
102
+ geoJSON = osm2geojson(json, {
103
+ completeFeature: true,
104
+ renderTagged: true,
105
+ excludeWay: false,
106
+ });
106
107
  }
107
108
 
108
- return flattenProperties(geoJSON);
109
+ return geoJSON;
109
110
  } else {
110
111
  const dom = new window.DOMParser().parseFromString(
111
112
  await resp.text(),
@@ -1,4 +1,3 @@
1
- import osmtogeojson from "osmtogeojson";
2
1
  import { setQueryBounds } from "../bounds.js";
3
2
 
4
3
  import { layers, popupTemplate, popupContextBuilder } from "./osm.js";
package/lib/sandbox.js CHANGED
@@ -11,12 +11,14 @@ const sandboxInit = async (sandboxId, p) => {
11
11
  id = msg.id;
12
12
  console.debug("parsed message", msg);
13
13
 
14
- const { default: transform } = await import(msg.transform);
14
+ const module = await import(
15
+ `data:text/javascript;base64,${btoa(msg.module)}`
16
+ );
15
17
 
16
- const o = await Promise.resolve(transform(msg.data));
17
- self.postMessage(JSON.stringify({ id: msg.id, data: o }));
18
+ const data = await Promise.resolve(module[msg.exportName](msg.data));
19
+ self.postMessage(JSON.stringify({ id, data }));
18
20
  } catch (e) {
19
- self.postMessage(JSON.stringify({ id: id, error: e.toString() }));
21
+ self.postMessage(JSON.stringify({ id, error: e.toString() }));
20
22
  }
21
23
  },
22
24
  false,
@@ -94,7 +96,7 @@ const makeSandbox = () => {
94
96
  );
95
97
  iframe.src = URL.createObjectURL(sandboxBlob);
96
98
 
97
- const run = (transform, data) => {
99
+ const run = (exportName, module, data) => {
98
100
  const messageID = crypto.randomUUID();
99
101
  return new Promise((resolve, reject) => {
100
102
  const listener = (event) => {
@@ -120,7 +122,8 @@ const makeSandbox = () => {
120
122
  iframe.contentWindow.postMessage(
121
123
  JSON.stringify({
122
124
  id: messageID,
123
- transform: `data:text/javascript;base64,${btoa(transform)}`,
125
+ exportName,
126
+ module,
124
127
  data,
125
128
  }),
126
129
  "*",
@@ -150,3 +153,10 @@ const makeSandbox = () => {
150
153
  });
151
154
  };
152
155
  export default makeSandbox;
156
+
157
+ let sandbox;
158
+ try {
159
+ sandbox = await makeSandbox();
160
+ } catch {}
161
+
162
+ export { sandbox };
package/lib/sprites.js CHANGED
@@ -16,10 +16,9 @@ export const handleStyleImageMissing = async (ev) => {
16
16
  }
17
17
  }
18
18
  if (builtin) {
19
- ev.target.addImage(
20
- ev.id,
21
- ev.target.getImage(builtin.slice(1, 3).join(":")).data,
22
- { sdf: true },
19
+ const { data, pixelRatio, sdf } = ev.target.getImage(
20
+ builtin.slice(1, 3).join(":"),
23
21
  );
22
+ ev.target.addImage(ev.id, data, { data, pixelRatio, sdf });
24
23
  }
25
24
  };
package/lib/style.js CHANGED
@@ -91,11 +91,15 @@ export async function getStyle(style, source) {
91
91
  } else if (typeof style.sprite === "string") {
92
92
  style.sprite = [{ id: "default", url: style.sprite }];
93
93
  }
94
+ const spritesheets = style.sprite.map(({ id }) => id);
94
95
  const extendedStyle = {
95
96
  ...parentStyle,
96
97
  ...style,
97
98
  sources: { ...parentStyle.sources, ...(style.sources || {}) },
98
- sprite: [...parentStyle.sprite, ...style.sprite],
99
+ sprite: [
100
+ ...parentStyle.sprite.filter(({ id }) => !spritesheets.includes(id)),
101
+ ...style.sprite,
102
+ ],
99
103
  layers,
100
104
  };
101
105
  return ensureSourceAndLayers(extendedStyle, source);
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "5.0.3",
6
+ "version": "6.0.0",
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": {
@@ -75,7 +75,7 @@
75
75
  "marked": "^14.1.2",
76
76
  "node-events": "^0.0.2",
77
77
  "normalize.css": "^8.0.1",
78
- "osmtogeojson": "^3.0.0-beta.5",
78
+ "osm2geojson-ultra": "^4.0.0",
79
79
  "pmtiles": "^3.2.0",
80
80
  "wkt": "^0.1.1",
81
81
  "yaml": "^2.5.1"
@@ -93,8 +93,12 @@
93
93
  "topicSeparator": " "
94
94
  },
95
95
  "jest": {
96
+ "transformIgnorePatterns": [
97
+ "node_modules/(?!osm2geojson-ultra)"
98
+ ],
96
99
  "transform": {
97
- "^.+\\.js$": "esbuild-jest"
100
+ "^.+\\.js$": "esbuild-jest",
101
+ "node_modules/.+\\.js$": "esbuild-jest"
98
102
  }
99
103
  }
100
104
  }