Fun with Tangram filtering

The great advantage of vector tiles is the ability to filter data and change the style of your map on the fly. We’ve all seen maps that show just metro routes and bike lanes – with Tangram, you can make these by changing just a few lines!

Compare and contrast bike networks at zoom 13, and open full screen!

How do you make a map like this? One way is a lot of arguing with QGIS (but we love QGIS!) Another way is with our bike map. It’s simply a matter of choosing the no-label variant of Walkabout, filtering out roads that are not bike-related, and disabling other layers like earth, buildings, landuse, water.

You can check out the full scene in Tangram Play, but here’s a quick overview.

import: 
    https://mapzen.com/carto/walkabout-style-no-labels/5/walkabout-style-no-labels.yaml

global:
    sdk_bike_overlay: true
    sdk_path_overlay: false
    sdk_mapzen_api_key: #ADD_YOUR_MAPZEN_API_KEY_HERE http://mapzen.com/developers

layers:
    roads:
        filter:
            is_bicycle_related: true
            not: 
                kind: ferry
    earth:
        enabled: false
    water:
        enabled: false
    landuse:
        enabled: false
    buildings:
        enabled: false
    places:
        enabled: false
    pois:
        enabled: false
    transit:
        enabled: false

For more advanced filters and data-driven mapping, Tangram can dynamically style map parameters and filter data using Javascript functions within the scene file. (A great example of this is our bike map, which generates colors based on infrastructure, route information and road type.)

The same holds true for transit. In fact, we turned filtering into a quiz! Can you recognize a city just by its transit network and route colors? It’s harder than you might think. (Way harder.)

  • click for a hint
  • zoom in to see the city

Open this quiz full screen to get fractional zoom!

For this map, while we’re enabling the transit overlay and filtering out everything else in Refill, there’s a twist: we are using zoom filters to re-enable places at z12 to show city names as you zoom in, along with roads and water at z13 to give you some context once the transit labels appear.

import: 
    https://mapzen.com/carto/refill-style/8/refill-style.yaml 
global:
    sdk_transit_overlay: true
    ux_language: en # change to your language of preference, or remove to see the native language
    sdk_path_overlay: false

layers:
    places:
        filter: { $zoom: { min: 12 } }
    water:
        filter: { $zoom: { min: 13 } }
    roads:
        filter: { $zoom: { min: 13 } }
    earth:
        enabled: false
    landuse:
        enabled: false
    buildings:
        enabled: false
    pois:
        enabled: false
    earth-labels:
        enabled: false
    boundaries:
        enabled: false

Sometimes these isolated layers verge on art. In this Walkabout map, we’ve disabled everything but parks and forests.

layers:
    landuse:
        filter: 
            not: 
                - kind: parking
                - kind: industrial
                - kind: retail
                - kind: residential
                - kind: commercial

(Note that you can also collect the filter terms into an array.)

layers:
    landuse:
        filter: 
            not: 
                kind: [parking, industrial, retail, residential, commercial]

This reminded me of a certain map involving islands and San Francisco. Using some judicious regex in JavaScript functions on neighbourhood names led to a watery planet where green space and parks turn into islands on aptly-named bays and seas.

Open full screen, with fluid zoom!

global:     
    sea_name: |
        function(feature){
            var sea_name = feature.name
            if (sea_name.match(/Mission/i)) {
                sea_name = sea_name.replace(/district/i, "Gulf")
                }
            ...
         }
...
places:
        neighbourhoods:
            neighborhood-z16:
                draw:
                    text-blend-order:
                        text_source: |
                            function(){
                                return global.sea_name(feature)
                                }
...

See how it was done in Tangram Play and filter your own map!