Build advanced maps with data fetched form a variety of sources using Leaflet.js library

<MapLeaflet /> can be used in MDX pages to display a dynamic maps, which are fully customisable.

Geodata can be retrieved form a Directus database or any other JSON API, a statically hosted geoJSON file or any GeoJSON file publically available on the Web. The component can be customised via the following parameters.

In this page:


Open in example in new page

Adding raster basemaps

import {
  MapLeaflet,
  RasterLayer,
} from "../../../modules/scms.js"

<MapLeaflet 
    height="400px" 
    center="37.00416,37.48551,9">
    
  <RasterLayer
    name="Open Street Map"
    url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
    attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' />

  <RasterLayer
    name="Esri Imagery/Satellite"
    url="https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}"
    checked={true} />

  <RasterLayer
    name="Esri Streets"
    url="https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}" />

  <RasterLayer
    name="Esri Topo"
    url="https://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{z}/{y}/{x}" />

  <RasterLayer
    name="Google Satellite"
    url="https://mt1.google.com/vt/lyrs=s&x={x}&y={y}&z={z}" />

  <RasterLayer
    name="Google Roadmap"
    url="https://mt1.google.com/vt/lyrs=m&x={x}&y={y}&z={z}" />

  <RasterLayer
    name="Carto DB"
    url="https://cartodb-basemaps-a.global.ssl.fastly.net/light_all/{z}/{x}/{y}.png" />

  <RasterLayer
    name="Stamen Terrain"
    url="https://a.tile.stamen.com/terrain/{z}/{x}/{y}.png" />

  <RasterLayer
    name="OpenStreetMap Mapnick"
    url="https://tile.openstreetmap.org/{z}/{x}/{y}.png" />

  <RasterLayer
    name="OSM Cycle Map"
    url="https://tile.thunderforest.com/cycle/{z}/{x}/{y}.png" />
    
</MapLeaflet>

Open in example in new page

Shorthand syntax to add default raster basemaps

import {
  MapLeaflet,
  RasterLayer,
} from "../../../modules/scms.js"

<MapLeaflet 
    height="400px" 
    center="37.00416,37.48551,9"
    baseLayers={["OSM", "EsriSatellite", "EsriStreets", "EsriTopo", "GoogleSatellite", "GoogleRoadmap", "GoogleTerrain", "GoogleAlteredRoadmap", "GoogleTerrainOnly", "GoogleHybrid", "CartoDb", "StamenTerrain", "OSMMapnick", "OSMCycle"]}
    >
</MapLeaflet>

Open in example in new page

Adding a vector layer from a local GeoJSON file

Data from Kahramanmaraş Survey created by Elizabeth Carter and published on OpenContext add distributed with CC BY 4.0 International license.

import {
  MapLeaflet,
  VectorLayer
} from "../../../modules/scms.js"

<MapLeaflet
  height="400px"
  baseLayers={["OSM"]}
  >
  
  <VectorLayer 
    name="Sites"
    source={{
      path2data: {
        path: "/data/ksa.geojson"
      }
    }}
    fitToContent={true}
    checked={true}
    popupTemplate="<p><strong>${Item_Label}</strong>. ${Site_Name} <br />Date: ${Early} — ${Late}</p>"
  />
</MapLeaflet>

Open in example in new page

Adding a vector layer from a local GeoJSON file using a function for the popup template

Data from Kahramanmaraş Survey created by Elizabeth Carter and published on OpenContext add distributed with CC BY 4.0 International license.

import {
  MapLeaflet,
  VectorLayer
} from "../../../modules/scms.js"

<MapLeaflet
  height="400px"
  baseLayers={["OSM"]}
  >
  
  <VectorLayer 
    name="Sites"
    source={{
      path2data: {
        path: "/data/ksa.geojson"
      }
    }}
    fitToContent={true}
    checked={true}
    popupTemplate={ (props) => `<p><strong>${props.Item_Label}</strong>. ${props.Site_Name} <br />Date: ${props.Early}${props.Late}</p>`}
  />
</MapLeaflet>

Open in example in new page

Adding a vector layer from a local GeoJSON file, and styling it on the base of the attributes

Data from Kahramanmaraş Survey created by Elizabeth Carter and published on OpenContext add distributed with CC BY 4.0 International license.

import {
  MapLeaflet,
  VectorLayer
} from "../../../modules/scms.js"

