Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
This project is "MapML.js", the central polyfill implementation of the MapML vocabulary. MapML is implemented as a suite of autonomous custom elements that come together as a package.

For instructions on the markup rules of MapML, which are especially important to follow when _generating_ either standalone MapML documents or MapML html markup within an HTML document, see the .github/skills folder child folders named `map-something-markup` generally, where `map-something` is the custom element name. These skills may also be useful when considering the design of new markup-driven features.

This project uses playwright for e2e tests. There are multiple generations of test, so consistency is lacking. We are trying to move away from testing the content rendered by Leaflet where possible, towards even screenshot based tests, even though they can be tricky.

Further information will go below, as appropriate.
165 changes: 165 additions & 0 deletions .github/skills/map-a-markup/SKILLS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
---
name: mapml-a-markup
description: Tells you how to correctly create and edit the markup for a <map-a> element. Use it when generating MapML output markup in an HTML page, especially to wrap `<map-geometry>` content, either in whole or in part, just like how you might use `<a>` to wrap all or part of a paragraph of text in HTML.
---

The `<map-a>` element is a proposal to extend the Web to include links between maps and locations.
This element allows you to wrap parts of coordinates or entire geometries, making a link out of the location/area that is wrapped. When a feature geometry or geometry part is
wrapped in a `<map-a>` element, it creates a blue outline that is 1 pixel wide around the feature (by default), that lets the user know it's a "linked feature".

## Attributes

### `href`
- The URL that the wrapped location points to. Note - If the `type` of the `<map-a>` is text/mapml
you can provide fragments, more on fragments below.

---

### `target`
- This is where the linked URL will be displayed. See table below for more details.
- Defaults to `_self`, in the absence of a valid value.

---

### `type`
- This is the mime type of the linked URL's format. Options are `text/html` & `text/mapml`.
- Defaults to `text/mapml`, in the absence of a valid type value.

---

### `inplace`
- The `inplace` attribute is a boolean attribute - `<map-a inplace href="..."><map-a>`
- When present, the default view-changing behavior is overridden and the map view does not change.

---

## Target Behavior for `text/mapml`

| Target Value | Behavior |
|-------------- |------------------------------------------------------- |
| _self | Replaces the current layer with the linked URL layer. |
| _blank | Adds the linked URL layer to the map. |
| _parent | Replace all the layers with the linked URL layer. |
| _top | Navigate the webpage to the linked URL. |

---

## Target Behavior for `text/html`

| Target Value | Behavior |
|-------------- |----------------------------------------- |
| _self | Navigate the webpage to the linked URL. |
| _blank | Open the linked URL in a new tab. |
| _parent | Navigate the webpage to the linked URL. |
| _top | Navigate the webpage to the linked URL. |

---

## Location fragments

If the `type` attribute's value is `text/mapml`, you have the ability add a location fragment
to the URL. This will pan & zoom the map to the given location.

Fragments are in the following format `#zoom, longitude, latitude`.

URL's solely defined in terms of location fragments pan and zoom the map to the given location regardless of the target value.
i.e. `<map-a href="#1, 20, 30">...</map-a>` will pan to latitude: 30, longitude: 20 and zoom to level 1.

---

## Examples

### Styling Linked Features

To style linked features simply target the `map-a` class in your CSS, once a link is clicked you can target the
`map-a-visited` class. See the example below:

```html
<map-layer>
<map-style>
.map-a {
stroke: red;
}
.map-a-visited {
stroke: green;
}
</map-style>
<map-feature>
<map-properties>
<h1>Basic</h1>
</map-properties>
<map-geometry>
<map-a href="../externalMapML.mapml#2,-98,37">
<map-polygon>
<map-coordinates>2771 3106 2946 3113 2954 3210 2815 3192 2771 3106</map-coordinates>
</map-polygon>
</map-a>
</map-geometry>
</map-feature>
</map-layer>
```

### Wrapping a Feature Type + Location Fragment

```html
<map-feature>
<map-properties>
<h1>Basic</h1>
</map-properties>
<map-geometry>
<map-a href="../externalMapML.mapml#2,-98,37">
<map-polygon>
<map-coordinates>2771 3106 2946 3113 2954 3210 2815 3192 2771 3106</map-coordinates>
</map-polygon>
</map-a>
</map-geometry>
</map-feature>
```

This will replace the current layer with the layer within externalMapML.mapml, once it's added the map will then goto
zoomlevel: 2, longitude: -98, latitude: 37.

### Wrapping a point coordinate with `target="_blank"`

```html
<map-feature>
<map-properties>
<h1>_blank target</h1>
</map-properties>
<map-geometry>
<map-polygon>
<map-coordinates>2771 3106 2946 3113 <map-a href="file.mapml" target="_blank"> 2954 3210 </map-a> 2815 3192 2771 3106</map-coordinates>
</map-polygon>
</map-geometry>
</map-feature>
```

In this example, a point will be created at (2954, 3210) which, once clicked, adds a new layer to the map.

