@trailstash/ultra 3.6.0 → 3.7.1

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.
@@ -0,0 +1,16 @@
1
+ ---
2
+ title: Add a title to a map
3
+ description: Use Ultra's HTMLControl to add a title to the map
4
+ controls:
5
+ - type: HTMLControl
6
+ options:
7
+ html: >
8
+ <h1><center>A Titled Map!</center></h1>
9
+ css: >
10
+ h1 {
11
+ position: fixed;
12
+ top: 0;
13
+ left: 0;
14
+ right: 0;
15
+ }
16
+ ---
@@ -0,0 +1,66 @@
1
+ ---
2
+ title: Add a custom modal control to the map
3
+ description: This adds an info button that opens a modal clicked using Ultra's HTMLControl
4
+ controls:
5
+ - type: NavigationControl
6
+ - type: HTMLControl
7
+ options:
8
+ html: >
9
+ <div class="maplibregl-ctrl maplibregl-ctrl-group">
10
+ <label for="info-modal">
11
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 192 512"><!--!Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M48 80a48 48 0 1 1 96 0A48 48 0 1 1 48 80zM0 224c0-17.7 14.3-32 32-32l64 0c17.7 0 32 14.3 32 32l0 224 32 0c17.7 0 32 14.3 32 32s-14.3 32-32 32L32 512c-17.7 0-32-14.3-32-32s14.3-32 32-32l32 0 0-192-32 0c-17.7 0-32-14.3-32-32z"/></svg>
12
+ </label>
13
+ </div>
14
+ <input type="checkbox" id="info-modal" checked></input>
15
+ <div class="info-modal">
16
+ <label for="info-modal" class="close">✕</label>
17
+ <h1>Information!</h1>
18
+ <p>
19
+ This is a simple way to add a information modal to your map.
20
+ </p>
21
+ <p>
22
+ To have it closed by default, remove the <code>checked</code> attribute from the checkbox <code>input</code>
23
+ </p>
24
+ </div>
25
+ css: >
26
+ .maplibregl-ctrl svg {
27
+ height: 16px;
28
+ width: 16px;
29
+ padding: 6.5px;
30
+ float: right;
31
+ }
32
+ .maplibregl-ctrl svg:hover {
33
+ background-color: rgba(0, 0, 0, 0.05);
34
+ }
35
+ label[for=info-modal] {
36
+ cursor: pointer;
37
+ }
38
+ label[for=info-modal].close {
39
+ float: right;
40
+ text-align: center;
41
+ height: 20px;
42
+ width: 20px;
43
+ display: block;
44
+ }
45
+ #info-modal {
46
+ display: none;
47
+ }
48
+ .info-modal {
49
+ display: none;
50
+ }
51
+ #info-modal:checked + .info-modal {
52
+ display: block;
53
+ position: fixed;
54
+ top: 0;
55
+ left: 0;
56
+ right: 0;
57
+ margin: 50px 20%;
58
+ padding: 20px;
59
+ background: white;
60
+ border-radius: 10px;
61
+ border: 1px solid grey;
62
+ pointer-events: initial;
63
+ box-shadow: 0 0 5px;
64
+ }
65
+ style: https://demotiles.maplibre.org/style.json
66
+ ---
@@ -0,0 +1,25 @@
1
+ ---
2
+ title: Use HTMLControl to add a link button to your map
3
+ description: This adds an info button that opens a link in a new window when clicked using Ultra's HTMLControl
4
+ controls:
5
+ - type: NavigationControl
6
+ - type: HTMLControl
7
+ options:
8
+ html: >
9
+ <div class="maplibregl-ctrl maplibregl-ctrl-group">
10
+ <a href="https://overpass-ultra.us/docs" target="_blank">
11
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 192 512"><!--!Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M48 80a48 48 0 1 1 96 0A48 48 0 1 1 48 80zM0 224c0-17.7 14.3-32 32-32l64 0c17.7 0 32 14.3 32 32l0 224 32 0c17.7 0 32 14.3 32 32s-14.3 32-32 32L32 512c-17.7 0-32-14.3-32-32s14.3-32 32-32l32 0 0-192-32 0c-17.7 0-32-14.3-32-32z"/></svg>
12
+ </a>
13
+ </div>
14
+ css: >
15
+ .maplibregl-ctrl svg {
16
+ height: 16px;
17
+ width: 16px;
18
+ padding: 6.5px;
19
+ float: right;
20
+ }
21
+ .maplibregl-ctrl svg:hover {
22
+ background-color: rgba(0, 0, 0, 0.05);
23
+ }
24
+ style: https://demotiles.maplibre.org/style.json
25
+ ---
@@ -0,0 +1,74 @@
1
+ import DOMPurify from "dompurify";
2
+
3
+ import { h } from "../lib/dom.js";
4
+ import { normalizeCSS } from "../lib/normalize.js";
5
+ import maplibreglStyle from "maplibre-gl/dist/maplibre-gl.css";
6
+
7
+ const maplibreCSS = new CSSStyleSheet();
8
+ maplibreCSS.replaceSync(`
9
+ ${maplibreglStyle}
10
+ /* override inset(top/left/bottom/right) & position bc nestin in existing controlgroup corner */
11
+ .maplibregl-ctrl-top-right,
12
+ .maplibregl-ctrl-top-left,
13
+ .maplibregl-ctrl-bottom-right,
14
+ .maplibregl-ctrl-bottom-left {
15
+ inset: initial;
16
+ position: initial;
17
+ }
18
+ `);
19
+
20
+ export class HTMLControl extends HTMLElement {
21
+ static observedAttributes = ["css", "html"];
22
+
23
+ get css() {
24
+ return this.getAttribute("css");
25
+ }
26
+ set css(value) {
27
+ return this.setAttribute("css", value);
28
+ }
29
+
30
+ get html() {
31
+ return this.getAttribute("html");
32
+ }
33
+ set html(value) {
34
+ return this.setAttribute("html", value);
35
+ }
36
+
37
+ constructor(options) {
38
+ super();
39
+ if (options) {
40
+ const { html, css } = options;
41
+ this.html = html;
42
+ this.css = css;
43
+ }
44
+ }
45
+ onAdd(map) {
46
+ this._map = map;
47
+ this._container = h("html-control");
48
+ if (this.html) this._container.html = this.html;
49
+ if (this.css) this._container.css = this.css;
50
+
51
+ return this._container;
52
+ }
53
+ onRemove() {
54
+ this.container.parentNode.removeChild(this.container);
55
+ this.map = undefined;
56
+ }
57
+
58
+ connectedCallback() {
59
+ const shadow = this.attachShadow({ mode: "open" });
60
+
61
+ // Add styles: Normalize, MapLibre, & User-specified
62
+ shadow.adoptedStyleSheets.push(normalizeCSS);
63
+ shadow.adoptedStyleSheets.push(maplibreCSS);
64
+ const style = new CSSStyleSheet();
65
+ style.replaceSync(this.css);
66
+ shadow.adoptedStyleSheets.push(style);
67
+
68
+ // Wrap in a div with the same className as parent so that control position CSS works
69
+ const container = h("div", { className: this.parentElement.className });
70
+ container.innerHTML = DOMPurify.sanitize(this.html);
71
+
72
+ shadow.appendChild(container);
73
+ }
74
+ }
@@ -14,6 +14,7 @@ import { getStyle } from "../lib/style.js";
14
14
  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
