Updating Campus Maps to Mobile Maps - June 2014

By peterm, 10 June, 2014

June 10, 2014 

Updated August 2015

Here are some rough notes on the process for getting a mapbox.com served set of tiles for the http://mobilemaps.ucsc.edu site (discontinued in June 2015).

Our objective was to reduce some of the design noise of OSM and purposefuly design the campus map to remove illegal paths used by bicyclists. I was able to take advantage of a lot of work done by maps.wisc.edu in terms of styling. We articulated a list of rules of what we wanted to see at different zoom levels. We were able to use TileMill and CartoCSS to develop approaches to renaming some points of interest, styling roads and buildings, etc.

The tools and process necessary to do the work is fairly complicated. I created the following environment on my iMac in the office, but we’ll likely migrate this work to one of the SDC VM’s so we can re-run data fetches from OSM and re-import into PostgreSQL.

I followed the process outlined in the MapBox article, <OSM Bright> and <OSM PostgreSQL>. The steps involve:

- getting a shapefile from techno that covers our region (SF Bay Area)

- importing the shapefile into PostgreSQL

- making a connection to PostgreSQL from TileMill

Once the connection is made, we can begin approaching making changes to the style of the map. Some of the basic changes we wanted to make included:

- highlighting roads, land and buildings through the development of a color palette

- highlighting parking

- removing unofficial bike paths (e.g., “No Brakes”)

- removing poi icon or name (recycling, unpaved paths, some land types, etc. )

A typical edit can be pretty complicated. Part of this is coming to understand how OSM classifies various components, the other part is figuring out where in the database schema an item exists. 

Here’s an example. The campus Arboretum can be seen in OSM here: http://www.openstreetmap.org/#map=14/36.9833/-122.0578. At zoom level 14, the label given by someone is, “University of California Santa Cruz Arboretum”. Great; very complete. But, too long. Our approach to this fix is to overwrite the standard OSM label with the shorter Arboretum. For our app’s needs, the context is already the University, so it makes sense. That’s the “opinionated design” approach we’ve taken (borrowed from a MapBox article).

… in our labels.mss file in the #area_label block I’ve added

/* Override labels for CASFS and Arboretum to fit */

    [type='farm'][zoom>=14] {

      text-name: "'CASFS'";

      }

    [type='garden'][zoom>=14] {

      text-name: "'Arboretum'";

      }

Further, we wanted to hide some of the area labels in this region of the campus to give a sparser look. We used:

/* hide Eucalyptus Grove @ Arb */

    [type='wood'][zoom>=14] {

      text-opacity: 0;

      }

/* hide Dr. Ball's Redwood Grove */

    [type='forest'][zoom>=14] {

      text-opacity: 0;

      }

Determining the target to override and apply styling can take some database work. My process typically included using JOSM to identify an item in OSM. I’d then determine if we’re looking at polygon, point or line. That helps determine the database table. In pgAdmin3, I would browse the data in the table or run some basic select commands to identify the item I was looking for. 

(SELECT osm_id, way, name, "natural"

FROM planet_osm_polygon

WHERE

"natural" IN (‘forest', 'wood')

AND

(name = 'Eucalyptus Grove')

OR

(name LIKE 'Dr. Ball%')

)

AS data

This would give us an exact match or a small set of like data that we could later save in TileMill for specific styling.

PostgreSQL

PostgreSQL is used for holding OpenStreetMap data that is either exported from OSM or via datasets provided by vendors. For our project, I pulled the SF Bay Area data that includes our region. This data is then pulled into PostgreSQL where we can perform SQL queries to get at data results.

Because OSM is a living map, the underlying data may change over time. So, we’ll be working on a refresh process to pull in new datasets over time. We’ll also move this from my iMac to a VM so we have a production level server behind the database and take some of the load off my workstation.

TileMill

TileMill is a desktop app used to style maps. It can pull and integrate data from a variety of sources including shapefiles, OpenStreetMap exports, Google docs, databases, etc.

Within TileMill, layers are used to hold different types of data that styling is applied to. Using the CartoCSS language, styling rules can be applied to the data held in the layer. Layers are composited in a “stack” that allows for additional styling rules to be applied. 

In addition to styling the look and feel for a map, there are a lot of options for developing further interactivity, tooltips, legends, etc.

Once a map is styled, it can be exported into a MBTile (MapBox Tile format). 

MapBox

Is a service providing hosting of MBTiles (along with a lot of other tech). The hosted tiles (maps) can be used in a variety of ways including them in web pages, mobile apps, etc. They host the finished map.

In our case, I have an account that serves 10,000 views for $5/mo. In the case that we exceed that load, we’ll buy a larger subscription on University funds. Having a paid account would also let us store multiple, styled versions of our maps for use in various projects from a single source.

Drupal

Drupal is used as a database to hold records for our buildings, classrooms, departments, etc. Each “node” is a record. Each record has a title, location and set of attributes. The location is the lat, lng for a particular node. When a selection is made from a menu, Drupal finds the record. As the record is being displayed, it calls out to MapBox which delivers back our styled map zoomed to a specific zoom level and a marker.

Within Drupal we are using the bootstrap theme. This works with mobile devices quite well. We have yet to design mobilemaps for the desktop, so it looks pretty sparse at larger dimensions. However, on the phone it looks and works well.

A number of modules are used in Drupal for this project including (views, MapBox, OpenLayers,  

Tags