name: inverse layout: true class: center, middle, inverse --- #Displaying Data from APIs on a Map MaptimeATL! Mollie Taylor June 22, 2015 Fork me at: https://github.com/maptimeatl/APIs-101 --- # Sponsors --- layout: false class: center, middle  --- layout: false class: center, middle  # 🍕 --- name: inverse layout: true class: center, middle, inverse --- # Maptime! --- layout: false ## What is Maptime? * Time for making maps! * Founded in San Francisco * 65 chapters worldwide * People at all knowledge levels * [http://maptime.io/](http://maptime.io/) --- ## Show-and-Tell * Your work * Something you learned * A cool map you found * Etc. * ~5 minutes per person --- ## Next meetups: ### [Hack Night with Code For Atlanta](http://www.meetup.com/MaptimeATL/events/223398994/) * Monday, July 13, 6:30pm * AT&T Drive Studio, Midtown ### [Instructional Meetup (Topic TBD)](http://www.meetup.com/MaptimeATL/) * Monday, July 27, 6:30pm * The Iron Yard ### http://www.meetup.com/MaptimeATL/ --- ## Slack ### http://slack.codeforatlanta.org/ \#maptime --- name: inverse layout: true class: center, middle, inverse --- #Displaying Data from APIs on a Map --- layout: true class: center, middle --- ## Example (JS)  http://proximityviz.com/south-downtown/eventbrite.html --- ## Example (iOS)  http://appstore.com/proximityvizllc/theironyardatllunch/ --- layout: false # Data Sources with APIs * Places * [Yelp](https://www.yelp.com/developers/documentation) * [Google Places](https://developers.google.com/places/) * [Foursquare](https://developer.foursquare.com/) * Media * [Twitter](https://dev.twitter.com/overview/documentation) * [Instagram](https://instagram.com/developer/) * [Flickr](https://www.flickr.com/services/api/) * Events * [Eventbrite](http://developer.eventbrite.com/) * Weather * Transit & Transportation * [MARTA](http://www.itsmarta.com/developers/default.aspx) --- # What is an API? * API stands for Application Programming Interface * APIs accept a query and return data that matches that query * APIs can be accessed through URLs, although you might need to be logged in or otherwise authenticated. * Base: **https:
//api.foursquare.com/v2/**venues/554791b8498e28eca3641d4b * Endpoint: https:
//api.foursquare.com/v2/**venues/**554791b8498e28eca3641d4b * Query: https:
//api.foursquare.com/v2/venues/**554791b8498e28eca3641d4b** --- # Endpoints * [Foursquare examples](https://developer.foursquare.com/docs/) ### HTTP Request Methods * GET * POST (Create a new entry) * PUT (Replace) * DELETE --- # Keys * [Foursquare example](https://foursquare.com/developers/apps) * Used to identify the app, developer, or user * Access rights for API  --- # Complete Queries * Base URL * Endpoint * Query * Key(s) * Other query parameters ```js 'https://www.eventbriteapi.com/v3/events/search/' + '?token=E55J2U6EXE3CVF6G43VU' + '&location.latitude=33.74986' + '&location.longitude=-84.39223' + '&location.within=1km'``` ```js 'https://api.foursquare.com/v2/venues/554791b8498e28eca3641d4b' + '?client_id=UTSGJ2ZPLOL2LHDOHW5XZFYHVASA4B0JIYMOXH3ZW1TLQ1X1' + '&client_secret=IOGOZ0YYX2CDS1CLO1ASXZU5EQ3MYSYUKXIP2SPD5MZ4CKKH' + '&v=20130815'``` --- # What Gets Returned? ```json { "meta": { "code": 200 }, "response": { "venue": { "id": "554791b8498e28eca3641d4b", "name": "The Iron Yard", "contact": { "phone": "7707518046", "formattedPhone": "(770) 751-8046", "twitter": "theironyard" }, "location": { "address": "115 Martin Luther King Jr Dr NW", "crossStreet": "Peachtree St SW", "lat": 33.75203090890745, "lng": -84.39147375346788, "postalCode": "30303", "cc": "US", "city": "Atlanta", "state": "GA", "country": "United States", "formattedAddress": ["115 Martin Luther King Jr Dr NW (Peachtree St SW)", "Atlanta, GA 30303", "United States"] }, "canonicalUrl": "https:\/\/foursquare.com\/v\/the-iron-yard\/554791b8498e28eca3641d4b", "categories": [{ "id": "4bf58dd8d48988d125941735", "name": "Tech Startup", "pluralName": "Tech Startups", "shortName": "Tech Startup", "icon": { "prefix": "https:\/\/ss3.4sqi.net\/img\/categories_v2\/shops\/technology_", "suffix": ".png" }, "primary": true }], "verified": false, "stats": { "checkinsCount": 4, "usersCount": 3, "tipCount": 0, "visitsCount": 4 }, "likes": { "count": 0, "groups": [] }, "dislike": false, "ok": false, "specials": { "count": 0, "items": [] }, "photos": { "count": 0, "groups": [] }, "hereNow": { "count": 0, "summary": "Nobody here", "groups": [] }, "reasons": { "count": 0, "items": [] }, "createdAt": 1430753720, "tips": { "count": 0, "groups": [{ "type": "others", "name": "All tips", "count": 0, "items": [] }] }, "tags": [], "shortUrl": "http:\/\/4sq.com\/1Piktac", "timeZone": "America\/New_York", "listed": { "count": 0, "groups": [{ "type": "others", "name": "Lists from other people", "count": 0, "items": [] }] }, "pageUpdates": { "count": 0, "items": [] }, "inbox": { "count": 0, "items": [] }, "venueRatingBlacklisted": true, "attributes": { "groups": [] } } } } ``` ### Dealing with latitude and longitude ### Errors pseudo-code --- # Documentation * The endpoints and queries available depend on the documentation * Limits * Rate limits * Policy --- # Documentation Examples * [Yelp](https://www.yelp.com/developers/documentation) * [Google Places](https://developers.google.com/places/) * [Foursquare](https://developer.foursquare.com/) * [Twitter](https://dev.twitter.com/overview/documentation) * [Instagram](https://instagram.com/developer/) * [Flickr](https://www.flickr.com/services/api/) * [Eventbrite](http://developer.eventbrite.com/) * [MARTA](http://www.itsmarta.com/developers/default.aspx) --- # Postman [Download](https://chrome.google.com/webstore/detail/postman-rest-client/fdmmgilgnpjigdojojpjoooidkmcomcm?hl=en)  --- name: inverse layout: true class: center, middle, inverse --- # JavaScript Example --- layout: true class: center, middle --- ## JavaScript Example  [Download the code](https://github.com/maptimeatl/APIs-101/tree/master/code) [View the website](http://proximityviz.com/south-downtown/eventbrite.html) --- layout: false # A Complete Query ```js var EB_TOKEN = 'E55J2U6EXE3CVF6G43VU' var API_ENDPOINT = 'https://www.eventbriteapi.com/v3/events/search/' + '?token=EB_TOKEN' + '&location.latitude=33.74986' + '&location.longitude=-84.39223' + '&location.within=1km';``` --- ## Make Query and Get Response ```js var eventbriteLayer = L.layerGroup(); $.getJSON(API_ENDPOINT .replace('EB_TOKEN', EB_TOKEN), function(result, status) { console.log("Results:"); console.log(result); console.log("Status: " + status); });``` --- ## Viewing results in the console  --- # Set Up Map ```js var map = L.map('map', { attributionControl: false, center: new L.LatLng(33.75, -84.392), zoom: 15 }); L.control.attribution({position: 'bottomleft'}).addTo(map); L.tileLayer('http://otile4.mqcdn.com/tiles/1.0.0/osm/{z}/{x}/{y}.png', { attribution: 'Made at
CodeAcross
for
Code for Atlanta
' + '
Tiles ©
MapQuest
', maxZoom: 18 }).addTo(map);``` --- # Map Points ```js var eventbriteLayer = L.layerGroup(); $.getJSON(API_ENDPOINT .replace('EB_TOKEN', EB_TOKEN), function(result, status) { if (status !== 'success') return alert('Request to Eventbrite failed'); // transform venue result into map marker for (var i = 0; i < result.events.length; i++) { var venue = result.events[i].venue; var eventInfo = result.events[i]; var category = ""; if (eventInfo.category !== null && eventInfo.category.name !== null) { category = eventInfo.category; } var latlng = L.latLng(venue.latitude, venue.longitude); var marker = L.marker(latlng, { icon: makeMarker(category) }) .bindPopup('
' + venue.name + '
' + eventInfo.name.html + '
Begins: ' + eventInfo.start.local.substr(0,10) + '
' + eventInfo.organizer.name + '
' + category.name) .addTo(map); } });``` --- name: inverse layout: true class: center, middle, inverse --- # Swift Example --- layout: true class: center, middle --- ## Swift Example  [Download the code](https://github.com/ProximityViz/TIY-Lunch-iOS) [Download the app](http://appstore.com/proximityvizllc/theironyardatllunch/) --- layout: false # A Complete Query ```swift let API_URL = "https://api.foursquare.com/v2/" let CLIENT_ID = "UTSGJ2ZPLOL2LHDOHW5XZFYHVASA4B0JIYMOXH3ZW1TLQ1X1" let CLIENT_SECRET = "IOGOZ0YYX2CDS1CLO1ASXZU5EQ3MYSYUKXIP2SPD5MZ4CKKH" let requestString = API_URL + "venues/" + id + "?" + "client_id=" + CLIENT_ID + "&" + "client_secret=" + CLIENT_SECRET + "&" + "v=20130815" ``` --- ## Make Query and Get Response ```swift let requestString = API_URL + "venues/" + id + "?" + "client_id=" + CLIENT_ID + "&" + "client_secret=" + CLIENT_SECRET + "&" + "v=20130815" if let url = NSURL(string: requestString) { let request = NSURLRequest(URL: url) // dictionary with array of venues if let data = NSURLConnection.sendSynchronousRequest(request, returningResponse: nil, error: nil) { if let returnInfo = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as? [String:AnyObject] { if let responseInfo = returnInfo["response"] as? [String:AnyObject] { let venue = responseInfo["venue"] as [String:AnyObject] return venue } } } } ``` --- # Mapping the Locations ```swift func mapView(mapView: RMMapView!, layerForAnnotation annotation: RMAnnotation!) -> RMMapLayer! { var markerImage = "restaurant" var markerSize = "small" var markerColor = greenColor switch annotation.userInfo.objectForKey("Type") as String { case "Eating": markerImage = "restaurant" markerColor = yellowColor foodAnnotations.append(annotation) ... } switch annotation.userInfo.objectForKey("Count") as String { case "1": markerSize = "small" ... } ``` --- # Mapping the Locations ```swift // marker and callout var lunchMarker = RMMarker(mapboxMarkerImage: markerImage, tintColorHex: markerColor, sizeString: markerSize) lunchMarker.canShowCallout = true var rightArrowButton = ArrowButton(frame: CGRectMake(0, 0, 28, 44)) rightArrowButton.strokeColor = greenUIColor lunchMarker.rightCalloutAccessoryView = rightArrowButton return lunchMarker } ``` --- # Swift Code ### API Request [FourSquareRequest.swift](https://github.com/ProximityViz/TIY-Lunch-iOS/blob/master/TIY%20Lunch/FourSquareRequest.swift) ### Map of All Venues [MainMapVC.swift](https://github.com/ProximityViz/TIY-Lunch-iOS/blob/master/TIY%20Lunch/MainMapVC.swift) ### Map and Info For Each Venue [VenueVC.swift](https://github.com/ProximityViz/TIY-Lunch-iOS/blob/master/TIY%20Lunch/VenueVC.swift) --- template: inverse # The End! Slideshow created using [remark](http://github.com/gnab/remark). --- name: last-page template: inverse # Show-and-Tell