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.
id
: ID of the map DOM element (example:mapid
), or the DOM elementmap
:options
: supports same options as Map options
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
: Stringdata
: An array of objects. data: takes preference over url.options
: supports same options as GeoJSON optionslink
: adds attributes from input dataset to geojson/topojsonurl
: url (String) to fetch datamapKey
: attribute name in geojson/topojson to matchdataKey
: column name in input dataset that matches with geojson/topojsonmapKey
mismatch
:true
(default) /false
/ function. Displays the number of mismatches betweendataKey
andmapKey
. 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.
- function accepts an list of objects. Each object has
popup
: string / function that returns formatted valuepopupOptions
: An object with properties and values from leaflet popup optionstooltip
: 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 optionsdirection
property can be a string or function. function is passed the following arguments.centerPoint
is center coordinates of map viewtooltipPoint
is center coordinates of tooltipproperties
are feature properties
NOTE:
tooltip
andtooltipOptions
are previously (till v0.9.l) are insideattrs
. This spec breaking change is mage to maintain consistency withpopup
andpopupOptions
attrs
Data driven styles. same asoptions
. (attrs
take priority overoptions
)- 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']}
- If
domain
An array of two numbers. Defaults to calculated values of givenmetric
.range
- For
fillColor
andcolor
, must be a interpolate color scheme
- For
- For
-
topojson
- same asgeojson
-
marker
layer MUST have a data as an array of objects or else MUST have a url (string).url
: Stringdata
: An array of objects. data: takes preference over url.latitude
: String (mandatory). Must be column name that contains latitude of markerlongitude
: String (mandatory). Must be column name that contains longitude of markeroptions
: 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
: Stringdata
: An array of objects. data: takes preference over url.latitude
: String (mandatory). Must be column name that contains latitude of markerlongitude
: String (mandatory). Must be column name that contains longitude of markeroptions
: supports same options as circleMarker optionsattrs
same asattrs
forgeojson
type layer
-
drilldown
:rootLayer
:geojson/topojson
layer that acts as root layer to drilldown further.levels
: Array of objects that provides layer infolayerName
: Can be a string or function. Function takes argument asproperties
of parentLayer featurelayerOptions
: Same as layer options inlayers
option. Ifurl
is function,url
takes argument asproperties
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 betopright
,topleft
,bottomleft
orbottomright
(Defaults tobottomright
)format
: accepts d3 formats and applies to legend labels. (Defaults tod
)shape
: can be a d3 symbol or an svg path. Defaultd3.symbolSquare
size
: size of legend cellcells
: number of cells in legend. Default5
width
: width of legendheight
: height of legendscale
: accepts d3 scale format (mandatory). For examples, refer d3-legendorient
: orientation of legend. Can bevertical
(Default) orhorizontal
shapeWidth
: width of legend cell. Default20
shapePadding
: padding of legend cell. Default20
labelOffset
: value to determine distance of label from each legend cell. Default20
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 nodestyle
: Defaults tobottom-left
. Specify styles for thehtml
position
: (Optional) Specifies the position ofhtml
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)
iflayerName
layer does not exist on map, adds the layer to the map.addLayer(layerName, layerConfig)
will creates a new layer withlayerConfig
options and adds it to the map.
layersloaded
is fired when all layers are saved in mapviewer.gLayers (used interally).- tooltip is rendered on each layer only after
layersload
is fired
- tooltip is rendered on each layer only after
layerName + 'loaded'
is fired for each layer with name aslayerName
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>