<MapLeaflet
  height="400px"
  baseLayers={["OSM"]}
  >
  
  <VectorLayer 
    name="Sites"
    source={{
      path2data: {
        path: "/data/ksa.geojson"
      }
    }}
    fitToContent={true}
    checked={true}
    popupTemplate="<p><strong>${Item_Label}</strong>. ${Site_Name} <br /> Date: ${Early} — ${Late}</p>"
    pointToLayer={
      (f, ll) => {
        return L.circleMarker(ll, {
          radius: 4,
          fillColor: !Object.hasOwn(f.properties, "Late") ? '#ebebeb' : (f.properties["Late"] < 0 ? "#FE04FC" : '#1B64F7'),
          color: "#000",
          weight: 1,
          opacity: 1,
          fillOpacity: 0.8
        });
      }}
  />
</MapLeaflet>

Open in example in new page

Adding a vector layer from a remote GeoJSON file

import {
  MapLeaflet,
  VectorLayer
} from "../../../modules/scms.js"

<MapLeaflet
  height="400px"
  baseLayers={["OSM", "EsriSatellite"]}
  fitToContent={true} >
  
  <VectorLayer
    name="Iron Age Sites"
    fitToContent={true}
    checked={true}
    source={{
      path2data: {
        path: "https://d2ad6b4ur7yvpq.cloudfront.net/naturalearth-3.3.0/ne_110m_populated_places_simple.geojson"
      }
    }}
    popupTemplate="<p><strong>${ls_name}</strong>"
  />
</MapLeaflet>

Open in example in new page

Adding a vector layer from a remote GeoJSON file with experimental ListVisibleFeatures

import {
  MapLeaflet,
  VectorLayer
} from "../../../modules/scms.js"

<MapLeaflet
  height="400px"
  baseLayers={["OSM", "EsriSatellite"]}
  fitToContent={true} >
  
  <VectorLayer
    name="Iron Age Sites"
    fitToContent={true}
    checked={true}
    source={{
      path2data: {
        path: "https://d2ad6b4ur7yvpq.cloudfront.net/naturalearth-3.3.0/ne_110m_populated_places_simple.geojson"
      }
    }}
    popupTemplate="<p><strong>${name}</strong>"
  />
</MapLeaflet>

Open in example in new page

Adding a vector layer from a Directus API

Data from Kahramanmaraş Survey created by Elizabeth Carter and published on OpenContext add distributed with CC BY 4.0 International license.

import {
  MapLeaflet,
  VectorLayer,
} from "../../../modules/scms.js"

<MapLeaflet
  height="400px"
  center="43,13.32,11"
  baseLayers={["OSM"]}>

  <VectorLayer
    name="All Sites"
    source= {{
      table: "scms_ksa",
      geoField: "geometry"
    }}
    
    checked={true}
    fitToContent={true}
    popupTemplate="<p><strong>${Item_Label}</strong>"
  />
</MapLeaflet>

Open in example in new page

Adding a vector layer with filter from a Directus API

Only Hellenistic and Roman sites are being displayed

Data from Kahramanmaraş Survey created by Elizabeth Carter and published on OpenContext add distributed with CC BY 4.0 International license.

import {
  MapLeaflet,
  VectorLayer,
} from "../../../modules/scms.js"

<MapLeaflet
  height="400px"
  baseLayers={["OSM"]}>

  <VectorLayer
    source={{
      directus: {
        table: "scms_ksa",
        geoField: "geometry",
        queryString: "filter[Hellenistic_Roman][_eq]=true"
      }
    }}
    name="Hellenistic and Roman Sites"
    checked={true}
    fitToContent={true}
    popupTemplate="<p><strong>${Item_Label}</strong>"
  />

</MapLeaflet>

Open in example in new page

Adding a vector layer with a dynamic filter

This example demonstrates how to add a GeoJSON layer to a Leaflet map and apply a filter to show only features that meet certain criteria.

Data from Kahramanmaraş Survey created by Elizabeth Carter and published on OpenContext add distributed with CC BY 4.0 International license.

import { MapLeaflet, VectorLayer } from "../../../modules/scms.js"

<MapLeaflet
  height="400px"
  baseLayers={["OSM"]}
>
  <VectorLayer
    name="Filtered Sites"
    source={{
      path2data: {
        path: "/data/ksa.geojson"
      }
    }}
    fitToContent={true}
    checked={true}
    filter={(feature) => feature.properties.Survey_Year === "1994"}
    popupTemplate="<p><strong>${Item_Label}</strong>. ${Site_Name} <br /> Survey years: ${Survey_Year}<br> Date: ${Early} — ${Late}</p>"
  />
</MapLeaflet>

Open in example in new page

API Documentation


MapLeaflet

The MapLeaflet component is used to create maps using Leaflet.js and it is a wrapper around the MapContainer component.

height

Height (with units) of the map element.

  • string,
  • optional,
  • default: "800px"
center

Center of the map, as a string with long, lat and zoom separated by commas.

  • string
  • optional
  • default: "0,0,2"
baseLayers

