Skip to content

🌍 Jekyll plugin that allows to easily display maps with MapLibre GL JS

License

Notifications You must be signed in to change notification settings

rriemann/jekyll-maplibre

 
 

Repository files navigation

Jekyll MapLibre

Gem Version

Jekyll MapLibre is a Jekyll plugin that allows to easily display maps with MapLibre GL JS. It is a fork of Jekyll Maps that uses Google Maps.

MapLibre GL JS is open source software and allows for self-hosted maps. Self-hosting become much easier with PMTiles, which is a single-file archive format for pyramids of tiled data that can be hosted on Github, Gitlab, Netlify, etc. and enables low-cost, zero-maintenance map applications.

Check out a Jekyll MapLibre demo at blog.riemann.cc!

Installation

  1. Add the following to your site's Gemfile:
gem 'jekyll-maplibre'
  1. Add the following to your site's _config.yml:
plugins:
  - jekyll-maplibre
  1. Also prepare configuration specific for jekyll-maplibre in your site's _config.yml:
maplibre:
  width:  600
  height: 400
  zoom:   10
  pmtiles: true
  style: false
  # if style is not set to an URL (Mapbox, MapTiler, OpenMapTiles), the following values are used
  sprite: /assets/maps/osm-liberty-sprites/osm-liberty
  glyphs: /assets/maps/fonts/{fontstack}/{range}.pbf
  layers: /assets/maps/OSM-Liberty-layers.json
  sources:
    openmaptiles: 
      type: vector
      url: pmtiles:///assets/maps/maptiler-osm-2020-02-10-v3.11-belgium_brussels.pmtiles
      attribution: © <a href='https://openstreetmap.org'>OpenStreetMap contributors</a>
    natural_earth_shaded_relief:
      attribution: Made with <a href='https://www.naturalearthdata.com/'>Natural Earth</a> data
      maxzoom: 6
      type: raster
      url: pmtiles:///assets/maps/natural_earth_2_shaded_relief.raster.pmtiles
      # uncomment tileSize and tiles for cloud CDN tiles
      # tileSize: 256
      # tiles:
      #   - "https://klokantech.github.io/naturalearthtiles/tiles/natural_earth_2_shaded_relief.raster/{z}/{x}/{y}.png"
  1. Prepare assets to display maps with MapLibre GL JS:

The required assets depend on your specific map configuration. With cloud hosting, it is sufficient to only configure the style property above.

For self-hosted maps, you need to host and configure the following resources:

  • The source. PMTiles covering the map area you need. Use pmtiles convert input.mbtiles output.pmtiles to convert your mbtiles from e.g. https://data.maptiler.com/downloads/planet/. More on pmtiles and extraction of custom areas at https://docs.protomaps.com/guide/getting-started.
  • The glyphs. Font files in pbf format when using vector sources. Check out https://github.com/openmaptiles/fonts/releases.
  • The sprite. Icons used when using vector sources.
  • The layers. A map requires at least one layer. Layers describe how to render source data and rely on glyphs and sprite. The layer definition for vector data depends on the schema used to encode the data in the vector source.
  • The Mapbox Style file. It links all assets together.

For an easy start jekyll-maplibre suggests to use PMTiles raster files and vector files following the OpenMapTiles Vector Tile Schema, so that the layers from OSM-Liberty can be used. Find a demo of OSM Liberty here.

Example assets folder:

assets
└── maps
    ├── fonts
    │   ├── Roboto Condensed Italic
    │   │   ├── 0-255.pbf
    │   │   ├── […]
    │   │   └── 9984-10239.pbf
    │   ├── Roboto Medium
    │   │   ├── 0-255.pbf
    │   │   ├── […]
    │   │   └── 9984-10239.pbf
    │   └── Roboto Regular
    │       ├── 0-255.pbf
    │       ├── […]
    │       └── 9984-10239.pbf
    ├── maplibre-gl.css
    ├── maplibre-gl.js
    ├── maptiler-osm-2020-02-10-v3.11-belgium_brussels.pmtiles
    ├── natural_earth_2_shaded_relief.raster.pmtiles
    ├── natural_earth.vector.pmtiles
    ├── OSM-Liberty-layers.json
    ├── osm-liberty-sprites
    │   ├── [email protected]
    │   ├── [email protected]
    │   ├── osm-liberty.json
    │   └── osm-liberty.png
    └── pmtiles.js

Example assets sources:

Those files are distributed as part of the assets on Github.

It is also possible to self-host everything except the openmaptiles source and link the latter to mbtiles in the cloud, i.e.:

maplibre:
  sources:
    openmaptiles: 
      type: vector
      url: https://api.maptiler.com/tiles/v3-openmaptiles/tiles.json?key=[REPLACE WITH OWN API KEY]
      attribution: © <a href='https://openstreetmap.org'>OpenStreetMap contributors</a>
    ...
  1. Load MapLibre GL JS CSS in <head>

