Lambda Taggable Geonames
Why?
Locating Hotels and other content by searching for a place name is the heart of the Tagging system. We use Geonames to "reverse geocode" the Lat/Lon for each Hotel in the database and add "hierarchy" for that place.
See: How? > Detail section for detailed example
What?
Lambda function that accepts a set of Longitude & Latitude coordinates (lat/lon) and returns a list of Geo Tags. (corresponding to the elements in the Geonames hierarchy for that lat/lon).
How?
There are two ways to use this package:
Lambda
-
Deploy the Lambda function by running the deployment script:
npm run deploy
( see: https://github.com/numo-labs/aws-lambda-deploy for detail ) -
Invoke in AWS Console:
Sample Event
"_id": "hotel:mhid.02tu1jz" "displayName": "Elvis Presley's Heartbreak" "location": "lat": "35.04850" "lon": "-90.02710" "tags":
Will return an array of Geo Tags in the Taggable System format:
"_id": "geo:geonames.6295630" "displayName": "Earth" "location": "lat": "0" "lon": "0" "tags": "_id": "geo:geonames.6255149" "displayName": "North America" "location": "lat": "46.07323" "lon": "-100.54688" "tags": "tagId": "geo:geonames.6295630" "displayName": "Earth" "source": "geonames" "inherited": false "active": true "_id": "geo:geonames.6252001" "displayName": "United States" "location": "lat": "39.76" "lon": "-98.5" "tags": "tagId": "geo:geonames.6255149" "displayName": "North America" "source": "geonames" "inherited": false "active": true "tagId": "geo:geonames.6295630" "displayName": "Earth" "source": "geonames" "inherited": false "active": true "_id": "geo:geonames.4662168" "displayName": "Tennessee" "location": "lat": "35.75035" "lon": "-86.25027" "tags": "tagId": "geo:geonames.6252001" "displayName": "United States" "source": "geonames" "inherited": false "active": true "tagId": "geo:geonames.6255149" "displayName": "North America" "source": "geonames" "inherited": false "active": true "tagId": "geo:geonames.6295630" "displayName": "Earth" "source": "geonames" "inherited": false "active": true "_id": "geo:geonames.4657046" "displayName": "Shelby County" "location": "lat": "35.184" "lon": "-89.8956" "tags": "tagId": "geo:geonames.4662168" "displayName": "Tennessee" "source": "geonames" "inherited": false "active": true "tagId": "geo:geonames.6252001" "displayName": "United States" "source": "geonames" "inherited": false "active": true "tagId": "geo:geonames.6255149" "displayName": "North America" "source": "geonames" "inherited": false "active": true "tagId": "geo:geonames.6295630" "displayName": "Earth" "source": "geonames" "inherited": false "active": true "_id": "geo:geonames.4645760" "displayName": "Nonconnah" "location": "lat": "35.06204" "lon": "-90.0362" "tags": "tagId": "geo:geonames.4657046" "displayName": "Shelby County" "source": "geonames" "inherited": false "active": true "tagId": "geo:geonames.4662168" "displayName": "Tennessee" "source": "geonames" "inherited": false "active": true "tagId": "geo:geonames.6252001" "displayName": "United States" "source": "geonames" "inherited": false "active": true "tagId": "geo:geonames.6255149" "displayName": "North America" "source": "geonames" "inherited": false "active": true "tagId": "geo:geonames.6295630" "displayName": "Earth" "source": "geonames" "inherited": false "active": true
Node Module
If you prefer to use this package as a node module e.g: as part of another lambda
npm install lambda-taggable-geonames-indexer --save
Then in your code:
var geonames = ;var lat = '28.3852';var lon = '81.5639';geonames;
Detail
The best way to understand how this works is with a simple example:
Imagine we have a Hotel in Formenterra
"MID": "1234ABCD" "Name": "Blanco Hotel Formentera" "Country": "SPAIN" "ISO-2": "ES" "Address": "Calle Fonoll Marí, 50 07871 Es Pujols" "Latitude": "38.7" "Longitude": "1.467"
We would lookup this hotel in Geonames given its Latitude
and Longitude
values using the following query:
"geonames": "distance":"1.31434" "timezone": "gmtOffset":1 "timeZoneId":"Europe/Madrid" "dstOffset":2 "asciiName":"Sant Ferran de ses Roques" "countryId":"2510769" "fcl":"P" "adminId2":"6424360" "adminId3":"6356033" "countryCode":"ES" "adminId1":"2521383" "lat":"38.70762" "fcode":"PPL" "continentCode":"EU" "elevation":0 "adminCode2":"PM" "adminCode3":"07024" "adminCode1":"07" "lng":"1.45543" "geonameId":6696037 "toponymName":"Sant Ferran de ses Roques" "population":10757 "adminName5":"" "adminName4":"" "adminName3":"Formentera" "alternateNames": "name":"http://en.wikipedia.org/wiki/Sant_Ferran_de_ses_Roques" "lang":"link" "adminName2":"Balearic Islands" "name":"Sant Ferran de ses Roques" "fclName":"city, village,..." "countryName":"Spain" "fcodeName":"populated place" "adminName1":"Balearic Islands"
From this response get the geonameId
which we can use to run the
hierarchy query:
http://api.geonames.org/hierarchyJSON?geonameId=6696037&username=demo
"geonames": "lng":"0" "geonameId":6295630 "name":"Earth" "fclName":"parks,area, ..." "toponymName":"Earth" "fcodeName":"area" "adminName1":"" "lat":"0" "fcl":"L" "fcode":"AREA" "population":6814400000 "lng":"9.14062" "geonameId":6255148 "name":"Europe" "fclName":"parks,area, ..." "toponymName":"Europe" "fcodeName":"continent" "adminName1":"" "lat":"48.69096" "fcl":"L" "fcode":"CONT" "population":0 "adminCode1":"00" "lng":"-4" "geonameId":2510769 "toponymName":"Kingdom of Spain" "countryId":"2510769" "fcl":"A" "population":46505963 "countryCode":"ES" "name":"Spain" "fclName":"country, state, region,..." "countryName":"Spain" "fcodeName":"independent political entity" "adminName1":"" "lat":"40" "fcode":"PCLI" "adminCode1":"07" "lng":"1.45871" "geonameId":6356033 "toponymName":"Formentera" "countryId":"2510769" "fcl":"A" "population":10757 "countryCode":"ES" "name":"Formentera" "fclName":"country, state, region,..." "countryName":"Spain" "fcodeName":"third-order administrative division" "adminName1":"Balearic Islands" "lat":"38.71905" "fcode":"ADM3"
Expected Environment Variables
Running the Lambda/Script
Using this script requires that you set a GEONAMES_USERNAMES
environment variable (one or more usernames)
e.g:
export GEONAMES_USERNAME=yourusername,backupusername,etc
Deploying
Deploying to AWS requires that you set AWS_REGION
and AWS_IAM_ROLE
variables.
e.g:
export AWS_REGION=eu-west-1export AWS_IAM_ROLE=arn:aws:iam::123456789:role/LambdaExecRole
Setup Geonames Account
To use this module you will require a Geonames account. If you have not already signed up, visit: http://www.geonames.org/login
Next, ensure that you have enabled the "Free Web Service" for your Geonames account:
Go to: http://www.geonames.org/manageaccount and scroll to the bottom of the page you will see a link "Click here to enable" click it.
Once enabled you should see a confirmation message:
Now everything should work as expected.
Running low on Geonames API Calls/Credits?
see: https://github.com/numo-labs/lambda-taggable-geonames-indexer/issues/5
Tests
to run the tests for this project execute the following command in your terminal:
npm test