Array with default baselayers to show. One, or many of the following values: "CAWM" "OSM", "EsriSatellite", "EsriStreets", "EsriTopo", "GoogleSatellite", "GoogleRoadmap", "GoogleTerrain", "GoogleAlteredRoadmap", "GoogleTerrainOnly", "GoogleHybrid", "CartoDb", "StamenTerrain", "OSMMapnick", "OSMCycle".

  • array
  • optional
  • default: null
scrollWheelZoom

Boolean value that controles whether zoom wheel is active or not.

  • boolean
  • optional
  • default: false
layersControlPosition

Position of the layers control, one of the following values: "topright", "topleft", "bottomright" "bottomleft".

  • string
  • optional
  • default: "topright"

MapLeaflet accepts none, one or more VectorLayer and/or RasterLayer instances as child components

VectorLayer

The VectorLayer component can be used to import, display, and customize your geographical vector data in the map. It must be used as a child of MapLeaflet component. A vector layer can be populated with data from different sources, such as:

  • a local GeoJSON file
  • a remote GeoJSON file
  • a table of Directus instance containing geographical data.
  • eventually, any other JSON API that returns GeoJSON data or that can be mapped to GeoJSON format.
source

An object containing information to source data. This should include the necessary properties for querying the data source. Data can be sourced from a static file (typically a CSV file stored locally or available on the web), a Directus API, or a custom API.

  • Object
  • Required
  • Default: null

If a static file is used, the source object should implement the path2data property, structued as a key: value object with a single path key poniting to the static file path, eg.:

{
  path2data: {
    path: "path/to/data.csv"
  }
}

If a Directus API is used, the source object should implement the directus property, structured as a key: value object with the following keys:

  • endpoint: Optional Directus endpoint. It can be omitted if env variable GATSBY_DIRECTUS_ENDPOINT is set.
  • table: Required Directus table name.
  • queryString: Optional Directus filters and other, provided as querystring compatible to Directus API.
  • token: Optional Directus access token. It can be omitted if env variable GATSBY_DIRECTUS_TOKEN is set.
  • id: Optional Id of a specific record to retrieve. Required for record data displaying.
  • geoField: Field that contains geographical data to display on map.

Example:

{
  directus: {
    endPoint: "https://example.com/directus",
    table: "my_table",
    queryString: "filter[my_field][_eq]=something&limit=-1",
    token: "my-random-string-access-token",
    id: "id-oth-the-record-to-display",
    geoField:"coordinates",
  }
}

Finally, if a custom API is used, the source object should implement the customApi property, structured as an object with the following keys:

  • formatUrl: Required function to format the URL. It accepts a string as a parameter and should return a string rappresenting the URL to get data from
  • parseResponse: Required function to parse the response. it accepts the response object and should return the data to display on the map.

Example:

{
  customApi: {
    formatUrl: (searchString) => {
      return `https://api.example.com/search?q=${searchString}`;
    },    
    parseResponse: (response) => {
      return response.data;
    }
  }
}
name

Layer name to use in the Layer control

  • string
  • required
  • default: null
popupTemplate

A string containing the HTML to render in the popup. Variable properties can be used using ${field_name} syntax. A function can also be provided, receving as parameters the properties of the clicked feature and returning an HTML-formatted string.

  • string | function
  • optional
  • default: null
pointToLayer

A function defining how GeoJSON points spawn Leaflet layers. It is internally called when data is added, passing the GeoJSON point feature and its LatLng as properties. The default is to spawn a default Marker. Full reference at Leaflet documentation.

  • function
  • optional
  • default: null
filter

A function that will be used to decide whether to include a feature or not in the current visualisation. The default is to include all features (no filter applied).

  • function
  • optional
  • default: null
checked

Boolean property to control the layer's default visibility on the map and control panel.

  • boolean
  • optional
  • default: true
fitToContent

Boolean property to decide whether to zoom/pan the map to fit the layer extension or not.

  • boolean
  • optional
  • default: false

RasterLayer

The RasterLayer components can be used to import and display raster tiles in the map. It must be used as a child of MapLeaflet component.

name

Layer name to use in the Layer control

  • string
  • required
  • default: null
url

URL where raster tiles are found.

  • string
  • required
  • default: null
checked

Boolean property to control the layer's default visibility on the map and control panel.

  • boolean
  • optional
  • default: false
attribution

Attribution or credits for the layer.

  • string
  • optional
  • default: null
asOverlay

If true the layer will be listed in the Overlay list; if false (default) in the base-layers list.

  • boolean
  • optional
  • default: false
LAD: Laboratorio di Archeologia Digitale alla Sapienza

Built with ♥ with s:CMS v5.0.1 by LAD @Sapienza

s:CMS è un progetto ideato e sviluppato dal
LAD: Laboratorio di Archeologia Digitale alla Sapienza
Code | Issues