Skip to content

Rails 5 API: Given an x,y coordinate, return information on the intersecting municipality (worldwide). Raspberry Pi's and Docker used for deployment.

Notifications You must be signed in to change notification settings

greghorne/CoordinateInfo-API

Repository files navigation

CoordinateInfo-API

Scope:

-   Rails 5.2.1 API
-   Given an x, y coordinate, return country and municipality information that intersects the coordinates.

Data Source:

-   GADM dataset of Global Administrative Area - www.gadm.org
-   File version 3.6 (June 2018 - gadm36_shp.zip)

Tech Stack:

-   Development Machine - Vagrant ubuntu/trusty32 - (3.13.0-110-generic)
-   Vagrant Box setup script: https://github.com/greghorne/VagrantRailsBox/blob/master/setup.sh

-   Ruby 2.5.1p57 (2018-03-09 revision 63029) [i686-linux]
-   Rails 5.2.1
-   Redis 4.0.11

-   PostgreSQL 9.4 with PostGIS 2.1.4
    Executing on a Raspberry Pi 2 Model B running Raspbian-Jessie
-   MongoDB v4.0.1
    Executing as a Docker 18.06.1-ce swarm replica set, primary, secondary & arbiter, on a Raspberry Pi 3 B running HypriotOS x64
-   (Note: PostgreSQl & MongoDB contain the same gadm36 dataset)
   
-   API tested with Postman (see 'test' folder for JSON test files)
   
-   Rails API deployed as a Docker container on a Raspberry Pi 3 B:  http://zotac1.ddns.net:3100

API Usage:

- Requests are throttled to 100 requests per 2 minutes per ip.

- http://zotac1.ddns.net:3100/api/v1?longitude_x=float&latitude_y=float&db=db_type&key=optional

    longitude_x = type: float 
    latitude_y  = type: float 
    db          = type: string ==> pg (default) or mongo 

- Return value is JSON
    {
        "success": integer         1 = success, 0 = error (check this value first)
        "response": {
            country:               country name in English
            municipality1:         municipality name in English
            municipality_nl1:      municipality name in native language
            municipality_nl_type1: municipality type in native language spelled in English
            municipality2:         municipality name in English
            municipality_nl2:      municipality name in native language
            municipality_nl_type2: municipality type in native language spelled in English
            municipality3:         municipality name in English
            municipality_nl3:      municipality name in native language
            municipality_nl_type3: municipality type in native language spelled in English
        }
    }

    if success = 0 then "response" will contain a "msg" (see below for example)

Example API Calls:

- example http://zotac1.ddns.net:3100/api/v1/coord_info?longitude_x=88.445670&latitude_y=23.243660

    returns JSON (intersects location in India)

    {
        "success": 1,
        "response": {
            "country": "India",
            "municipality1": "West Bengal",
            "municipaltiy_nl1": "",
            "municipality_nl_type1": "State",
            "municipality2": "Nadia",
            "municipaltiy_nl2": "",
            "municipality_nl_type2": "District",
	        "municipality3": "Ranaghat",
    		"municipaltiy_nl3": "",
	        "municipality_nl_type3": "Taluk"
        }
    }

    read as:
        (India, West Bengal State, Nadia District, Ranaghat Taluk)


- example http://zotac1.ddns.net:3100/api/v1/coord_info?db=mongo&longitude_x=-95.992775&latitude_y=36.153980

    returns JSON (intersects location in Tulsa, OK)

    {
        "success": 1,
        "response": {
            "country": "United States",
            "municipality1": "Oklahoma",
            "municipaltiy_nl1": "",
            "municipality_nl_type1": "State",
            "municipality2": "Tulsa",
            "municipaltiy_nl2": "",
            "municipality_nl_type2": "County",
	        "municipality3": null,
    		"municipaltiy_nl3": null,
	        "municipality_nl_type3": null
        }
    }

    read as:
        (United States, Oklahoma State, Tulsa County)


- example http://zotac1.ddns.net:3100/api/v1/coord_info?longitude_x=116.407396&latitude_y=39.904200

    returns JSON (intersects location in China)

    {
        "success": 1,
        "response": {
            "country": "China",
            "municipality1": "Beijing",
            "municipaltiy_nl1": "北京|北京",
            "municipality_nl_type1": "Zhíxiáshì",
            "municipality2": "Beijing",
            "municipaltiy_nl2": "北京|北京",
            "municipality_nl_type2": "Zhíxiáshì",
	        "municipality3": "Beijing",
    		"municipaltiy_nl3": "北京|北京",
	        "municipality_nl_type3": "Zhíxiáshì"
        }
    }

    read as:
        (China, Beijing Zhíxiáshì)
                    or
        (China, 北京|北京 Zhíxiáshì)

        The data repeats iteself with: 北京|北京.  北京 = Beijing
        The left side of | is for old characters and the right side is for new characters.
        In this case, they are the same and there is no difference.
        Try different locations in China and the left vs right side differences can be observed.


- example http://zotac1.ddns.net:3100/api/v1/coord_info?longitude_x=34.299316&latitude_y=43.413029

    returns JSON (intersects location in The Black Sea):
    {
        "success": 1,
        "response": { }
    }


- example http://zotac1.ddns.net:3100/api/v1/coord_info?longitude_x=-200&latitude_y=15.552727

    returns JSON (invalid longitude_x):
    {
        "success": 0,
        "response": {
            "msg": "invalid longitude_x and/or latitude_y"
        }
    }

- example http://zotac1.ddns.net:3100/api/v1/coord_info?longitude_x=48.516388&latitude_y=15.552727

    returns JSON (intersects location in Yemen): 
    {
        "success": 1,
        "response": {
            "country": "Yemen",
            "municipality1": "Hadramawt",
            "municipaltiy_nl1": "حضرموت",
            "municipality_nl_type1": "Muhafazah",
            "municipality2": "Wadi Al Ayn",
            "municipaltiy_nl2": "وادي العين وحوره",
            "municipality_nl_type2": "Muderiah",
            "municipality3": null,
            "municipaltiy_nl3": null,
            "municipality_nl_type3": null
        }
    }

    read as:
        (Yemen, Hadramawt Muhafazah, Wadi Al Ayn Muderiah) 
                               or
        (Yemen, حضرموت Muhafazah, وادي العين وحوره Muderiah)

Notes:

- There are additonal columns in the dataset but I have cut them off after the first three interations of a location.

- Creating this app has been a weird trip
  
  rails new . --api --skip-turbolinks --skip-puma --database=postgresql (which is what finally worked)

  --skip-active-records ==> if used as an option I never could create a controller 
  Instead of a controller, I tried putting code into an .rb file in lib/.  This would work in
  'development' but once I switched to 'production' then rails couldn't find the lib/file.rb.
  Googled the issue and tried a number of 'solutions'.  I never could resolve this issue.
  Basically, you can't generate a new controller on the command line without active records and a db.

  repo CoordinateInfoAPI was the previous version I worked on that in the end I just had to dump the project.

About

Rails 5 API: Given an x,y coordinate, return information on the intersecting municipality (worldwide). Raspberry Pi's and Docker used for deployment.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages