Skip to content

Commit b48c47b

Browse files
committed
WIP document new search control
1 parent 34c7d03 commit b48c47b

9 files changed

Lines changed: 7498 additions & 6778 deletions

File tree

docs/api/mapml-viewer-api.mdx

Lines changed: 82 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@ The HTMLMapmlViewerElement interface represents the `<mapml-viewer>` element.
1313

1414
| Property name | Description |
1515
|-------------- |-------------------------------------------------------- |
16-
| [controls](#controls) | Turns native map controls on or off. Reflects the controls attribute. |
17-
| [controlsList](#controlslist) | Allows to change the set of native controls. Reflects the controlslist attribute. |
16+
| [controls](#controls) | Turns native map controls on or off. Reflects the `controls` attribute. |
17+
| [controlsList](#controlslist) | Allows to change the set of native controls with script. Note use of camelCase of the property name vs lowercase attribute name. Reflects the `controlslist` attribute. |
1818
| [extent](#extent) | Returns the extent of the current map view. Read only. |
1919
| [lat](#lat) | Get or set the map's latitude. Reflects to the lat content attribute. No effect on map dynamic state. |
2020
| [lon](#lon) | Get or set the map's longitude. Reflects to the lon content attribute. No effect on map dynamic state. |
21-
| [projection](#projection) | The map's projection. Reflects the projection attribute. |
22-
| [zoom](#zoom) | Get or set the map's zoom level. Reflects to the zoom content attribute. No effect on map dynamic state. |
21+
| [projection](#projection) | The map's projection. Reflects the `projection` attribute. |
22+
| [zoom](#zoom) | Get or set the map's zoom level. Reflects to the `zoom` content attribute. No effect on map dynamic state. |
2323

2424
### controls
2525

@@ -45,8 +45,10 @@ that helps the user select what controls to display on the `mapml-viewer` elemen
4545
To set the controlslist attribute:
4646
```js
4747
let map = document.querySelector('mapml-viewer');
48-
map.controlsList.value = "noreload nozoom"; // values can be noreload | nofullscreen | nozoom | nolayer
48+
map.controlsList.value = "noreload nozoom"; // values can be noreload | nofullscreen | nozoom | nolayer | search | geolocation
4949
map.controlsList.add("nofullscreen"); // can also add using the 'add' method
50+
map.controlsList.add("geolocation"); // adds the locate control
51+
map.controlsList.add("search"); // adds the search control, disabled until a search URL template link is defined
5052
map.controlsList.toggle("nolayer"); // can also toggle using the 'toggle' method
5153
// view all methods here - https://developer.mozilla.org/en-US/docs/Web/API/DOMTokenList
5254
```
@@ -406,6 +408,79 @@ state of the queried map properties (projection, zoom, extent); any change to th
406408
| zoomend | Fired after the map has changed zoom level |
407409
| preclick | Fired before a click on the map is triggered. May not be a primitive. |
408410
| contextmenu | Fired when user right-clicks or long presses on map. May not be a primitive.|
411+
| [mapsearch](#mapsearch) | Fired after search responses arrive from all search-enabled layers. |
412+
| [mapsuggestions](#mapsuggestions) | Fired after typeahead suggestion responses arrive from all search-enabled layers. |
413+
414+
### mapsearch
415+
416+
Fired on the `<mapml-viewer>` element after search responses have been received
417+
from all checked layers that contain a
418+
[`<map-link rel="search">`](../elements/link/#rel). Triggered when the user
419+
presses **Enter** in the search input **or selects a suggestion** from the
420+
typeahead dropdown (selecting a suggestion uses the suggestion's display text as
421+
a search query). The event bubbles and is cancelable.
422+
423+
The `e.detail` structure is identical to [`mapsuggestions`](#mapsuggestions).
424+
425+
By default, the built-in `mapsearch` event handler renders a list of clickable
426+
results in the search panel, navigates to the first result, and keeps focus on
427+
the search input. For each feature it expects `e.detail.responses[].data` to be
428+
a **GeoJSON FeatureCollection** and looks for:
429+
430+
- **Display name** — uses `properties.display_name` if present; otherwise
431+
builds a comma-separated string from `properties.name`, `city`, `county`,
432+
`state`, and `country` (skipping duplicates of `name`). Falls back to
433+
`"Unnamed"`.
434+
- **Map navigation** — zooms and pans to fit `feature.bbox`
435+
(`[west, south, east, north]`), falling back to `properties.extent` (same
436+
format). If neither is available, centers the map on the first
437+
`geometry.coordinates` (`[lon, lat]`) value at `properties.zoom` (default `14`).
438+
439+
Call `e.preventDefault()` to suppress the default navigation and handle results
440+
yourself.
441+
442+
```js
443+
let map = document.querySelector('mapml-viewer');
444+
map.addEventListener('mapsearch', (e) => {
445+
e.preventDefault(); // take over result handling
446+
const { query, responses } = e.detail;
447+
for (const { data, layer } of responses) {
448+
// data is the JSON returned by the search endpoint
449+
for (const feature of data.features) {
450+
console.log(feature.properties.display_name, feature.bbox);
451+
}
452+
}
453+
});
454+
```
455+
456+
---
457+
458+
### mapsuggestions
459+
460+
Fired on the `<mapml-viewer>` element after suggestions responses have been
461+
received from all checked layers that contain a
462+
[`<map-link rel="suggestions">`](../elements/link/#rel). The event bubbles and
463+
is cancelable.
464+
465+
| `e.detail` property | Description |
466+
|---------------------|-------------|
467+
| `query` | The search string the user typed. |
468+
| `responses` | An array of `{ data, link, layer }` objects — one per responding layer. `data` is the parsed JSON response, `link` is the originating `<map-link>` element, and `layer` is the `<map-layer>` element. |
469+
470+
Call `e.preventDefault()` to suppress the built-in suggestion dropdown and
471+
handle results yourself.
472+
473+
```js
474+
let map = document.querySelector('mapml-viewer');
475+
map.addEventListener('mapsuggestions', (e) => {
476+
e.preventDefault(); // take over rendering
477+
const { query, responses } = e.detail;
478+
for (const { data, layer } of responses) {
479+
// data is the JSON returned by the suggestions endpoint
480+
console.log(layer.label, data);
481+
}
482+
});
483+
```
409484

410485
---
411486

@@ -773,6 +848,8 @@ let output = map.geojson2mapml(json);
773848
|:---------------------------------------------------------------------------------|:------: |:-----: |:---: |
774849
| [**Properties**](#properties) | full | full | full |
775850
| [**Methods**](#methods) | partial * | full | partial * |
851+
| [**Interpreting locations and map positions (5.3)**](https://maps4html.org/HTML-Map-Element-UseCases-Requirements/#map-viewers-capabilities-locations) | | | |
852+
| <div class="undecided">[Select map view from street address or place name (5.3.2)](https://github.com/Maps4HTML/HTML-Map-Element-UseCases-Requirements/issues/145)</div> | full | [full](https://maps4html.org/web-map-doc/docs/user-guide/search) | [full](#events) |
776853

777854
<details>
778855
<summary>Exceptions *</summary>

docs/elements/link.md

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ maps. Most of the extensions center on proposed new values of the `rel` attribu
1616
- include links to legend graphics for a layer. Currently such links are rendered as hyperlinks, not as graphics.
1717
- provide links to CSS and pmtiles stylesheets via the `stylesheet` rel value, which are imported by the polyfill automatically.
1818
- provide links to layers at next native zoom level via `zoomin`, `zoomout` rel values. Such links are automatically followed by the polyfill when appropriate.
19+
- links provide URL templates (in the `tref` attribute) for georeferenced search endpoints via the `search` rel value, and for typeahead/autocomplete via the `suggestions` rel value. These links power the [search control](../../user-guide/search) when it is [enabled](../mapml-viewer/#controlslist) on the viewer.
1920

2021
<!-- demo / example -->
2122
<iframe src="../../../demo/map-link-demo/" title="MapML Demo" height="410" width="100%" scrolling="no" frameBorder="0"></iframe>
@@ -42,6 +43,8 @@ defines several uses of existing and new `rel` keyword values.
4243
| `legend` | The `legend` link relation designates a link to metadata, typically an image, describing the symbology used by the current layer. Currently, the polyfill creates a hyperlink for the label of the layer in the layer control, which opens in a new browsing context. |
4344
| `query` | The `query` link relation is used in combination with the `tref="..."` attribute to establish a URL template that composes a map query URL based on user map gestures such as click or touch. These URLs are fetched and the response presented on top of the map as a popup. Such queries can return text/html or text/mapml responses. In the latter case, the response may contain more than one feature, in which case a 'paged' popup is generated, allowing the user to cycle through the features' individual metadata. |
4445
| `stylesheet` | The link imports a CSS or [pmtiles](../../user-guide/creating-styles) stylesheet from the `href` value. |
46+
| `search` | The `tref` attribute contains a URL template for a georeferenced search endpoint. The `tref` attribute must contain a `{searchTerms}` variable reference that is substituted with the user's query. Only the first `search` link per layer is used. A layer must provide a `search` link for the search control to become enabled. See [Search](../../user-guide/search). |
47+
| `suggestions` | The `tref` attribute contains a URL template for a typeahead / autocomplete endpoint. Uses the same `{searchTerms}` substitution as `search`. A suggestions link is optional but recommended: when present, results appear as the user types (debounced). Only the first `suggestions` link per layer is used. See [Search](../../user-guide/search). |
4548

4649

4750
---
@@ -104,14 +107,18 @@ Advisory [language designation](https://datatracker.ietf.org/doc/html/rfc5646) a
104107
The `tref` attribute contains a string that, once processed, will be treated as
105108
a URL and fetched automatically by the polyfill. The string is known as a URL
106109
template. The processing that takes place prior to a URL template becoming a
107-
valid URL is _variable reference substitution_. Variables are created by
108-
`<map-input name="foo">` elements. The name of the variable can be
110+
valid URL is _variable reference substitution_. Variables are usually created
111+
and named by `<map-input name="foo">` elements. The name of the variable can be
109112
referenced in the URL template string contained in the `tref` value, using the
110113
`{foo}` syntax notation. A URL template string can contain 0 or more variable
111-
references. Processing will remove variable references that are valid. That is,
114+
references. Processing will resolve variable references that are valid. That is,
112115
all variables that have been created by `<map-input>`s that are referenced in the
113116
template will be replaced with the value of the variable at the time of processing.
114117

118+
For link `rel` values `search` or `suggestions`, the variable `searchTerms` is **predefined**
119+
and bound to user text input from the search control form. The variable should be
120+
used in the `tref` attribute URL template, via the `{searchTerms}` variable reference.
121+
115122
---
116123
### `tms`
117124

@@ -161,6 +168,46 @@ and [extent](../../api/mapml-viewer-api#extent).
161168

162169
## Examples
163170

171+
### Search and suggestions
172+
173+
In a remote MapML document, `search` and `suggestions` links are children of `<map-head>`:
174+
175+
```html
176+
<map-head>
177+
<map-link rel="search"
178+
tref="https://photon.komoot.io/api/?q={searchTerms}&limit=5" />
179+
<map-link rel="suggestions"
180+
tref="https://photon.komoot.io/api/?q={searchTerms}&limit=5" />
181+
</map-head>
182+
```
183+
184+
Within inline in HTML, the `search` and `suggestions` links are direct children of the `<map-layer>` element:
185+
186+
```html
187+
<mapml-viewer projection="OSMTILE" zoom="3" lat="45" lon="-75"
188+
controls controlslist="search">
189+
<map-layer label="OpenStreetMap" checked>
190+
<map-link rel="search"
191+
tref="https://photon.komoot.io/api/?q={searchTerms}&limit=5" />
192+
<map-link rel="suggestions"
193+
tref="https://photon.komoot.io/api/?q={searchTerms}&limit=5" />
194+
<map-extent units="OSMTILE" checked hidden>
195+
<map-input name="z" type="zoom" min="0" max="18" value="3" />
196+
<map-input name="x" type="location" axis="column" units="tilematrix" />
197+
<map-input name="y" type="location" axis="row" units="tilematrix" />
198+
<map-link rel="tile"
199+
tref="https://tile.openstreetmap.org/{z}/{x}/{y}.png" />
200+
</map-extent>
201+
</map-layer>
202+
</mapml-viewer>
203+
```
204+
205+
The search control is disabled until at least one `checked` layer provides
206+
a `<map-link rel="search">`. The `suggestions` link is optional — without it the
207+
control still works but only returns results on submission.
208+
209+
---
210+
164211
### Tile Mapping Specification (tms)
165212

166213
```html
@@ -206,6 +253,8 @@ and [extent](../../api/mapml-viewer-api#extent).
206253

207254
| | Spec | Viewer | API |
208255
|:---------------------------------------------------------------------------------|:------: |:-----: |:---: |
256+
| [**Interpreting locations and map positions (5.3)**](https://maps4html.org/HTML-Map-Element-UseCases-Requirements/#map-viewers-capabilities-locations) | | | |
257+
| <div class="undecided">[Select map view from street address or place name (5.3.2)](https://github.com/Maps4HTML/HTML-Map-Element-UseCases-Requirements/issues/145)</div> | full | [full](https://maps4html.org/web-map-doc/docs/user-guide/search) | [full](https://maps4html.org/web-map-doc/docs/api/mapml-viewer-api#events) |
209258
| [**Vector features and overlays (5.2)**](https://maps4html.org/HTML-Map-Element-UseCases-Requirements/#map-viewers-capabilities-vectors) | | | |
210259
| <div class="requirement">Display map data attribution and links (5.2.4)</div> | full | full | |
211260
| [**User navigation (pan and zoom) (5.4)**](https://maps4html.org/HTML-Map-Element-UseCases-Requirements/#map-viewers-capabilities-user-navigation) | | | |

docs/elements/mapml-viewer.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ The `<mapml-viewer>` element is the main element you can use to put a custom Web
2222
</style>
2323
</head>
2424
<body>
25-
<mapml-viewer projection="OSMTILE" zoom="0" lat="0.0" lon="0.0" controls>
25+
<mapml-viewer projection="OSMTILE" zoom="0" lat="0.0" lon="0.0" controls controlslist="geolocation search">
2626
<map-layer label="OpenStreetMap" src="https://geogratis.gc.ca/mapml/en/osmtile/osm/" checked></map-layer>
2727
</mapml-viewer>
2828
</body>
@@ -82,7 +82,9 @@ The default projection is `OSMTILE`.
8282

8383
### `controlslist`
8484

85-
`controlslist` - an enumerated attribute, possible values are: "`nofullscreen`", "`nolayer`", "`noreload`", "`noscale`" and "`nozoom`". Occasionally, you may not want your users to have access to a particular control, so you may prune the set of controls automatically presented (when you have used the `controls` boolean attribute).
85+
`controlslist` - an enumerated attribute, possible values are: "`nofullscreen`", "`nolayer`", "`noreload`", "`noscale`", "`nozoom`", "`geolocation`" and "`search`". The `no*` tokens let you prune the set of controls automatically presented (when you have used the `controls` boolean attribute), while unlike the `no*` tokens (which hide default controls), the `geolocation` and `search` tokens are **opt-in**. `geolocation` and `search` add location and search controls to the map, respectively. The search control is `disabled` by default, and becomes enabled only when at least one `checked` [`<map-layer>`](../layer/) contains a [`<map-link rel="search">`](../link/) element.
86+
87+
For a full guide to configuring and customizing search, see the [Search user guide](../../user-guide/search).
8688

8789
---
8890

@@ -132,8 +134,7 @@ present. When it is not present or removed, these features are enabled again.
132134
| <div class="requirement">Display a basic map without JavaScript (5.1.5)</div> | full | [limited](https://maps4html.org/experiments/progressive-enhancement/) | |
133135
| <div class="requirement">Display map content in a users preferred language (5.1.6)</div> | [full](https://github.com/Maps4HTML/HTML-Map-Element-UseCases-Requirements/issues/136) | [full](https://github.com/Maps4HTML/mapml-extension) | |
134136
| [**Interpreting locations and map positions (5.3)**](https://maps4html.org/HTML-Map-Element-UseCases-Requirements/#map-viewers-capabilities-locations) | | | |
135-
| <div class="requirement">Select map view from latitude and longitude point (5.3.1)</div> | full | full | [full](https://maps4html.org/web-map-doc/docs/api/mapml-viewer-api#zoomtolat-lon-zoom) |
136-
| <div class="undecided">Display map tiles defined in various common coordinate systems (5.3.3)</div> | [full](https://github.com/Maps4HTML/HTML-Map-Element-UseCases-Requirements/issues/14) | full | [full](https://maps4html.org/web-map-doc/docs/api/custom-projections) |
137+
| <div class="requirement">Select map view from latitude and longitude point (5.3.1)</div> | full | full | [full](https://maps4html.org/web-map-doc/docs/api/mapml-viewer-api#zoomtolat-lon-zoom) || <div class="undecided">[Select map view from street address or place name (5.3.2)](https://github.com/Maps4HTML/HTML-Map-Element-UseCases-Requirements/issues/145)</div> | full | [full](https://maps4html.org/web-map-doc/docs/user-guide/search) | [full](https://maps4html.org/web-map-doc/docs/api/mapml-viewer-api#events) || <div class="undecided">Display map tiles defined in various common coordinate systems (5.3.3)</div> | [full](https://github.com/Maps4HTML/HTML-Map-Element-UseCases-Requirements/issues/14) | full | [full](https://maps4html.org/web-map-doc/docs/api/custom-projections) |
137138
| <div class="undecided">Reproject map tile data into a new projection or globe view (5.3.4)</div> | [under discussion](https://github.com/Maps4HTML/HTML-Map-Element-UseCases-Requirements/issues/3) | none | |
138139
| <div class="undecided">Save the location or export to other application (5.3.5)</div> | limited | limited | |
139140
| [**User navigation (pan and zoom) (5.4)**](https://maps4html.org/HTML-Map-Element-UseCases-Requirements/#map-viewers-capabilities-user-navigation) | | | |

0 commit comments

Comments
 (0)