-
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,
}
-
countryis the name that’s used throughout the platform -
countryCodetwo letter iso code -
centermap center to be used. -
zoominitial map zoom level -
layerslist of layers for this country -
sourcesobject with lists of sources for this country -
uicontrolsobject defining the uicontrols for this country -
csvcsv 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:
-
idis the unique id of this data source. Mapbox GL uses this to add the source to the map. This is user defined. -
layeris the source layer from the data. This can be found on Mapbox Studio when uploading a dataset. -
tilesetidis 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:
-
idis 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. -
sourceis the id of the source that this layer should read from. This was defined previously, in sources.js. -
typedefines how the layer is rendered. In this case, we are rendering the data as circles. -
paintdefined 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: '',
},
],
}
-
facilitiesis the top level unique key for the JSON of this set of controls. -
labelis the name of category to be displayed -
iconcustom icons can be imported and used. For example see the import lines. -
descriptionis the description that displayed right after the name -
controlsis the second level key that starts the definition of mapping the control to layers -
healthis the key for the first item in the category -
labelname of the first item in the category -
defaultVisibilitydetermines whether this layer should be visible when the page loads. If it’struethe layer will be visualized as the user visits the platform. -
legendis used to display a legend within the control item ('none'does not show a legend) -
layerIdsdefines what layers ids are associated with this category. These must be defined in layers.js -
infois 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 -
defaultRangedefines the default state of the filter -
domainis the domain of the data -
unitthe unit of the data, used for labelling

