mapviewer.md 9.32 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243
# g1.mapviewer

Mapviewer is an abstraction over [Leaflet](http://leafletjs.com/) that can
create common GIS applications using configurations.

Mapviewer requires `npm install leaflet d3 d3-scale-chromatic g1`.

```html
<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/g1/dist/mapviewer.min.js"></script>
```

This creates a simple base map:

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

This creates a set of markers for each row in [cities.json](test/cities.json).

```html
<div id="marker-map" style="height:300px">
<script>
  var map = g1.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',
        options: {
          // title: 'column-name'      // TODO
        }
        // TODO: allow specifying styles (e.g. color, icon file, etc) from data
      }
    }
  })
</script>
```

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

```html
<div id="circle-marker-map" style="height:300px">
<script>
  var map = g1.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 loads a [GeoJSON file](test/india-states.geojson), links data from
[state_score.json](test/state_score.json), and sets the fill color from a merged
attribute.

```html
<div id="geojson-map" style="height:300px">
<script>
  var map = g1.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
          }
        },
        attrs: {
          fillColor: {                // Fill the regions
            metric: 'score',          // with the "score" column from state_score.json
            scheme: 'RdYlGn'           // using a RdYlGn gradient
          },
          tooltip: function(prop) {   // On hover, show this HTML tooltip
            return prop.ST_NM + ': ' + prop.TOT_P
          }
        }
      }
    }
  })
</script>
```

Drilldown feature example:

```html
<div id="geojson-map" style="height:300px">
<script>
  var map = g1.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
        },
        attrs: {
          fillColor: {                // Fill the regions
            metric: 'score',          // with the "score" column state_score.json
            range: 'RdYlGn'           // using a RdYlGn gradient
          },
          tooltip: function(prop) {   // On hover, show this HTML tooltip
            return prop.ST_NM + ': ' + prop.TOT_P
          }
        }
      }
    },
    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>
```

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

## g1.mapviewer options

- `id`: ID of the map DOM element (example: `mapid`), or the DOM element
- `map`:
    - `options`: supports same options as [Map options](http://leafletjs.com/reference-1.3.0.html#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](http://leafletjs.com/reference-1.3.0.html#tilelayer-minzoom)
  - `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](http://leafletjs.com/reference-1.3.0.html#geojson-style)
    - `link`: adds attributes from input dataset to geojson
      - `url` is url (String) to fetch data
      - `mapKey` is attribute name in geojson to match
      - `dataKey` is column name in input dataset that matches with geojson `mapKey`
    - `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`
          - For `fillColor` and `color`, must be a [interpolate color scheme](https://github.com/d3/d3-scale-chromatic#diverging)
          - For `weight`, `opacity`,`fillOpacity` must be an array with min and max values
      - `tooltip`: string / function that returns formatted value.
        - function(properties) must return a string. feature properties are passed as argument.
        - TODO: the properties currently include only geoJSON properties. link properties must be added
  - `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](http://leafletjs.com/reference-1.3.0.html#marker-icon)
  - `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](http://leafletjs.com/reference-1.3.0.html#circlemarker-radius)
    - `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

## g1.mapviewer methods
`fitToLayer(layerName, options)`
Zooms map view to fit the layer. Supports same options as [fitBounds options](http://leafletjs.com/reference-1.3.0.html#fitbounds-options)

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

## g1.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`