Category Archives: cartography

Introducing Marillac – A way to find food pantries in Cuyahoga County

As a food pantry manager, I occasionally get asked: where else can I get food?

Conversations would go like this:

If they asked in person,

I or a pantry volunteer would hand them a paper list (that they couldn’t take to keep) that were sorted by zip code with listings that contained the name of the organization, the address, zip, type of assistance they gave (a hot meal or a pantry where people can receive parishable and non-parishable groceries), and if there were any geographic restriction (1).

If I was helping a client on the telephone,

I would type their address into google maps, get their zip code, and try to figure out which locations sounded they would be close to them. Look at a private web page hosted by the Greater Cleveland Food Bank that lists agencies sorted by zip code, name some of the locations, ask if they sound close or familiar to the client and then give them the information.

There had to be a better way to getting this information to people. Drawing from my experience of a year of managing a pantry and my mapping background,
I’m making a map/web app that allows other pantry managers who are asked this question to answer this question more informatively and quicker by making Marillac, a web map that has allow the user to:

– input the person’s address
– the map will automatically zoom to the address on the map and display pantries and hot meals near the person’s home;
– find additional details about the pantry/hot meal by clicking on the icon;

Use it at: http://skorasaurus.github.io/marillac/

This is the first usable version and I’m sharing it with fellow agencies and the local food bank (the Greater Cleveland Food Bank) to see if they find it useful and what can be done to make it more useful for my fellow pantry managers. I used it for the first time earlier this week with a person who called me and it worked :)

If you’re interested in seeing the source code, you can view it on https://github.com/skorasaurus/marillac
(If you’re javascript proficient, any tips or suggestions on my code too would be appreciated!)

Technical details (for the opendata geeks and the curious):
As I dove into this, there was a lot of work to be done; my data sources were a PDF and
or a web page (only available to agencies) that organized the locations by zip. I first scraped the PDF using Tabula, did some formatting with regex, and turned it into a csv file and then a geojson file (mapbox’s csv2geojson). Then, I needed to find a geocoder for addresses that are inputted. I finally found one: SmartyStreets, with a great price (free!) for non-profits.
I’m a big fan and user of mapbox; so I used mapbox’s mapping library. I was still a little rusty on some of my javascript, so some mapbox’s excellent examples for mapbox.js, like filtering markers, were also useful.

(1) Most pantries restrict access based on a person’s zip code although they will usually serve a person for the first time. Zip codes aren’t always an effective way geographic boundary. What may be close for one resident in a zip isn’t close at all. (See this gis.stackexchange discussion for a more technical explanation)

Advertisements

How I styled polygons in mapbox.js from an external geojson file

so, this blog post had come a lot later than I expected
because a bit of yak shaving and I explain why at the end of this post.
This post is also the followup to How I learned a 3rd way to link external GEOJSON files in mapbox.js and leaflet.

How to style polygons, based on their properties, that were stored in an external geojson file, using mapbox.js

The Code referenced in this post is based on this commit and is viewable here .

To see the most updated of the Downtown Cleveland public parking map, which may include changes that were made after this blog post, go to http://skorasaurus.github.io/dtparking/

I’ll go through a couple things of what the code is doing and hopefully clarify a couple things for you:

First, at Line 52, I create a featureLayer method that will be used to
load the geojson file
.

Then, load your geojson file using loadURL() . In this example, it’s in the same directory as the index.html file.

Line 63 is a function will return the color based on the argument of the function. myargument is just a placeholder of sorts. This function is later called on lines 82 and 83 with to read the value of parking, which describes what kind of parking lot it is – surface, a multi-storey, or a underground one (written as polygon.feature.properties.parking)

Why polygon is there, I honestly can’t explain at the moment.
feature is there to represent each feature in our featLayer. I did not name it feature, but
properties is there to reference the properties of each feature,
and parking is to select the parking property.

There’s likely many different ways to write this function that begins at line 63 but this one that works for me. I’m interested to hear if there’s any disadvantages to what I did here.

The eachLayer method is confusing. This method is being used to say “hey, I want this code (in lines 77-83) to act on every object (all of the parking areas) that’s in featLayer. Layers have different meanings depending on context in geospatial/GIS.

Line 82
getMyColor is just an arbitrary name that I made to name the function that I made.I still catch myself once in a while of what is function and what is a method….
In several past commits, I didn’t include the ‘feature’ part of the object
because I had mistaken assumed that eachLayer method would go through each object within the layer and that adding ‘feature’ wasn’t necessary.

Beginning at line 63, is the function that will return a different color depending on what is the value of parking. For example, for this polygon parking has a value of ‘surface’ so ‘#679967’ is used as the fillColor for that particular polygon.

polygon and myargument are both arbitrary names that are selected by the coder. If you were to copy and paste this page into as your own, (as well as the dtparking.geojson file at the github repo ), you could rename polygon to
blob and myargument to judgejudy in each place and it’ll work.

Some helpful reminders/refreshers:

‘what’s a method versus a function?’ (unfortunately, I couldn’t find a nice, succinct answer for people on the web);
eachLayer (and all of the functions within mapbox.js, actually) is asynchronous – if you don’t know what this means, it can be explained better than I can by Michael Vollmer here

All methods in mapbox.js will begin with “l.mapbox.” ; you can still use leaflet methods which begin with “l.”

Interestingly, l.geojson is NOT asynchronous, I understand this better after this project. (I don’t know if there’s a way to determine if a class or its methods are asynchronous or not).

Mozilla’s javascript guide and reference are great.

=====

Cause for the delay of posting this blog post; one of my features in the geojson file was missing the parking property and caused the following error in the javascript console for the dtparking html page even though the html code was otherwise working. I added it to here in case someone else would have the same problem and search for the solution.

it was returning the following in the console:

Uncaught TypeError: undefined is not a function 945fae4e059fb12090a8dc22c6cd22e665ebeea2.html:51
(anonymous function) 945fae4e059fb12090a8dc22c6cd22e665ebeea2.html:51
s.LayerGroup.s.Class.extend.eachLayer mapbox.js:2
(anonymous function) 945fae4e059fb12090a8dc22c6cd22e665ebeea2.html:50
s.Mixin.Events.fireEvent mapbox.js:1
(anonymous function) mapbox.js:6
(anonymous function) mapbox.js:1
a mapbox.js:6

I fixed it in
this commit

Best practices for styling your tilemill stylesheet

(last updated July 2013)

  • Should I create separate layers for labels and then for the features (roadways, buildings, etc) themselves ?

Yes. If you’re intending to display text of any feature (like the name of a building or road), create a separate layer for them. You can name it as ‘labels’ or whatever you’d like. Labels are not yet automatically set to render on top of every other feature (<a href=”https://github.com/mapnik/mapnik/issues/87&gt;) layer so the text will not display as you intend in some instances (Dane Springmayer gave me a much more detailed explanation at State of the Map-US 2012).

Should each feature (roadways) have a separate layer ?
Do you have different layers for each zoom level ?

It’s common practice to have separate layers for highways based on different zoom levels.

Wnat data sources should I use ? Is there an advantage to use SHPs over PostGIS Databases ? GeoJSON instead of sqlite ?

 

I haven’t found any Tilemill stylesheets that extensively use layers from postgis besides osm-bright and am curious to see what others do.

  • Other Tips:

Remember to ask yourself at each particular zoom level, what do I specifically want to show at this zoom level ?
– (J. Lord – State of the Map, US 2012)

 

Debugging, or why is my code or Tilemill, not working ?!

– Normally, Tilemill will point out a specific error in your Carto if it’s not formatted correctly.

 

However,

 

If you want to see some carto in action, of howto write, manage your stylesheets, here’s a couple that I admire,

Osm-bright – Made by Mapbox.
Uses Postgis layers as their data sources;