+ import { HTMLControl } from "./html-control.js";
17
18
 
18
19
  const css = new CSSStyleSheet();
19
20
  css.replaceSync(`
@@ -65,7 +66,7 @@ export class UltraMap extends HTMLElement {
65
66
  querySources = UltraMap.defaults.querySources;
66
67
 
67
68
  options = UltraMap.defaults.options;
68
- controls = UltraMap.defaults.controls;
69
+ #controls = UltraMap.defaults.controls;
69
70
 
70
71
  fitBounds = UltraMap.defaults.fitBounds;
71
72
 
@@ -119,6 +120,18 @@ export class UltraMap extends HTMLElement {
119
120
  get center() {
120
121
  return this.refs?.mapLibre?.center;
121
122
  }
123
+ get controls() {
124
+ return this.#controls;
125
+ }
126
+ set controls(value) {
127
+ this.#controls = value.map
128
+ ? value.map(({ type, options, position }) =>
129
+ type === "HTMLControl"
130
+ ? { type: new HTMLControl(options), position }
131
+ : { type, options, position },
132
+ )
133
+ : value;
134
+ }
122
135
 
123
136
  connectedCallback() {
124
137
  this.#shadow = this.attachShadow({ mode: "open" });
Binary file
package/docs/index.md CHANGED
@@ -43,8 +43,8 @@ style:
43
43
  }
44
44
  ```
45
45
 
46
- For more examples, see the [Examples](./Examples) and [MapLibre Examples](./MapLibre-Examples)
47
- sections.
46
+ For more examples, see the [Examples](./Examples/index.md) and [MapLibre
47
+ Examples](./MapLibre-Examples/index.md) sections.
48
48
 
49
49
  ## Configuration
50
50
 
@@ -0,0 +1,123 @@
1
+ # Mapping Resources
2
+
3
+ ## Query Data
4
+
5
+ There are many sources of query data for use with Ultra.
6
+
7
+ ### OpenStreetMap
8
+
9
+ Ultra was initially made to visualize OSM data via [Overpass](#overpass) queries. OSM continues to
10
+ be an excellent source of data for Ultra, and can be consumed in more ways than one.
11
+
12
+ #### Overpass
13
+
14
+ [OverpassQL](https://wiki.openstreetmap.org/wiki/Overpass_API/Overpass_QL) or [Overpass
15
+ XML](https://wiki.openstreetmap.org/wiki/Overpass_API/Language_Guide) queries are supported by the
16
+ [`overpass` query provider](./yaml.md#overpass).
17
+
18
+ #### Ohsome
19
+
20
+ The [ohsome API](https://api.ohsome.org) can be used via the [`ohsome` query
21
+ provider](./yaml.md#ohsome) to loader quanties of OSM data with a simpler [filtering
22
+ syntax](https://docs.ohsome.org/ohsome-api/v1/filter.html) than Overpass.
23
+
24
+ #### Bunting Labs
25
+ Using [separate N/S/E/W bbox
26
+ placeholders](./query-shortcuts.md#other-formats), the [`geojson`
27
+ provider](./yaml.md#geojson) can load data from the [Bunting Labs
28
+ API](https://buntinglabs.com/solutions/openstreetmap-extracts)
29
+
30
+ #### OSM API
31
+ The [`osmxml`](./yaml.md#osmxml) and [`osmjson`](./yaml.md#osmjson) providers can load data
32
+ directly from the [OSM API](https://wiki.openstreetmap.org/wiki/API_v0.6).
33
+
34
+ #### Tiles
35
+ There are a variety of providers of tiled OSM data.
36
+
37
+ ##### OpenStreetMap US Tileserver
38
+
39
+ Née the [OSM Americana](https://americanamap.org/) Community Vector Tile Server, [OSM
40
+ US](https://openstreetmap.us) hosts [OpenMapTiles](https://openmaptiles.org) on
41
+ [tile.ourmap.us](https://tile.ourmap.us). For usage, see their
42
+ [policy](https://tile.ourmap.us/usage.html).
43
+
44
+ ### Google My Maps
45
+
46
+ The [`kml` provider](./yaml.md#kml) can directly load Google My Maps URLs.
47
+
48
+ ### Natural Earth
49
+
50
+ [Natural Earth Data](https://www.naturalearthdata.com/) data is available as GeoJSON from the
51
+ [geojson.xyz CDN](https://geojson.xyz)
52
+
53
+ ### Wilderness.net
54
+
55
+ [Wilderness.net](https://wilderness.net) provides GIS data for Wildernes Areas in the USA. The data
56
+ files need to be downloaded, converted to tiles or GeoJSON, and hosted before using them with Ultra
57
+
58
+ * [Downloads Page](https://wilderness.net/visit-wilderness/gis-gps.php)
59
+ * [Shapefile](https://www.wilderness.net/GIS/Wilderness_Areas.zip)
60
+ * [state KMZs](https://wilderness.net/visit-wilderness/google-earth.php)
61
+
62
+ ### All The Places
63
+
64
+ [All The Places](https://alltheplaces.xyz) provides GeoJSON files for a many retail establishments,
65
+ scraped from their websites.
66
+
67
+ ATP doesn't serve the files with [CORS
68
+ headers](https://developer.mozilla.org/en-US/docs/Glossary/CORS), so you must re-host them with the
69
+ appropriate headers yourself.
70
+
71
+ ### Overture Maps
72
+
73
+ The [Overture foundation](https://overturemaps.org/) makes map data derived from various sources
74
+ available. It needs to be processed and hosted before use with Ultra.
75
+
76
+ ## Base Style resources
77
+
78
+ ### TrailStash Style Server
79
+
80
+ Most of the styles made available in the **Style Picker** menu on
81
+ [overpass-ultra.us](https://overpass-ultra.us) are hosted on
82
+ [styles.trailsta.sh](https://styles.trailsta.sh).
83
+
84
+ #### OpenMapTiles Styles
85
+
86
+ Most of the [OpenMapTiles Styles](https://openmaptiles.org/styles/) are available, with fonts and
87
+ sprites hosted along-side the style, and tiles hosted by the [OSM US Tile
88
+ Server](#openstreetmap-us-tileserver).
89
+
90
+ #### Protomaps
91
+
92
+ The light, dark, white, grey, black variants and the community "contrast" varaint of the Protomaps
93
+ styles are available, with fonts and sprites hosted by the [protomaps basemaps assets
94
+ repo](https://github.com/protomaps/basemaps-assets) and tiles hosted by the [Protomaps
95
+ API](https://protomaps.com)
96
+
97
+ #### Esri Satellite
98
+
99
+ A style using [Esri World
100
+ Imagery](https://www.arcgis.com/home/item.html?id=10df2279f9684e4a9f6a7f08febac2a9) is available.
101
+
102
+ ### Natural Earth
103
+
104
+ The [TrailStash fork](https://trailstash.github.io/naturalearthtiles/) of [Lukas Martinelli's
105
+ Natural Earth Tiles](https://github.com/lukasmartinelli/naturalearthtiles) includes a MapLibre
106
+ vector style.
107
+
108
+ ### Versatiles
109
+
110
+ [Versatiles](https://versatiles.org/intro.html) provides a few styles based on the [Shortbread
111
+ Schema](https://shortbread-tiles.org/), free for use anywhere.
112
+
113
+ ### OpenFreeMap
114
+
115
+ [OpenFreeMap](https://openfreemap.org/quick_start/) provides a few styles based on the [OpenMapTile
116
+ schema](https://openmaptiles.org/schema/) free for use
117
+ anywhere.
118
+
119
+ ### Commercial Providers
120
+
121
+ Any MapLibre style provider can be used with Ultra. See [Awesome
122
+ MapLibre](https://github.com/maplibre/awesome-maplibre?tab=readme-ov-file#maptile-providers) for a
123
+ more comprehensive list of MapLibre style providers.
package/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ import DOMPurify from "dompurify";
1
2
  import { Protocol } from "pmtiles";
2
3
  import MapLibre from "@trailstash/maplibre-component";
3
4
  import maplibregl from "maplibre-gl";
@@ -5,6 +6,7 @@ import maplibregl from "maplibre-gl";
5
6
  import { normalizeCSS } from "./lib/normalize.js";
6
7
  import FallbackGlyphProtocol from "./lib/glyphFallback.js";
7
8
 
9
+ import { HTMLControl } from "./components/html-control.js";
8
10
  import { UltraLoader } from "./components/ultra-loader.js";
9
11
  import { UltraMap } from "./components/ultra-map.js";
10
12
  import { UltraIDE } from "./components/ultra-ide.js";
@@ -20,6 +22,15 @@ import { FontAwesomeIcon } from "./components/fontawesome-icon.js";
20
22
  import { ButtonModal } from "./components/button-modal.js";
21
23
  import { MapPopup } from "./components/map-popup.js";
22
24
 
25
+ // Allow pages in new windows securely
26
+ DOMPurify.addHook("afterSanitizeAttributes", function (node) {
27
+ // set all elements owning target to target=_blank
28
+ if ("target" in node) {
29
+ node.setAttribute("target", "_blank");
30
+ node.setAttribute("rel", "noopener");
31
+ }
32
+ });
33
+
23
34
  // style
24
35
  document.adoptedStyleSheets.push(normalizeCSS);
25
36
 
@@ -48,6 +59,7 @@ customElements.define("map-popup", MapPopup);
48
59
  customElements.define("ultra-map", UltraMap);
49
60
  customElements.define("ultra-ide", UltraIDE);
50
61
  customElements.define("ultra-loader", UltraLoader);
62
+ customElements.define("html-control", HTMLControl);
51
63
 
52
64
  // reload on hash changes
53
65
  addEventListener("hashchange", () => window.location.reload());
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "3.6.0",
6
+ "version": "3.7.1",
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": {