Skip to content

Mapviewer simplifies creating map visualizations using configurations. It is an abstraction over Leaflet

License

Notifications You must be signed in to change notification settings

gramener/mapviewer

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

mapviewer

Mapviewer is an abstraction over Leaflet that can create common GIS applications using configurations.

Mapviewer requires npm install leaflet d3 d3-scale-chromatic mapviewer.

<link rel="stylesheet" href="node_modules/leaflet/dist/leaflet.css">
<script src="node_modules/leaflet/dist/leaflet.js"></script>
<script src="node_modules/d3/build/d3.js"></script>
<script src="node_modules/d3-scale-chromatic/dist/d3-scale-chromatic.min.js"></script>
<script src="node_modules/mapviewer/dist/mapviewer.min.js"></script>

This creates a simple base map:

<div id="base-map" style="height:300px"></div>
<script>
  var map = mapviewer({
    id: 'base-map',
    layers: {
      worldMap: { type: 'tile', url: 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png' }
    }
  })
</script>

This loads a GeoJSON file, links data from state_score.json, and sets the fill color from a merged attribute.

<div id="geojson-map" style="height:300px">
<script>
  var map = mapviewer({
    id: 'geojson-map',
    layers: {
      worldMap: { type: 'tile', url: 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png' },
      indiaGeojson: {
        type: 'geojson',
        url: 'india-states.geojson',
        link: {
          url: 'state_score.json',    // Load data from this file
          dataKey: 'name',            // Join this column from the URL (data)
          mapKey: 'ST_NM'             // with this property in the GeoJSON
        },
        options: {
          style: {
            fillColor: '#a00',
            fillOpacity: 1
          }
        },
        tooltip: function(prop) {   // On hover, show this HTML tooltip
          return prop.ST_NM + ': ' + prop.TOT_P
        },
        attrs: {
          fillColor: {                // Fill the regions
            metric: 'score',          // with the "score" column from state_score.json
            scheme: 'RdYlGn'           // using a RdYlGn gradient
          }
        }
      }
    }
  })
</script>

Note: You can use type: 'topojson' when loading TopoJSON maps.

mapviewer options

  • id: ID of the map DOM element (example: mapid), or the DOM element
  • map:
  • layers: builds layers one on top of another in the specified order.
    • {layername: {...} } dict with layer name as keys

    • Each layer MUST have a type. Currently supported types are

      • tile
      • geojson
      • topojson
      • marker (link: option is not yet supported )
      • circleMarker
    • tile layer MUST have a url: that has the URL template for the leaflet tile layer.

      • url: A string of the form - http://{s}.somedomain.com/blabla/{z}/{x}/{y}{r}.png
      • options: supports same options as Tile options
    • geojson layer MUST have a data as an array of objects or else MUST have a url (string).

      • url: String
      • data: An array of objects. data: takes preference over url.
      • options: supports same options as GeoJSON options
      • link: adds attributes from input dataset to geojson/topojson
        • url: url (String) to fetch data
        • mapKey: attribute name in geojson/topojson to match
        • dataKey: column name in input dataset that matches with geojson/topojson mapKey
        • mismatch: true (default) / false / function. Displays the number of mismatches between dataKey and mapKey. By default, appears as a label at the bottom left corner of the map. To customise the message, use function
          • function accepts an list of objects. Each object has status and all geojson/topojson feature properties:
            • status: A boolean value representing whether the geojson/topojson feature found a match from input dataset or not.
      • popup: string / function that returns formatted value
      • popupOptions: An object with properties and values from leaflet popup options
      • tooltip: string / function that returns formatted value.
        • function(properties) must return a string. feature properties are passed as argument.
      • tooltipOptions: An object with properties and values from leaflet tooltip options
        • direction property can be a string or function. function is passed the following arguments.
          • centerPoint is center coordinates of map view
          • tooltipPoint is center coordinates of tooltip
          • properties are feature properties

      NOTE: tooltip and tooltipOptions are previously (till v0.9.l) are inside attrs. This spec breaking change is mage to maintain consistency with popup and popupOptions

      • attrs Data driven styles. same as options. (attrs take priority over options)
        • For color, weight, opacity, fillColor, fillOpacity properties, the options are:.
          • metric string / function
            • If metric: is a string, can be any numeric property of geojson
            • To have a metric that is formala based on multiple properties, use function. Example: function(row) { return row['congress_votes'] - row['bjp_votes']}
          • domain An array of two numbers. Defaults to calculated values of given metric.
          • range
    • topojson - same as geojson

    • marker layer MUST have a data as an array of objects or else MUST have a url (string).

      • url: String
      • data: An array of objects. data: takes preference over url.
      • latitude: String (mandatory). Must be column name that contains latitude of marker
      • longitude: String (mandatory). Must be column name that contains longitude of marker
      • options: supports same options as marker options
    • circleMarker layer MUST have a data as an array of objects or else MUST have a url (string).

      • url: String
      • data: An array of objects. data: takes preference over url.
      • latitude: String (mandatory). Must be column name that contains latitude of marker
      • longitude: String (mandatory). Must be column name that contains longitude of marker
      • options: supports same options as circleMarker options
      • attrs same as attrs for geojson type layer
  • drilldown:
    • rootLayer: geojson/topojson layer that acts as root layer to drilldown further.
    • levels: Array of objects that provides layer info
      • layerName: Can be a string or function. Function takes argument as properties of parentLayer feature
      • layerOptions: Same as layer options in layers option. If url is function, url takes argument as properties of parentLayer feature
  • legend: configuration of legend to be added to layer. It requires d3-legend. This creates a <div class="map-legend">.
    • position: can be topright, topleft, bottomleft or bottomright(Defaults to bottomright)
    • format: accepts d3 formats and applies to legend labels. (Defaults to d)
    • shape: can be a d3 symbol or an svg path. Default d3.symbolSquare
    • size: size of legend cell
    • cells: number of cells in legend. Default 5
    • width: width of legend
    • height: height of legend
    • scale: accepts d3 scale format (mandatory). For examples, refer d3-legend
    • orient: orientation of legend. Can be vertical (Default) or horizontal
    • shapeWidth: width of legend cell. Default 20
    • shapePadding: padding of legend cell. Default 20
    • labelOffset: value to determine distance of label from each legend cell. Default 20

mapviewer methods

fitToLayer(layerName, options) Zooms map view to fit the layer. Supports same options as fitBounds options

zoomHandler(layerName, minZoomLevel, maxZoomLevel(optional) ) Shows the layer with layerName only between minZoomLevel and maxZoomLevel.

addNote(options) Adds a html label on the map. options is an object with following properties

  • html: html object node
  • style: Defaults to bottom-left. Specify styles for the html
  • position: (Optional) Specifies the position of html on the map

removeLayer(layerName) Removes the layer from the map and returns the layer if the layer exists on the map, else throws an error. Note: This function will remove the layer from the map only. The layer object still exists in memory. Use addLayer(layerName) to add the layer back to the map.

addLayer(layerName, layerConfig)

  • addLayer(layerName) if layerName layer does not exist on map, adds the layer to the map.
  • addLayer(layerName, layerConfig) will creates a new layer with layerConfig options and adds it to the map.

mapviewer events

  • layersloaded is fired when all layers are saved in mapviewer.gLayers (used interally).
    • tooltip is rendered on each layer only after layersload is fired
  • layerName + 'loaded' is fired for each layer with name as layerName

mapviewer features examples

This creates a set of markers for each row in cities.json.

<div id="marker-map" style="height:300px">
<script>
  var map = mapviewer({
    id: 'marker-map',
    layers: {
      worldMap: { type: 'tile', url: 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png' },
      cityMarkers: {
        type: 'marker',
        url: 'cities.json',
        latitude: 'lat',
        longitude: 'long',
      }
    }
  })
</script>

This creates a set of circle markers for each row in cities.json. You can apply styles based on any attribute or function.

<div id="circle-marker-map" style="height:300px">
<script>
  var map = mapviewer({
    id: 'circle-marker-map',
    layers: {
      worldMap: { type: 'tile', url: 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png' },
      cityMarkers: {
        type: 'circleMarker',
        url: 'cities.json',
        latitude: 'lat',
        longitude: 'long',
        attrs: {
          fillColor: {
            metric: 'pollution',
            scheme: 'RdYlGn'
          }
        }
      }
    }
  })
</script>

This adds legend to the map

<div id="choropleth" class="map"></div>
<script>
  var choro_map = mapviewer({
    id: 'choropleth',
    legend: {
      position: 'topright',
      format: 'd',
      shape: d3.symbolCircle,
      size: 100,
      scale: d3.scaleLinear().domain([10, 20, 30]).range(['red', 'yellow', 'green']),
      orient: 'horizontal',
      width: 300,
      height: 100
    },
    layers: {
      worldMap2: { type: 'tile', url: 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png' },
      indiaGeojson: {
        type: 'geojson',
        url: 'india-states.geojson',
        link: {
          url: 'state_score.json',
          dataKey: 'name',
          mapKey: 'ST_NM'
        },
        options: {
          style: {
            fillColor: '#ccc',
            fillOpacity: 1
          }
        },
        attrs: {
          fillColor: {
            metric: 'score',
            scale: 'linear',
            domain: [10, 20, 30],
            range: ['red', 'yellow', 'green'],
          }
        }
      }
    }
  })
</script>

Drilldown feature example:

<div id="geojson-map" style="height:300px">
<script>
  var map = mapviewer({
    id: 'geojson-map',
    layers: {
      worldMap: { type: 'tile', url: 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png' },
      indiaGeojson: {
        type: 'geojson',
        url: 'india-states.geojson',
        link: {
          url: 'state_score.json',    // Load data from this file
          dataKey: 'name',            // Join this column from the URL (data)
          mapKey: 'ST_NM'             // with this property in the GeoJSON
        },
        tooltip: function(prop) {   // On hover, show this HTML tooltip
          return prop.ST_NM + ': ' + prop.TOT_P
        },
        attrs: {
          fillColor: {                // Fill the regions
            metric: 'score',          // with the "score" column state_score.json
            range: 'RdYlGn'           // using a RdYlGn gradient
          }
        }
      }
    },
    drilldown: {
      rootLayer: 'indiaGeojson',
      levels: [
        {
          layerName: function(properties) {return properties['STATE'] + '-layer'},
          layerOptions: {
            url: function(properties) {return properties['STATE'] + '-census.json'},
            type: 'geojson',
            attrs: {
              fillColor: {
                metric: 'DT_CEN_CD',
                range: 'RdYlGn'
              }
            },
            tooltip: function (properties) {
              return 'DISTRICT: ' + properties['DISTRICT']
            }
          }
        }
      ]
    }
  })
</script>

Examples showing usage of mismatch label:

<div class="error-pange"></div>
<div id="mismatch_map" class="map"></div>
<script>
  var custom_mismatch_map = mapviewer({
    id: 'custom-mismatch-map',
    layers: {
      indiaGeojson: {
        type: 'geojson',
        url: 'india-states.geojson',
        link: {
          url: state_scores,
          dataKey: 'name',
          mapKey: 'ST_NM',
          mismatch: function (mismatch_array ) {
            // Render custom message
            var custom_message = `<h2>List of Data Merge Mismatches</h2>`
            custom_message += `<table>`
            mismatch_array.forEach(function(obj){
              custom_message +=  `<tr><td>${obj.feature.properties.ST_NM}</td></tr>`
            })
            custom_message += `</table>`
            $('.error-pane')
              .html(custom_message)
          }
        }
      }
    }
  })

</script>

About

Mapviewer simplifies creating map visualizations using configurations. It is an abstraction over Leaflet

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published