1.0.11 • Published 4 years ago

@binary-constructions/semantic-map v1.0.11

Weekly downloads
-
License
ISC
Repository
gitlab
Last release
4 years ago

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 &copy; <a href='https://www.openstreetmap.org/'>OpenStreetMap</a> contributors, <a href='https://creativecommons.org/licenses/by-sa/2.0/'>CC-BY-SA</a>, Imagery &copy; <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.

AttributeValueRequired
data-semantic-map-idan identifier for this map to reference from a .semantic-map-contextno
data-semantic-map-tile-url-templatethe URL from where to load the map data (which should already include the access token if needed)yes
data-semantic-map-initial-centerno
data-semantic-map-initial-zoomno
data-semantic-map-fit-boundsno
data-semantic-map-max-zoomno
data-semantic-map-min-zoomno
data-semantic-map-enable-clusteringno

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.

AttributeValueRequired
data-semantic-map-refthe data-semantic-map-id of the target mapno (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.

AttributeValueRequired
data-semantic-map-featuresJSON defining one or more featuresyes

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.

AttributeValueRequired
data-semantic-map-geometry-typeone of "Point", "LineString", "Polygon", "MultiPoint", "MultiLineString", "MultiPolygon" or "GeometryCollection"yes
data-semantic-map-geometry-coordinatesthe coordintes of the geometry in questionyes, 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.

AttributeValueRequired
data-semantic-map-geometriesa list of GeoJSON geometry objectsyes

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.

AttributeValueRequired
data-semantic-map-property-namethe name of the propertyyes
data-semantic-map-property-valuethe value of the propertyno
data-semantic-map-property-parsewhether 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.

AttributeValueRequired
data-semantic-map-propertiesa JSON object defining the propertiesyes

TODO: clarify/document the semantics of nesting properties

1.0.11

4 years ago

1.0.10

4 years ago

1.0.8

4 years ago

1.0.7

4 years ago

1.0.6

4 years ago

1.0.5

4 years ago

1.0.4

4 years ago

1.0.3

4 years ago

1.0.2

5 years ago

1.0.1

5 years ago

1.0.0

5 years ago