### Nested `<map-a>` definition and behavior

```html
<map-feature>
<map-properties>
<h1>Advanced Example</h1>
</map-properties>
<map-geometry>
<map-a href="parent.mapml" target="_blank">
<map-multipolygon>
<map-polygon>
<map-coordinates>2771 3106 2946 3113 <map-a href="webpage.html" target="_blank" type="text/mapml"> 2954 3210 </map-a> 2815 3192 2771 3106</map-coordinates>
</map-polygon>
<map-a href="nested.mapml" target="_top">
<map-polygon>
<map-coordinates>11 11 12 11 12 12 11 12</map-coordinates>
</map-polygon>
</map-a>
</map-multipolygon>
</map-a>
</map-geometry>
</map-feature>
```
In this advanced example there are multiple nested `<map-a>`. The simple behavior is, the closest `<map-a>` is the link
behavior that the given location/area will adopt.

---
13 changes: 13 additions & 0 deletions .github/skills/map-caption-markup/SKILLS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
name: mapml-caption-markup
description: Tells you how to correctly create and edit the markup for a <map-caption> element. Use it when generating MapML output markup in an HTML page, especially when generating a `<mapml-viewer>` element, to describe the map's purpose, if possible and known.
---

This element is especially important for screen reader users to understand the purpose of a map. It is like 'alt-text' for a map.

The `<map-caption>` element is a child of `<mapml-viewer>` and is used to define
a simple text string that is not visually rendered (at this time).
The caption should be read by screen readers when the `<mapml-viewer>` is focused,
as it generates the `<mapml-viewer aria-label="...">` value, if no aria-label
has been specified by the HTML author. `<map-caption>` may be the first or last
element child of `<mapml-viewer>`.
137 changes: 137 additions & 0 deletions .github/skills/map-extent-markup/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
---
name: mapml-extent-markup
description: Tells you how to correctly create and edit the markup for a <map-extent> element. Use it when generating MapML output markup in an HTML page.
---

The `<map-extent>` element is a hypertext control that is associated to and represents the
rectangle of the map viewport, from the user's perspective. Map authors use it
to compose server requests for layer content. Requests are composed using
URL templates processed by the browser as the map moves and requires new content
to paint. The URL templates each contain one or more variable references, with each
variable reference denoted by the name of the variable enclosed in braces `{}`.

Variables are created by the map author using the `<map-input>` element. There are
several types of `<map-input>`, allowing the map author to reference the corners
of the extent, its width and height, and its zoom.

An example of a `<map-extent>` element being used to load image tiles for a single
URL template.

```html
<mapml-viewer projection="OSMTILE" lat="10" lon="0" zoom="1">
<map-layer label="OpenStreetMap" checked>
<map-extent units="OSMTILE" checked hidden>
<map-input name="z" type="zoom" value="18" min="0" max="18"></map-input>
<map-input name="x" type="location" units="tilematrix" axis="column" min="0" max="262144"></map-input>
<map-input name="y" type="location" units="tilematrix" axis="row" min="0" max="262144"></map-input>
<map-link rel="tile" tref="https://tile.openstreetmap.org/{z}/{x}/{y}.png"></map-link>
</map-extent>
</map-layer>
</mapml-viewer>
```

## Attributes

### `units`

Specifies the projection of the tiles and other content that is expected from the
server. If the projection value is a case-insensitive match of the `<mapml-viewer>`
`projection` attribute, the extent will be disabled in the layer control, and will
not be displayed on the map, nor content fetched.

Defined values of `units` include:

| Projection | Description |
|-------------- |-------------------------------------------------------- |
| OSMTILE | Web Mercator, with 256px x 256px tiles recursively defined inside a square bounds at zoom = 0|
| WGS84 | Pseudo plate carrée, with 256px x 256px tiles. Zoom = 0 contains two tiles in two columns, with their origin at -180,90. False easting and northing (pcrs) values inside the projection bounds correspond to longitude and latitude, respectively. |
| CBMTILE | Lambert Conformal Conic, with 256px x 256px tiles. Zoom levels chosen by scale denominator, so tiles do not nest.|

