@binary-constructions/semantic-map
v1.0.11
Published
A markup wrapper for the Leaflet map API
Downloads
27
Readme
semantic-map
A wrapper for Leaflet allowing you to display maps on your website by writing HTML markup only.
Warning: this project is currently in a relatively early state of development with only the most basic functionality implemented and a lot of polishing still to be done. The documentation below is also a little bit out-of-date. I'm busy with other things at the moment but should be able to get back to this project at some point in the not too distant future. Should you be interested in using semantic-map please make sure to contact me first!
Example
A very simple map might look as follows:
<div class='semantic-map'
data-semantic-map-tile-url-template='https://api.tiles.mapbox.com/v4/mapbox.streets/{z}/{x}/{y}.png?access_token=YOUR_ACCESS_TOKEN'
data-semantic-map-initial-center='[13.4, 52.52]'
data-semantic-map-initial-zoom='12'>
<div class='semantic-map__feature'>
<div class='semantic-map__geometry' data-semantic-map-geometry-type='Point' data-semantic-map-geometry-coordinates='[13.4, 52.52]'>
<div class='semantic-map__property' data-semantic-map-property-key='popup'>
<h4>Hey, I'm a Point!</h4>
<p>I mark the initial center of the map.</p>
</div>
</div>
</div>
<div class='semantic-map__attribution'>
Map data © <a href='https://www.openstreetmap.org/'>OpenStreetMap</a> contributors, <a href='https://creativecommons.org/licenses/by-sa/2.0/'>CC-BY-SA</a>, Imagery © <a href='https://www.mapbox.com/'>Mapbox</a>
</div>
</div>
For more examples see the file showcase.html
in the dist/
folder.
Features
- Display one or more maps. (Yay!)
- Add map features like points and polygons.
- Define content to show in a popup when a map feature is selected.
- Customize basic map behavior like min/max zoom, clustering, etc. (TODO: map bounds, automatic panning/zooming when the visible features change, initial center/zoom defined by the map features present, initial center/zoom defined by a bounding box, ...).
- Define map features not only as part of the map itself but anywhere in your markup (e.g. together with a list of addresses that you are showing elsewhere on your page anyway).
- Add any kind of additional properties to a feature (with some of
those properties having customizable default effects, like
popup
above). - TODO: group features into (possibly nested) collections with shared properties.
- TODO: add callbacks for map feature selection, etc.
- TODO: define the markup of popups (amongst other things) using lodash templates.
- TODO: add custom hooks to transform property values, style map features, etc.
Limitations
The main focus of this project is to let you easily add basic maps to a webpage by dumping all of the relevant data directly into your markup. While more functionality might be added in the future in ways that do not conflict with the overall design goals, it is not the aim of this project to make the whole of the backend APIs accessible via markup.
Installation
As a <script>
First load the script into your webpage:
<script src="path/to/semantic-map.min.js"></script>
Then add another script element to mount all maps when the page is loaded:
<script>
window.onload = function() {
semanticMap.mount();
}
</script>
You probably also want to extend your style definitions with simple CSS rules similar to the following:
.semantic-map {
height: 400px; /* ... or whatever the height of your map(s) is supposed to be. */
}
.semantic-map__attribution,
.semantic-map__property:not([data-semantic-map-property-value]) {
display: none;
}
Via npm/yarn
The npm package of semantic-map is not currently being kept up-to-date so for now it shouldn't be used!
Usage
A Note on Coordinates
Like GeoJSON -- and unlike Leaflet amongst others -- semantic-map
uses the order [LON, LAT]
to define coordinates.
Merging of Map Elements
To allow for terser markup semantic-map allows the "merging" of basically any kind of nested elements. Because of that, the map feature in the example above could also be written as:
<div class='semantic-map__feature semantic-map__geometry'
data-semantic-map-geometry-type='Point'
data-semantic-map-geometry-coordinates='[13.4, 52.52]'>
<div class='semantic-map__property' data-semantic-map-property-key='popup'>
<h4>Hey, I'm a Point!</h4>
<p>I mark the initial center of the map.</p>
</div>
</div>
Or even:
<div class='semantic-map__feature semantic-map__geometry semantic-map__property'
data-semantic-map-geometry-type='Point'
data-semantic-map-geometry-coordinates='[13.4, 52.52]'
data-semantic-map-property-key='popup'>
<h4>Hey, I'm a Point!</h4>
<p>I mark the initial center of the map.</p>
</div>
While there are certain cases where the specific semantics of merged
elements might not be completely obvious (e.g.: merging semantic-map
with semantic-map-context
), in most sensible cases the results
should be what you expect.
The Markup API
The Markup API is designed to be straigtforward to use while still being adaptable to different requirements with respect to the structuring of a webpage.
.semantic-map
Defines the mount point for a map. Several such mount points may exist in a given webpage.
| Attribute | Value | Required |
|---------------------------------------|:-------------------------------------------------------------------------------------------------:|:--------:|
| data-semantic-map-id
| an identifier for this map to reference from a .semantic-map-context
| no |
| data-semantic-map-tile-url-template
| the URL from where to load the map data (which should already include the access token if needed) | yes |
| data-semantic-map-initial-center
| | no |
| data-semantic-map-initial-zoom
| | no |
| data-semantic-map-fit-bounds
| | no |
| data-semantic-map-max-zoom
| | no |
| data-semantic-map-min-zoom
| | no |
| data-semantic-map-enable-clustering
| | no |
Notes:
Additional map details (e.g. features like points or polygons) may be added to a map by making the corresponding elements children of the map element. Any element placed in such a way will automatically have the parent element as the target map.
If map details need to be defined outside of the map element itself, they may also be placed inside a
.semantic-map-context
element instead (see below).
.semantic-map-context
Allows the placement of map details outside of the actual map elements by treating both the context element itself as well as all of its childred as if they were children of the corresponding map.
| Attribute | Value | Required |
|-------------------------|:--------------------------------------------:|:--------------------------------------------------:|
| data-semantic-map-ref
| the data-semantic-map-id
of the target map | no (defaults to the first map without a custom id) |
.semantic-map__feature
Defines an individual map feature via a child element.
Notes:
Every such element needs to contain exactly one child element of class
.semantic-map__geometry
(making these two elements a prime candidate for merging; see above.)Additionally, features may contain properties.
.semantic-map__features
Defines one or more map features using JSON.
| Attribute | Value | Required |
|------------------------------|------------------------------------|----------|
| data-semantic-map-features
| JSON defining one or more features | yes |
Notes:
- If the provided JSON defines an array, it must consist entirely of valid Feature Objects as defined by the GeoJSON spec (i.e. each must have a member "type" with a value of "Feature").
- If the provided JSON defines an object instead, it may be any kind of valid GeoJSON Object as per the spec linked above (i.e. it must have a member "type" with a value of either "Feature", "FeatureCollection" or one of the seven GeoJSON geometry types).
TODO: clarify/document the semantics of adding properties to this element.
.semantic-map__geometry
Defines an individual geometry.
| Attribute | Value | Required |
|------------------------------------------|------------------------------------------------------------------------------------------------------------------|----------------------------------------------|
| data-semantic-map-geometry-type
| one of "Point", "LineString", "Polygon", "MultiPoint", "MultiLineString", "MultiPolygon" or "GeometryCollection" | yes |
| data-semantic-map-geometry-coordinates
| the coordintes of the geometry in question | yes, unless the type is a GeometryCollection |
Notes:
- As the only valid case of nested geometries a "GeometryCollection" is allowed to have multiple other geometry elements to be nested inside it (as long as they are not themselves of type "GeometryCollection").
Note: properties may not be defined for geometries but need to be defined for the corresponding feature instead.
.semantic-map__geometries
Defines a list of geometries via attributes.
| Attribute | Value | Required |
|--------------------------------|------------------------------------|----------|
| data-semantic-map-geometries
| a list of GeoJSON geometry objects | yes |
Notes:
- This element is only meant to be used inside a geometry of type "GeometryCollection".
.semantic-map__property
Defines a single property of a feature.
| Attribute | Value | Required |
|------------------------------------|:--------------------------------------------------------------------------------------------------------:|:--------------------------:|
| data-semantic-map-property-name
| the name of the property | yes |
| data-semantic-map-property-value
| the value of the property | no |
| data-semantic-map-property-parse
| whether to parse the value attribute literally ("literal"), HTML-escaped ("escaped") or as JSON ("json") | no (defaults to "literal") |
Notes:
If the
data-semantic-map-property-value
attribute is not provided the value of the property becomes the.innerHTML
of the property element.The different parse types only have an effect if the property value is specified via an attribute.
TODO: once feature collections are implemented they'll also be allowed to have properties (to use as default properties for features, mainly). The specific semantics of cascading properties (e.g.: overwriting vs. merging) still have to be worked out, however.
.semantic-map__properties
Defines multiple properties of a feature via JSON.
| Attribute | Value | Required |
|--------------------------------|:-------------------------------------:|:--------:|
| data-semantic-map-properties
| a JSON object defining the properties | yes |
TODO: clarify/document the semantics of nesting properties