Skip to content

Commit 2e59beb

Browse files
prushforthPeter Rushforth
authored andcommitted
Add search control documentation
1 parent 2426d53 commit 2e59beb

17 files changed

Lines changed: 8214 additions & 6798 deletions

File tree

docs/api/mapml-viewer-api.mdx

Lines changed: 97 additions & 6 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
```
@@ -221,7 +223,8 @@ let zoom = map.zoom;
221223
| [viewSource()](#viewsource) | View the source of the map. |
222224
| [defineCustomProjection(options)](#definecustomprojectionoptions) | Define a custom projection for use by the page. |
223225
| [zoomTo(lat, lon, zoom)](#zoomtolat-lon-zoom) | Fly or pan the map to a (new) location and zoom level.|
224-
| [geojson2mapml(json, options)](#zoomtolat-lon-zoom) | Add a GeoJSON Layer to the map. |
226+
| [zoomToExtent(west, south, east, north)](#zoomtoextentwest-south-east-north) | Fit the map view to a geographic extent. |
227+
| [geojson2mapml(json, options)](#geojson2mapml) | Add a GeoJSON Layer to the map. |
225228
| [matchMedia(mediaQueryString)](#matchmediamediaquerystring) | Returns a [MediaQueryList](https://developer.mozilla.org/en-US/docs/Web/API/MediaQueryList)-like object.
226229

227230

@@ -328,6 +331,19 @@ navigator.geolocation.getCurrentPosition(success, error, options);
328331

329332
---
330333

334+
### zoomToExtent(west, south, east, north)
335+
336+
Fit the map view to the geographic extent defined by the four coordinate values,
337+
automatically choosing the appropriate maximum zoom level.
338+
339+
```js
340+
let map = document.querySelector('mapml-viewer');
341+
// Fit the map to show southern Ontario
342+
map.zoomToExtent(-80, 43, -70, 48);
343+
```
344+
345+
---
346+
331347
### geojson2mapml(json, options)
332348

333349
Convert a GeoJSON feature or feature collection string or object to MapML [`<map-layer>`](/web-map-doc/docs/elements/layer/) containing one or more [`<map-feature>`](/web-map-doc/docs/elements/feature/) elements. Returns and adds the converted layer element to the map.
@@ -406,6 +422,79 @@ state of the queried map properties (projection, zoom, extent); any change to th
406422
| zoomend | Fired after the map has changed zoom level |
407423
| preclick | Fired before a click on the map is triggered. May not be a primitive. |
408424
| contextmenu | Fired when user right-clicks or long presses on map. May not be a primitive.|
425+
| [mapsearch](#mapsearch) | Fired after search responses arrive from all search-enabled layers. |
426+
| [mapsuggestions](#mapsuggestions) | Fired after typeahead suggestion responses arrive from all search-enabled layers. |
427+
428+
### mapsearch
429+
430+
Fired on the `<mapml-viewer>` element after search responses have been received
431+
from all checked layers that contain a
432+
[`<map-link rel="search">`](../elements/link/#rel). Triggered when the user
433+
presses **Enter** in the search input **or selects a suggestion** from the
434+
typeahead dropdown (selecting a suggestion uses the suggestion's display text as
435+
a search query). The event bubbles and is cancelable.
436+
437+
The `e.detail` structure is identical to [`mapsuggestions`](#mapsuggestions).
438+
439+
By default, the built-in `mapsearch` event handler renders a list of clickable
440+
results in the search panel, navigates to the first result, and keeps focus on
441+
the search input. For each feature it expects `e.detail.responses[].data` to be
442+
a **GeoJSON FeatureCollection** and looks for:
443+
444+
- **Display name** — uses `properties.display_name` if present; otherwise
445+
builds a comma-separated string from `properties.name`, `city`, `county`,
446+
`state`, and `country` (skipping duplicates of `name`). Falls back to
447+
`"Unnamed"`.
448+
- **Map navigation** — zooms and pans to fit `feature.bbox`
449+
(`[west, south, east, north]`), falling back to `properties.extent` (same
450+
format). If neither is available, centers the map on the first
451+
`geometry.coordinates` (`[lon, lat]`) value at `properties.zoom` (default `14`).
452+
453+
Call `e.preventDefault()` to suppress the default navigation and handle results
454+
yourself.
455+
456+
```js
457+
let map = document.querySelector('mapml-viewer');
458+
map.addEventListener('mapsearch', (e) => {
459+
e.preventDefault(); // take over result handling
460+
const { query, responses } = e.detail;
461+
for (const { data, layer } of responses) {
462+
// data is the JSON returned by the search endpoint
463+
for (const feature of data.features) {
464+
console.log(feature.properties.display_name, feature.bbox);
465+
}
466+
}
467+
});
468+
```
469+
470+
---
471+
472+
### mapsuggestions
473+
474+
Fired on the `<mapml-viewer>` element after suggestions responses have been
475+
received from all checked layers that contain a
476+
[`<map-link rel="suggestions">`](../elements/link/#rel). The event bubbles and
477+
is cancelable.
478+
479+
| `e.detail` property | Description |
480+
|---------------------|-------------|
481+
| `query` | The search string the user typed. |
482+
| `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. |
483+
484+
Call `e.preventDefault()` to suppress the built-in suggestion dropdown and
485+
handle results yourself.
486+
487+
```js
488+
let map = document.querySelector('mapml-viewer');
489+
map.addEventListener('mapsuggestions', (e) => {
490+
e.preventDefault(); // take over rendering
491+
const { query, responses } = e.detail;
492+
for (const { data, layer } of responses) {
493+
// data is the JSON returned by the suggestions endpoint
494+
console.log(layer.label, data);
495+
}
496+
});
497+
```
409498