Author-defined values of `units` are possible, using the [Custom projections API](../../api/mapml-viewer-api/#definecustomprojectionoptions)

The `units` attribute is required and can't be changed.

---

### `label`

Specifies a label for an extent which is displayed in the layer control. When a `label` value is not provided, the `label` value defaults to 'Sub-Layer' in the layer control.

---

### `checked`

The `checked` attribute and property is boolean. When present, the checked property value is taken to be 'true'; when not present, the property value is 'false'. The map-extent content will be fetched and rendered according to the `checked` state. Beware that it is the *presence* of the attribute that makes it true, not the value of the attribute. For example, the attribute `checked="false"` actually turns out to be checked, [as described by MDN Web docs](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes#boolean_attributes).

---

### `hidden`

The `hidden` attribute and property is boolean. When present, the extent is hidden (not present) in the layer control. Regardless of `hidden` state, the layer is rendered or not depending on the `checked` attribute state.

---

### `opacity`

The `opacity` attribute is used to set the initial opacity of the `<map-extent>` element.
Valid `opacity` values range from from "0.0" to "1.0" with strictly one demical place and are reflected in the extent settings
opacity input slider control. When the `opacity` attribute is not present, the opacity is set to "1.0" by default.

---

## Examples

### Multiple Extent

The following example shows multiple `<map-extent>` elements in a layer. The different elements can be selected from the three dots menu of the Basemap layer.

```html
<mapml-viewer projection="OSMTILE" zoom="2" lat="53.331" lon="-91.667" controls>
<!-- Change Basemap using the three dots menu of the basemap layer -->
<map-layer label="Basemap" checked="">
<!-- This extent will be hidden in the layer control since no label is provided -->
<map-extent units="OSMTILE" checked>
<map-input name="TileMatrix" type="zoom" value="18" min="0" max="18"></map-input>
<map-input name="TileCol" type="location" units="tilematrix" axis="column" min="0" max="262144"></map-input>
<map-input name="TileRow" type="location" units="tilematrix" axis="row" min="0" max="262144"></map-input>
<map-link rel="tile" tref="https://server.arcgisonline.com/arcgis/rest/services/World_Imagery/MapServer/WMTS/tile/1.0.0/World_Imagery/default/default028mm/{TileMatrix}/{TileRow}/{TileCol}.jpg"></map-link>
</map-extent>
<map-extent label="Nat Geo" units="OSMTILE" checked>
<map-input name="TileMatrix" type="zoom" value="18" min="0" max="18"></map-input>
<map-input name="TileCol" type="location" units="tilematrix" axis="column" min="0" max="262144"></map-input>
<map-input name="TileRow" type="location" units="tilematrix" axis="row" min="0" max="262144"></map-input>
<map-link rel="tile" tref="https://server.arcgisonline.com/arcgis/rest/services/NatGeo_World_Map/MapServer/WMTS/tile/1.0.0/NatGeo_World_Map/default/default028mm/{TileMatrix}/{TileRow}/{TileCol}.jpg"></map-link>
</map-extent>
<map-extent label="Imagery" units="OSMTILE" checked>
<map-input name="TileMatrix" type="zoom" value="18" min="0" max="18"></map-input>
<map-input name="TileCol" type="location" units="tilematrix" axis="column" min="0" max="262144"></map-input>
<map-input name="TileRow" type="location" units="tilematrix" axis="row" min="0" max="262144"></map-input>
<map-link rel="tile" tref="https://server.arcgisonline.com/arcgis/rest/services/World_Imagery/MapServer/WMTS/tile/1.0.0/World_Imagery/default/default028mm/{TileMatrix}/{TileRow}/{TileCol}.jpg"></map-link>
<map-link rel="tile" tref="https://services.arcgisonline.com/arcgis/rest/services/Reference/World_Boundaries_and_Places/MapServer/WMTS/tile/1.0.0/Reference_World_Boundaries_and_Places/default/default028mm/{TileMatrix}/{TileRow}/{TileCol}.png"></map-link>
</map-extent>
</map-layer>
</mapml-viewer>
```

### WMS Request

The following example shows a Web Map Service Request using `<map-link>` to request map images.

```html
<mapml-viewer projection="OSMTILE" zoom="4" lat="53.331" lon="-91.667" controls>
<map-layer label="Toporama" checked="">
<map-extent xmlns="http://www.w3.org/1999/xhtml" units="OSMTILE" checked>
<!-- URL parameters for WMS Request -->
<map-input name="z" type="zoom" value="18" min="4" max="18"></map-input>
<map-input name="w" type="width"></map-input>
<map-input name="h" type="height"></map-input>
<map-input name="xmin" type="location" units="pcrs" position="top-left" axis="easting" min="-2.003750834E7" max="2.003750834E7"></map-input>
<map-input name="ymin" type="location" units="pcrs" position="bottom-left" axis="northing" min="-2.003750834E7" max="2.003750834E7"></map-input>
<map-input name="xmax" type="location" units="pcrs" position="top-right" axis="easting" min="-2.003750834E7" max="2.003750834E7"></map-input>
<map-input name="ymax" type="location" units="pcrs" position="top-left" axis="northing" min="-2.003750834E7" max="2.003750834E7"></map-input>
<!-- Web Map Service requesting image -->
<map-link rel="image" tref="https://wms.ess-ws.nrcan.gc.ca/wms/toporama_en?SERVICE=WMS&amp;REQUEST=GetMap&amp;FORMAT=image/jpeg&amp;TRANSPARENT=FALSE&amp;STYLES=&amp;VERSION=1.3.0&amp;LAYERS=WMS-Toporama&amp;WIDTH={w}&amp;HEIGHT={h}&amp;CRS=EPSG:3857&amp;BBOX={xmin},{ymin},{xmax},{ymax}&amp;m4h=t"></map-link>
</map-extent>
</map-layer>
</mapml-viewer>
```
Loading
Loading