The file maplibre-gl.css should be linked in your <head> or included in another css file.

Many Jeyll templates provide for a file _includes/my-head.html or _includes/custom-head.html (check the docs). If so, add a line such as <link href="/assets/maps/maplibre-gl.css" rel="stylesheet">.

  1. Check your Content Security Policy (CSP) headers

Read more about CSP here: https://maplibre.org/maplibre-gl-js/docs/#csp-directives

Usage

MapLibre Tag

{% maplibre %}

The following optional attributes are supported:

  • id
  • width
  • height
  • class
  • style
  • zoom
  • center
  • description
  • latitude
  • longitude

The flag no_cluster can be used to disable clustering of points.

Example with all attributes and flags:

{% maplibre id="custom-id" width="100%" height="200" class="custom-class" style="clear: both;" zoom="10" center="4.300,50.800" description="<a href='#'>Popup Link</a>" longitude="4.300" latitude="50.800" no_cluster %}

Hint: Icons/sprites work with the dev server only with localhost but not with 127.0.0.1!

Data Source

Jekyll MapLibre offers several ways to add markers to the map. While in principle MapLibre GL JS allows to add all kinds of data other than markers to the map, more configuration must be added to the style definition.

Location data in the tag attributes

Example:

{% maplibre longitude="4.300" latitude="50.800" %}

Location data in the YAML frontmatter

location:
  latitude: 50.800
  longitude: 4.300

GeoJSON data in the YAML frontmatter

The geojson attribute in the YAML frontmatter supports (a) individual GeoJSON features or (b) collections of features.

Individual feature:

geojson:
  type: Feature
  properties:
    description: |
      <strong>A Little Night Music</strong><p>The Arlington Players' production of Stephen Sondheim's <em>A Little Night Music</em> comes to the Kogod Cradle at The Mead Center for American Theater (1101 6th Street SW) this weekend and next. 8:00 p.m.</p>
  geometry:
    type: Point
    coordinates: [4.300, 50.800]

Collection of features:

geojson:
  type: FeatureCollection
  features:
    -
      type: Feature
      properties:
        description: "<strong>A Little Night Music</strong><p>The Arlington Players' production of Stephen Sondheim's <em>A Little Night Music</em> comes to the Kogod Cradle at The Mead Center for American Theater (1101 6th Street SW) this weekend and next. 8:00 p.m.</p>\n"
      geometry:
        type: Point
        coordinates: [4.376, - 50.83012]
    -
      type: Feature
      ...

GeoJSON data in a JSON file

The geojson attribute in the YAML frontmatter can also contain a URL with .json extension.

Example:

geojson: /post-locations.json`

The linked file can be a static file on the same host or another server. If the data source points to a generated file capturing the location attribute of posts, Jekyll MapLibre can display maps with post markers.

Example for /post-locations.json:

{% assign posts = site.posts | where_exp:"location", "location != nil" %}
{
  "type": "FeatureCollection",
  "features": [
  {% for post in posts limit:20 %}
    {
      "type": "Feature",
      "properties": {
        "description": "<b><a href='{{post.url}}'>{{post.title}}</a></b><br/>{{post.description}}<br/>"
      },
      "geometry": {
        "type": "Point",
        "coordinates": {{post.location | jsonify }}
      }
    }{% unless forloop.last %},{% endif %}
  {% endfor %}
  ]
}

With where and where_exp (see documentation), Jekyll permits to implement various filters.

Marker Cluster

Clusters are enabled by default. Use the flag no_cluster in the tag to disable clusters.

Contributing

  1. Fork it (https://github.com/rriemann/jekyll-maplibre/fork)
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request

TODOs

The following issues and limitation require contribution:

  • implement random SVG markers, see: maplibre/maplibre-gl-js#3243, https://github.com/rbrundritt/maplibre-gl-svg/
  • implement more than one map tag per page
  • add more examples on how to generate geojson data from Jekyll collections/data.
  • Jekyll-Maps has spec tests (still in this repo) – make them work again with Jekyll MapLibre
  • add flag to switch popups to open by default (without click to open)
  • fix bug: Liquid Exception: stack level too deep in [your file].md/#excerpt (current work around, use maplibre tags only after the excerpt \<!--more--\>

Similar Software

Contributors

  • Anatoliy Yastreb (as the author of the forked Jekyll Maps gem)
  • Robert Riemann

License

MIT. Feel free to use, copy or distribute it.

About

🌍 Jekyll plugin that allows to easily display maps with MapLibre GL JS

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Ruby 77.3%
  • HTML 22.3%
  • Shell 0.4%