410499
---
411500

@@ -773,6 +862,8 @@ let output = map.geojson2mapml(json);
773862
|:---------------------------------------------------------------------------------|:------: |:-----: |:---: |
774863
| [**Properties**](#properties) | full | full | full |
775864
| [**Methods**](#methods) | partial * | full | partial * |
865+
| [**Interpreting locations and map positions (5.3)**](https://maps4html.org/HTML-Map-Element-UseCases-Requirements/#map-viewers-capabilities-locations) | | | |
866+
| <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) |
776867

777868
<details>
778869
<summary>Exceptions *</summary>

docs/elements/link.md

Lines changed: 69 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ maps. Most of the extensions center on proposed new values of the `rel` attribu
1515
- provide a URL template that is processed and converted to a URL and fetched by the polyfill, each time the map requires new content to render, such as a tile, via the `tile`, `image`, `feature` and `query` rel values, in conjunction with the `tref="..."` attribute. Such links are automatically created and followed / imported when appropriate.
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.
18-
- provide links to layers at next native zoom level via `zoomin`, `zoomout` rel values. Such links are automatically followed by the polyfill when appropriate.
18+
- 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.
1919

2020
<!-- demo / example -->
2121
<iframe src="../../../demo/map-link-demo/" title="MapML Demo" height="410" width="100%" scrolling="no" frameBorder="0"></iframe>
@@ -42,6 +42,8 @@ defines several uses of existing and new `rel` keyword values.
4242
| `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. |
4343
| `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. |
4444
| `stylesheet` | The link imports a CSS or [pmtiles](../../user-guide/creating-styles) stylesheet from the `href` value. |
45+
| `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). |
46+
| `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). |
4547

4648

4749
---
@@ -104,14 +106,18 @@ Advisory [language designation](https://datatracker.ietf.org/doc/html/rfc5646) a
104106
The `tref` attribute contains a string that, once processed, will be treated as
105107
a URL and fetched automatically by the polyfill. The string is known as a URL
106108
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
109+
valid URL is _variable reference substitution_. Variables are usually created
110+
and named by `<map-input name="foo">` elements. The name of the variable can be
109111
referenced in the URL template string contained in the `tref` value, using the
110112
`{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,
113+
references. Processing will resolve variable references that are valid. That is,
112114
all variables that have been created by `<map-input>`s that are referenced in the
113115
template will be replaced with the value of the variable at the time of processing.
114116

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

@@ -161,6 +167,63 @@ and [extent](../../api/mapml-viewer-api#extent).
161167

162168
## Examples
163169

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

166229
```html
@@ -206,6 +269,8 @@ and [extent](../../api/mapml-viewer-api#extent).
206269

207270
| | Spec | Viewer | API |
208271
|:---------------------------------------------------------------------------------|:------: |:-----: |:---: |
272+
| [**Interpreting locations and map positions (5.3)**](https://maps4html.org/HTML-Map-Element-UseCases-Requirements/#map-viewers-capabilities-locations) | | | |
273+
| <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) |
209274
| [**Vector features and overlays (5.2)**](https://maps4html.org/HTML-Map-Element-UseCases-Requirements/#map-viewers-capabilities-vectors) | | | |
210275
| <div class="requirement">Display map data attribution and links (5.2.4)</div> | full | full | |
211276
| [**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)