custom map Rotterdam yellow

Leaflet.js: Creating custom maps

"THE AUTONOMOUS FABRIC maps the majority of self-organised initiatives in Rotterdam."
These initiatives are - literally - displayed on a map. This map displays an abstracte outline of Rotterdam.
We gebruiken hiervoor Leaflet.js.

Setup

Obviously the leaflet javascript and css must be included first.
A simple div contains our map. This div requires a height, say 250px.

1
<div id="mymap"></div>
if we then simply do:
1
var mymap = L.map('mymap');
our map is initialised and we have a startingpoint; An empty map. Great.

Layers

Leaflet works with layering. Most features are each added in a seperate layer.
So to add a visual representation of - in our case - Rotterdam, we need to add a layer.
Since leaflet has a number of specialised types of layers, things can get confusing quickly. A simple feature like a city with some markers on it consists of several diffent types of layers like a polyline or markers.
In order to keep things organised, we can use a LayerGroup. This enables us to handle a set of layers which together make up a feature, as a single object.

Next we need information about Rotterdam, a way to render the outline. This can be done with a L.polyline();
A polyline consists of a set of points. Points are objects with two values, a Latitude and a Longitude: for example [51.994333, 4.601726].

I found these two sites very usefull to get what I needed.
https://nominatim.openstreetmap.org/ and
http://polygons.openstreetmap.fr/
From the nominatim we can find many details on the place we are looking for. If we search for Rotterdam, we can click on "details". On this page you will find the 'OSM Relation'-id. In our case it is 1411101 (see screenshot). With this ID we head over to http://polygons.openstreetmap.fr and submit our query. Here we can then "Generate a simplified polygon". Which results in a small table with some different filetypes. In our case the GeoJSON is what we want.
This gives us something like this:

screenshot nominatim OSM Rotterdam
Nominatim details of Rotterdam.
screenshot polygons fr OSM Rotterdam
GeoJSON


I want to illustrate a thing that I found confusing when I started using leaflet. Since our outline is a polygone I figured that using an L.polygon would make sense. It takes a list of coordinates that make up our shape. So if we use the coördinates from our file:

1
2
3
4
var Rotterdam = [[[4.376,51.960000000000001],[4.375,51.963999999999999],...,[[4.377,...]]];
var mymap = L.map('mymap');
var outline = L.polygon(Rotterdam).addTo(mymap2);
mymap.fitBounds(outline.getBounds());//this scales and centers the map so that the 'bounds' fit our viewport.

we get the following result.

There are a couple of things to notice.
First, the drawn polyline does not look like Rotterdam. It looks stretched or rotated. This is due to the difference in how GeoJSON stores it's reference: [longitude, latitude] and how the L.LatLng in leaflet does this: [latitude, longitude].
see this answer
To fix this we can use a L.geoJSON() layer. (which actually makes more sense than a polyline, onces you know of it's existance).
We can pass it the complete object.

1
2
3
var RotterdamGeoJSON = {"type":"MultiPolygon","coordinates":[[[[4.376,51.960000000000001],[4.375,51.963999999999999],[4.377,....]]]];
var gjOutline = L.geoJSON(RotterdamGeoJSON).addTo(mymap);
mymap.fitBounds(gj.getBounds());

To (randomly) customise the look of our outline we can add some options:

1
2
3
4
5
6
7
8
9
var style_options = {
  stroke: true,
  color: '#444444',
  weight: 1,
  fill: true,
  fillColor: '#FF6633',
  fillOpacity: 1,
};
var gjOutline = L.geoJSON(RotterdamGeoJSON, style_options).addTo(mymap);
1
 #mymap{ background: #ffff55; }

So we have some locations in Rotterdam that we would like to display on the map.

1
var locations = [{"title":"A Tale of a Tub","field_latlng":"51.9157418, 4.4310496"},{"title":"ADA  Rotterdam","field_latlng":"51.9253088, 4.476450199999999"},...];

Next we can replace the default icon with a custom one.
Also we can additionally add a street map in the background (I picked a server from this list). ) (more/other options here)

1
2
3
4
5
6
7
var customIcon = L.icon({
    iconUrl: '../images/map-icon.png',
    iconRetinaUrl: '../images/map-icon.png',//this should offcourse be a double resoluted image
    iconSize: [48, 62],
    iconAnchor: [24, 62],
    popupAnchor: [0, -14]
});