by Gerard Sans |  @gerardsans

Finding a

bike in London with AWS Amplify

Finding a

bike in London with AWS Amplify

SANS

GERARD

Developer Advocate AWS

Developer Advocate AWS

Benefits

  • Transport flexibility
  • Reduce traffic emissions
  • Reduce traffic congestion
  • Health benefits for users

International Speaker

Spoken at 149 events in 37 countries

Bike Sharing

Santander Cycles

Overview

  • Since 2010
  • +12,000 Bikes
  • 778 stations

Boris Bikes

LNDBikes

Fullstack Serverless

🦄

🌩️

Icons made by Gregor Cresnar from www.flaticon.com is licensed by CC 3.0 BY
Icons made by Darius Dan from www.flaticon.com is licensed by CC 3.0 BY

No servers to manage

Fault tolerance High availability

background Layer 1

Never pay for idle usage

Auto-scales immediately

Serverless

$

AWS AMPLIFY

Categories

interactions

storage

notifications

auth

analytics

function

amplify add <category>

api

hosting

xr

AWS-AppSync_light-bg
Amazon-Pinpoint_light-bg
Amazon-S3_light-bg
AR-VR_light-bg
Amazon-Cognito_light-bg
Amazon-Lex_light-bg
Amazon-Kinesis_light-bg
AWS-Lambda_light-bg
Amazon-CloudFront_light-bg

transcribe

rekognition

translate

comprehend

amplify add predictions

polly

London

Unified API

/BikePoint

/BikePoint/id

TfL Unified API

/BikePoint/Search

Data Strategies

0.5s

2s

0.6 KB

/BikePoint/id

3.45s

1s

1.7 MB

/BikePoint

slow 3G

fast 3G

[
  {
    "id": "BikePoints_1",
    "commonName": "River Street , Clerkenwell",
    "additionalProperties": [{
      "key": "NbBikes", "value": "11",
     }],
    "lat": 51.529163,
    "lon": -0.10997
  }
  // 777 more
]

/BikePoint

{
  "id": "BikePoints_1",
  "commonName": "River Street , Clerkenwell",
  "additionalProperties": [{
    "key": "NbBikes", "value": "11",
  }],
  "lat": 51.529163,
  "lon": -0.10997
}

/BikePoint/BikePoints_1

Loading   bike stations

Data Transformations

GeoJSONfeature

BikesPoint

{
  "type": "Feature",
  "geometry": {
    "type": "Point",
    "coordinates": [-0.10997, 51.529163]
  },
  "properties": {
    "id": "BikePoints_1",
    "name": "River Street , Clerkenwell"
  }
}

geoJSON feature

Coordinates = [-0.109971, 51.529163]

51.529163

-0.109971

Coordinates

Data Transformations

GeoJSONfeature

BikesPoint

mapbox Source

mapbox Layer

REST API integration

type BikePoint @model {
  id: ID!
  name: String!
  description: String
  location: Location!
  bikes: Int
}

GraphQL Schema

// request VTL template
{
  "version": "2018-05-29",
  "method": "GET",
  "resourcePath": "/BikePoint/$context.source.id",
}

BikePoint.bikes HTTP Resolver

// response VTL template
#set($body = $util.parseJson($ctx.result.body))
#if($ctx.error)
  $util.error($ctx.error.message, $ctx.error.type)
#end
#if($ctx.result.statusCode == 200)
  $body.additionalProperties[6].value
#else
  #return
#end

BikePoint.bikes HTTP Resolver

Adding Search

type BikePoint @model @searchable {
  id: ID!
  name: String!
  description: String
  location: Location!
  bikes: Int
}
type Location {
  lat: Float!
  lon: Float!
}
type Query {
  nearbyBikeStations(location: LocationInput!, m: Int, limit: Int)
}

GraphQL Schema

Data Transformations

GeoJSONfeature

BikesPoint

GraphQL API

Elastic Search

# Create index
PUT /bikepoint

# Setup location type as geo_point
PUT /bikepoint/_mapping/doc
{
  "properties": {
    "location": {
      "type": "geo_point"
    }
  }
}

Elastic Search index

mutation addBikePoint {
  createBikePoint(input: { 
    id: "BikePoints_1" 
    name: "River Street , Clerkenwell" 
    location: { 
      lat: 51.529163 
      lon: -0.10997 
    } 
  }) { id }
}

Automatic indexing

GET /bikepoint/doc/_search
{ 
  "query": {
    "bool" : {
      "must" : { "match_all" : {} },
      "filter" : {
        "geo_distance" : {
          "distance" : "500m",
          "distance_type": "arc", 
          "location" : {
            "lon": -0.134167, "lat": 51.510239
          }

Query nearbyBikeStations (1/2)

  "sort": [{
    "_geo_distance": {
      "location": {
        "lon": -0.134167, "lat": 51.510239
      },
      "order": "asc",
      "unit": "m",
      "distance_type": "arc"
    }
  }]
}

Query nearbyBikeStations (2/2)

Distance Calculations

[lon1, lat1]

[lon2, lat2]

Haversine Formula

Great-circle distance

Distance Calculations

double distance(double lat1, double lon1, double lat2, double lon2) {
  return 6378137 * haversine(lat1, lon1, lat2, lon2);
}

double haversine(double lat1, double lon1, double lat2, double lon2) {
  double hsinX = Math.sin((lon1 - lon2) * 0.5);
  double hsinY = Math.sin((lat1 - lat2) * 0.5);
  double h = hsinY * hsinY + (Math.cos(lat1) * Math.cos(lat2) * hsinX * hsinX);
  return 2 * Math.atan2(Math.sqrt(h), Math.sqrt(1 - h));
}

ElasticSearch arc distance (WGS 84)

More

@undef_obj

@kurtiskemple

@dabit3

Kurt Kemple

Richardo

Nader Dabit

@TheSwaminator 

Nikhil Swaminathan

Finding a bike in London with AWS Amplify

By Gerard Sans

Finding a bike in London with AWS Amplify

Are you visiting London and want a bike to move around? Are you with some friends? No worries. In this talk, we are going to build LNDBikes an app to find in real-time how many bikes are available so you and your friends are good to go and enjoy a great ride. We will be using the Transport for London Unified API to query the data and show it in a map using mapbox GL JS. There are more than 750 docking stations across London with 12K bikes. We will build our client using the latest versions of AWS Amplify, GraphQL and Angular. Awesome!

  • 2,392