-
Notifications
You must be signed in to change notification settings - Fork 4
Configuring the Map
This version of AIP supports Kenya, though, it is possible to add new countries and expand new data sources. The config folder captures all the configuration available in AIP.
Each country gets a folder. For example, Kenya is ke
. Each country has their corresponding sources, layers, basemap-layers and uicontrols. These are described in detail below.
To add a new country:
- Create a new folder in the config folder, create sources, layers and uicontrols
- Then import those into config/index.js, for example here.
The country is defined as a JSON object in config/index.js:
ke: {
country: 'Kenya',
countryCode: 'ke',
center: [37.85335, 0.44014],
zoom: 7,
layers,
sources,
uicontrols,
csv,
}
-
country
is the name that’s used throughout the platform -
countryCode
two letter iso code -
center
map center to be used. -
zoom
initial map zoom level -
layers
list of layers for this country -
sources
object with lists of sources for this country -
uicontrols
object defining the uicontrols for this country -
csv
csv file associated to this country
AIP supports vector and raster data sources. These are ideally hosted on Mapbox. In case of some vector datasets like GeoJSONs and CSVs, these can be hosted directly on Github or anywhere it’s easily accessible via HTTP.
For example, the administrative boundaries are currently pulled from Mapbox, while the census data that maps the administrative boundaries are pulled from Github.
AIP is made configurable through several components. We’ll go over these and explain where in the code you can find it.
All the configurable aspects of AIP are hosted in the [src/config](https://github.com/developmentseed/catalyst-aip/tree/develop/src/config)
directory.
Data sources that we discussed earlier are plugged into AIP using the [sources.js](https://github.com/developmentseed/catalyst-aip/blob/develop/src/config/sources.js)
file. Sources defined what data is visualized on the map. There are three types of supported data sources — raster tilesets, vector tilesets, and GeoJSON files.
When defining a new source, it takes id
, tilesetid
, layer
(source layer). This is defined as a JSON. For example:
{
id: 'education',
layer: 'Education_Facilities-6v7pmw',
tilesetid: 'iandmuir.922ukwf8',
}
Let’s take each of the attributes above:
-
id
is the unique id of this data source. Mapbox GL uses this to add the source to the map. This is user defined. -
layer
is the source layer from the data. This can be found on Mapbox Studio when uploading a dataset. -
tilesetid
is the unique tileset id on Mapbox. This can be found on the Mapbox Tileset page after data is uploaded.
The sources.js file has three sections — raster, vector, and geojson. Each of these have JSON objects that define a single data source. To add a new one, simply add a new block with id, layer and tilesetid. Note the inline comments in the file itself for further explanation and examples.
AIP supports loading data attributes from CSV files. At the moment, the census data for Kenya is loaded from 'data/Energy/Census/KenyaLighting_Cooking.csv
. These imported in the config and used to define layers in CsvLayers.js. To add new data sources to the same geographic areas, add another component here and pass in the other .csv data as prop. Make sure the .csv data has an id
that matches the geographic areas. To change the geographic reference areas, you need to change the source
and sourceLayer
fields of the csv layers (referring to a source defined in sources.js).
Note that the uicontrols.js file (described below) refers directly to the column names in the CSV file.
Adding data sources to the map is not enough for them to be visualized on the map. We have to create layers from the data source and apply styles to them so they can be rendered. Layers are defined in the [layers.js](https://github.com/developmentseed/catalyst-aip/blob/develop/src/config/layers.js)
file (with the exception of csv layers, which are described above).
Each layer should define the type — this defines how the layer is rendered on the map. These can be fill, line, symbol, raster, circle, heatmap etc. For more layer types, take a look at the Mapbox documentation.
Just like sources, layers are also defined as a JSON object. For example:
{
id: 'education',
source: 'education',
'source-layer': 'Education_Facilities-6v7pmw',
type: 'circle',
paint: {
'circle-color': '#DB93B0',
},
}
Let’s look at the JSON above and inspect each attribute:
-
id
is the unique id of this layer. This is user defined. Note that it’s ok to have same ids for sources and layers. This helps us be consistent. -
source
is the id of the source that this layer should read from. This was defined previously, in sources.js. -
type
defines how the layer is rendered. In this case, we are rendering the data as circles. -
paint
defined how the circles should be styled. In the above example, we defined the circle color as#DB93B0
Mapbox GL supports clustering point data from a GeoJSON data source. To do this, follow the example in the Mapbox documentation. This can be defined directly in layers.js.
UI Controls define how the layers are displayed and what interactions are available to the users. To make it easier to customize as layers grow, these are defined in [uicontrols.js](https://github.com/developmentseed/catalyst-aip/blob/develop/src/config/uicontrols.js)
.
There are two levels of hierarchy for rendering the controls. Layers are organized under a top level category. For example, the education layer we defined above is under a category called Public Facilities
.
Let’s look at how this is defined:
facilities: {
label: 'Public facilities',
icon: Public,
description:
'Locations of Schools, Doctors, Hospitals and other Health Institutions.',
controls: [
health: {
label: 'Health Facilities',
defaultVisibility: false,
legend: 'none',
layerIds: ['health'],
info: '',
},
education: {
label: 'Education Facilities',
defaultVisibility: false,
legend: { type: 'dot', color: '#DB93B0' },
layerIds: ['education'],
info: '',
},
],
}
-
facilities
is the top level unique key for the JSON of this set of controls. -
label
is the name of category to be displayed -
icon
custom icons can be imported and used. For example see the import lines. -
description
is the description that displayed right after the name -
controls
is the second level key that starts the definition of mapping the control to layers -
health
is the key for the first item in the category -
label
name of the first item in the category -
defaultVisibility
determines whether this layer should be visible when the page loads. If it’strue
the layer will be visualized as the user visits the platform. -
legend
is used to display a legend within the control item ('none'
does not show a legend) -
layerIds
defines what layers ids are associated with this category. These must be defined in layers.js -
info
is displayed when the user hovers over the ‘i’ icon next to the category (the icon only visible if info text is provided here)
AIP supports a third level of controls through the subcontrols
key. To use this see the following example:
controls: [
census: {
label: 'Census',
info: '',
subcontrols: [
'Conventional Households': {
label: 'Conventional Households',
defaultVisibility: false,
legend: {
type: 'gradient',
defaultRange: { min: 30000, max: 1500000 },
domain: [30000, 1500000],
unit: '#',
},
layerIds: ['Conventional Households'],
info: '',
},
'Main Electricity': {
label: 'Main Electricity',
defaultVisibility: false,
legend: {
type: 'gradient',
defaultRange: { min: 50, max: 80 },
domain: [0, 100],
unit: '%',
},
layerIds: ['Main Electricity'],
info: '',
}
]
]
In the above example, see the use of subcontrols
which defined all the third level census categories.
We’ve built a straightforward pattern to implement filters to any vector layers on AIP. These are also defined in uicontrols.js. For example:
'Main Electricity': {
label: 'Main Electricity',
defaultVisibility: false,
legend: {
type: 'gradient',
defaultRange: { min: 50, max: 80 },
domain: [0, 100],
unit: '%',
},
layerIds: ['Main Electricity'],
info: '',
}
The above control will introduce a slider that allows the user to filter the data as it is visualized on the map. The most important attributes for the filter are:
-
type: 'gradient'
displays the legend as a gradient to represent the sequential color scheme of the layer -
defaultRange
defines the default state of the filter -
domain
is the domain of the data -
unit
the unit of the data, used for labelling