#Ushahidi Map
A map of donor and government-funded projects in Kenya. Demo: http://leekevin.github.io/ushahidimap/
##Set-up
Copy the project folder onto your server and set public access to the public/
folder.
You can use the following to download a copy:
git clone https://github.com/LeeKevin/ushahidimap.git
Run in terminal within the project root directory:
./build.sh
Alternatively, if you want to just use this specific Ushahidi map-building code within your own web app (for some crazy reason), you can simply require the file resources/assets/js/ushahidimap.js
using Browserify or RequireJS.
The constructor for the map can be called using:
UshahidiMap.init(element, projects, counties)
element
is the jQuery element within which you'd like to create the map,
projects
is an Object created from the Open Kenya project data JSON, and
counties
is an Object created from the Kenya GeoJSON county boundaries data
You'll also need jQuery, Leaflet, and Leaflet.markercluster. Versions can be viewed in package.json
.
##What this code does
The project JSON and county GeoJSON data are downloaded loaded in JS and are passed to the UshahidiMap
namespace, along with the target jQuery element within which to render the Leaflet map. From there, an instance of UshahidiMap.Map
is created for these parameters.
First, we search for and save the array locations of the desired column headers (like location, project title, etc.). As we loop through the each project's data, we merge the column header field names with the project values into an associative array (i.e. just another object in JS). Now we have an array of project objects, with each of its values nicely labeled for easy future access.
Example:
[
{
'location2_secondary': {
"human_address": null,
"latitude": "-1.12603004099",
"longitude": "35.82922720520",
"machine_address": null,
"needs_recoding": false
},
'project_title': 'Some title',
'project_description': 'Description',
'project_objectives': 'These are the objectives.',
'county': 'MSAMBWENI'
}
...
]
Now that's sorted, we move along and create the map markers. A marker cluster group is created (via our markercluster plugin). We loop through our parsed project data to create individual markers at the project coordinates and bind a popup containing other project data. We skip any projects that don't have complete coordinates.
Hey! Why are you looping through all the projects a second time? Isn't that inefficient?
Maybe. But it makes it a lot easier to code, read, and manage. Given the number of projects that we have, the difference in performance is nearly negligible.
Next, we want to process the counties data object to create a new layer for the choropleth. We loop through the project again to count the number of projects belonging to each unique county. With this, we can shade in each county with a different color that corresponds to its project density. For good measure, we include a legend and an info box that will display the county name and information when the mouse hovers over a given county.
That's pretty much it.
Because the project JSON data was formatted unintuitively, my first priority was to create a method to parse it into an intuitive object. With the goal to create working code for each step of the challenge, the parseJsonForProjects
method was structured so I could easily add columns to retrieve. For example, I added the County and Project Total columns in the later steps.
I used a pseudo-classical pattern for UshahidiMap.Map
because it's easy to manage and looks clean. I'm able to easily define private and public methods/variables for the "class" and easily build upon the code.
I heavily relied upon the Leaflet documentation. My first time using the library (or any for map data). It's really well done!
I spent a little over 6 hours on this project from start to finish.