Retrieve Venues

The Mapzen Places API allows you to query and retrieve Who’s On First data including venue data via a REST-ish interface.

In this tutorial, you will use the API to retrieve venues in New York City's Flatiron District and display them on a map. To do this, you will:

  1. Create a Map
  2. Find Info With Spelunker
  3. Retrieve Data using the API
  4. Display the data

Step 1: Create a Map

We are going to utilize mapzen.js to make our initial map.

To do this, we need to create a html page. Within that page, we use the code below to create the map.

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Flatiron District Venues</title>
    <meta charset="utf-8">
    <link rel="stylesheet" href="https://mapzen.com/js/mapzen.css">
    <script src="https://mapzen.com/js/mapzen.min.js"></script>
    <style>
      #map {
        height: 100%;
        width: 100%;
        position: absolute;
      }
      html,body{margin: 0; padding: 0;}
    </style>
  </head>
  <body>
    <div id="map"></div>
    <script>
    // Get an API key from https://mapzen.com/dashboard
    L.Mapzen.apiKey = 'your-mapzen-api-key';
    var map = L.Mapzen.map('map', {
      tangramOptions: {
        scene: {
          import: [
            'https://mapzen.com/carto/refill-style/8/refill-style.zip',
            'https://mapzen.com/carto/refill-style/8/themes/color-gray.zip',
            'https://mapzen.com/carto/refill-style/8/themes/label-1.zip'
          ]
        }
      }
    });
    map.setView([40.741331,-73.989332], 19);
    </script>
  </body>
</html>

To learn more about mapzen.js, check out its Get Started tutorial.

Step 2: Find Info With Spelunker

Now, we need some background info (WOF ID, latitude, longitude, etc...) to best utilize the API. To do this, we are going to take a look at the Spelunker.

Search for Flatiron District New York in the Spelunker. Find the one that is the locality in the United States. You should find the page below.

Note the WOF ID. You can find it if you scroll down, it also the number located near the top of the page preceded by / and followed by .geojson. For the Flatiron District, this is 85869245.

Also, verify that you map is centered on the the right coordinates and the level is set correctly. For our purposes, we are going to level 19.

<script>
// Get an API key from https://mapzen.com/dashboard
L.Mapzen.apiKey = 'your-mapzen-api-key';
var map = L.Mapzen.map('map', {
  tangramOptions: {
    scene: {
      import: [
        'https://mapzen.com/carto/refill-style/8/refill-style.zip',
        'https://mapzen.com/carto/refill-style/8/themes/color-gray.zip',
        'https://mapzen.com/carto/refill-style/8/themes/label-1.zip'
      ]
    }
  }
});
map.setView([40.741331,-73.989332], 19);
</script>

Step 3: Retrieve Data using the API

To retrieve data using the API, we are going to utilize the mapzen.places.api.js file.

Download a local copy and then add the script to your html file.

<script src="mapzen.places.api.js"></script>

Also add jQuery, we are going to use that later.

<script src="jquery.min.js"></script>

This script will allow you to make the queries available through the Mapzen Places API.

Add the following helper function to make those calls from your html file. Note that we are using the mapzen.places.getDescendants API method. We include geom: so we are able to obtain information about the venue.

function init() {

  // Get all the venues in the Flatiron District
  // See: https://mapzen.com/documentation/places/methods/#mapzen.places.getDescendants
  var parent_id = 85869245;
  var method = 'mapzen.places.getDescendants';
  var data = {
    id: parent_id,
    per_page: 500,
    extras: 'geom:' // this gets us lat/lng coords
  };

  // Ok now we actually call the API
  mapzen.places.api.call_paginated(method, data, onpage, onerror, oncomplete);
}

Add the following helper functions. Not that the show_venue function has not yet been created.

// Incrementally show API results on the map
var onpage = function(rsp) {
  //console.log(rsp);
  for (var i = 0; i < rsp.places.length; i++) {
    var place = rsp.places[i];
    show_venue(place);
  }
};

// Just log errors to the JS console
var onerror = function(rsp) {
  console.error(rsp);
};

// NOOP (we are using onpage instead)
var oncomplete = function() { return; };

Step 4: Display the Data

Now we are going to display the data. To do this, we are going to write a show_venue function. The show_venue function takes a place's latitude and longitude and stylizes it as a circle with a fill and stroke using the marker style. For our purposes, we have selected a shade of grey.

// Venues are shown as a green circle
var markerStyle = {
  "weight": 2,
  "opacity": .6,
  "fillOpacity": .2,
  "radius": 9,
  "fillColor": "#888888",
  "color": "#888888"
};

// How we should handle each API result
var show_venue = function(place) {
  var marker = L.circleMarker({
    lat: place['geom:latitude'],
    lng: place['geom:longitude']
  }, markerStyle);
  marker.bindTooltip(place['wof:name']);
  map.addLayer(marker);
};

Your code should now resemble:

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Flatiron District Venues</title>
    <meta charset="utf-8">
    <link rel="stylesheet" href="https://mapzen.com/js/mapzen.css">
    <script src="https://mapzen.com/js/mapzen.min.js"></script>
    <style>
      #map {
        height: 100%;
        width: 100%;
        position: absolute;
      }
      html,body{margin: 0; padding: 0;}
    </style>
  </head>
  <body onload="init()">
    <div id="map"></div>
    <script src="mapzen.places.api.js"></script>
    <script src="jquery.min.js"></script>
    <script>
    // Get an API key from https://mapzen.com/dashboard
    L.Mapzen.apiKey = 'your-mapzen-api-key';
    var map = L.Mapzen.map('map', {
      tangramOptions: {
        scene: {
          import: [
            'https://mapzen.com/carto/refill-style/8/refill-style.zip',
            'https://mapzen.com/carto/refill-style/8/themes/color-pink.zip',
            'https://mapzen.com/carto/refill-style/8/themes/label-1.zip'
          ]
        }
      }
    });
    map.setView([40.741331, -73.989332], 19);

    var markerStyle = {
      "weight": 2,
      "opacity": .6,
      "fillOpacity": .2,
      "radius": 9,
      "fillColor": "#888888",
      "color": "#888888"
    };

    // How we should handle each API result
    var show_venue = function(place) {
      var marker = L.circleMarker({
        lat: place['geom:latitude'],
        lng: place['geom:longitude']
      }, markerStyle);
      marker.bindTooltip(place['wof:name']);
      map.addLayer(marker);
    };

    // Incrementally show API results on the map
    var onpage = function(rsp) {
      //console.log(rsp);
      for (var i = 0; i < rsp.places.length; i++) {
        var place = rsp.places[i];
        show_venue(place);
      }
    };

    // Just log errors to the JS console
    var onerror = function(rsp) {
        console.error(rsp);
    };

    // NOOP (we are using onpage instead)
    var oncomplete = function() { return; };

    function init() {

      // Get all the venues in the Flatiron District
      // See: https://mapzen.com/documentation/places/methods/#mapzen.places.getDescendants
      var parent_id = 85869245;
      var method = 'mapzen.places.getDescendants';
      var data = {
        id: parent_id,
        per_page: 500,
        extras: 'geom:' // this gets us lat/lng coords
      };

      // Ok now we actually call the API
      mapzen.places.api.call_paginated(method, data, onpage, onerror, oncomplete);
    }
    </script>
  </body>
</html>

When you refresh your html page, you should see this.

Congrats, you just made a map of venues in New York City's Flatiron District using the Mapzen Places API.