Category Archives: leaflet

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

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

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