How to: get ODM data using ODM-API

×

Warning message

  • You can't delete this newsletter because it has not been sent to all its subscribers.
  • You can't delete this newsletter because it has not been sent to all its subscribers.

There are two main calls that can be used to retrieve ODM data:

  • get: used to retrieve the inbound or outbound flow values between a selected position and the available origins/destinations
  • polygon: used to retrieve the polygon used to describe a specific area

 

Examples

get:

https://www.snap4city.org/odmm/api/get?latitude=43.78089&longitude=11.26116&precision=ace&from_date=2024-11-04+00%3A00%3A00&organization=DISIT&inflow=True&od_id=FI-PO-PT-Test0_DISIT_ACE&perc=False&contextbroker=orionUNIFI

OLD: https://odmm.snap4city.org/api/get?latitude=43.78089&longitude=11.26116&precision=ace&from_date=2024-11-04+00%3A00%3A00&organization=DISIT&inflow=True&od_id=FI-PO-PT-Test0_DISIT_ACE&perc=False

where:

  • latitude and longitude are the coordinates of a point (inside of an OD area)
  • from_date is the initial datetime
  • organization the org owning the OD matrix
  • inflow (True/False) tells whether retrieving the inbound (True) or outbound (False) flows
  • od_id is the OD name
  • perc (True/False) is used to specify if the flow values must be returned as absolute values (False) or percentage values (True) computed w.r.t. the total inbound/outbound flow number

This call returns a JSON like

{

    "type": "FeatureCollection",

    "features": [

        {

            "type": "Feature",

            "id": 9144,

            "geometry": {

                "type": "MultiPolygon",

                "coordinates": [

                    []

                ]

            },

            "properties": {

                "name": 9144,

                "txt_name": "Firenze_ACE23",

                "density": 13

            }

        },

...

   ]

}

 

that is a JSON object where the features array includes objects that are the origin/destination with respect to the selected point (area). Each feature object includes the geometry filed describing the polygon of the origin/destination area, and the properties with the area ID (name and txt_name) and the flow (density).

In the case for the selected point/area no flow data is available an empty array is returned.

polygon:

https://www.snap4city.org/odmm/api/polygon?latitude=43.78089&longitude=11.26116&type=ace&organization=DISIT&contextbroker=orionUNIFI

OLD: https://odmm.snap4city.org/api/polygon?latitude=43.78089&longitude=11.26116&type=ace&organization=DISIT

where:

  • latitude and longitude are the coordinates of a point (inside of an OD area)
  • type describes the area type
  • organization the org owning the OD matrix

This call returns a JSON like

{

    "type": "FeatureCollection",

    "features": [

        {

            "type": "Feature",

            "id": 9031,

            "geometry": {

                "type": "MultiPolygon",

                "coordinates": [

                    ...   

                ]

            },

            "properties": {

                "name": 9031,

                "txt_name": "Firenze_ACE12"

            }

        }

    ]

}

 

that is a JSON object where the features array includes the area ID and its geometry, while the properties filed includes the area ID name and txt_name.

An empty response ({"type": "FeatureCollection", "features": []}) is returned if no polygon for the specified type is available for the selected point/area.

 

Specific Information on FI-PO-PT ODM

  • od_id: FI-PO-PT-Test1_DISIT_ACE
  • max flow: 1414
  • min flow: 4
  • avg flow: 25.23
  • datetime:
    • 2024-11-04 from 00:00 to 23:59 (with one hour granularity)
    • 2024-11-05 from 00:00 to 23:59 (with one hour granularity)
    • 2024-11-06 from 00:00 to 23:59 (with one hour granularity)
    • 2024-11-07 from 00:00 to 23:59 (with one hour granularity)
    • 2024-11-08 from 00:00 to 23:59 (with one hour granularity)
    • 2024-11-09 from 00:00 to 23:59 (with one hour granularity)
    • 2024-11-10 from 00:00 to 23:59 (with one hour granularity)
    • 2024-11-11 from 00:00 to 23:59 (with one hour granularity)
    • 2024-11-12 from 00:00 to 23:59 (with one hour granularity)
    • 2024-11-13 from 00:00 to 23:59 (with one hour granularity)
    • 2024-11-14 from 00:00 to 23:59 (with one hour granularity)
    • 2024-11-15 from 00:00 to 23:59 (with one hour granularity)
  • owning organization: DISIT
  • API endpointhttps://www.snap4city.org/odmm/api/
  • contextbroker: orionUNIFI
  • covered areas: this ODM describe flows from or toward ACE areas in Tuscany with at least the origin or the destination in Firenze, Prato, or Pistoia municipalities. See the origins.csv and destinations.csv files for a list of areas included in the ODM (and for each area an example lat/lon point that can be used in the calls)

FILES:

https://www.snap4city.org/drupal/sites/default/files/files/destinations.zip

https://www.snap4city.org/drupal/sites/default/files/files/origins.zip

Example of authenticated ODM access

import requests
import sys
URL_GET = "https://www.snap4city.org/odmm/api"
USER = "<your Snap4City username>"
PSW = "<your Snap4City password>"

def accessTokenDelegated(user, psw):
    """Get the authentication token from keycloak. Uses global variables to ease programming. Uses the delegated credentials
 

    Args:
        usr (str): username credentials

        psw (str): password credential
 
    Returns:
        str | None: The access_token returned from the keycloak service

    """    
    access_token = ''
    payload = {
        'f': 'json',
        'client_id': "js-kpi-client",
        'grant_type': 'password',
        'username': user,
        'password': psw,
// OLD        'scope': 'openid' # only for MicroX
    }
 
    header = {
        'Content-Type': 'application/x-www-form-urlencoded'
    }
 
    urlToken = "https://www.snap4city.org/auth/realms/master/protocol/openid-connect/token"

//OLD # conf.get('token').get('token_url')
    
    try:
        response = requests.request("POST", urlToken, data=payload, headers=header)
        response.raise_for_status()
    except requests.exceptions.HTTPError as errh:
        print("Http Error:", errh)
    except requests.exceptions.ConnectionError as errc:
        print("Error Connecting:", errc)
    except requests.exceptions.Timeout as errt:
        print("Timeout Error:", errt)
    except requests.exceptions.RequestException as err:
        print("Ops: Something Else", err)
    else:
        token = response.json()
        access_token = token['access_token']
 
    return access_token
 
def get_gadm_istat(header, data, contextbroker):
    response = requests.get(URL_GET + '/get?' + f"contextbroker={contextbroker}", params=data , headers=header)
    return response.json(), response.status_code

def get_polygon(header, data, contextbroker):
    response = requests.get(URL_GET + '/polygon?' + f"contextbroker={contextbroker}", params=data , headers=header)
    return response.json(), response.status_code

if __name__ == "__main__":
    contextbroker='orionUNIFI'
    organization='DISIT'
    precision = 'ACE'

    od_name = "FI-PO-PT-Feb24"

    od_id = od_name + "_" + organization + "_" + precision

    from_date = "2024-02-13 09:00"

    token = accessTokenDelegated(USER, PSW)
    header = {
        "Authorization": f"Bearer {token}"
    }

    # ISTAT
    data = {
        "organization": organization,
        "precision": 'municipality',
        "from_date": from_date,
        "latitude": '43.77996790468745',
        "longitude": '11.244942607789538',
        "inflow": True,
        "od_id": od_id,
        "perc": False
    }
    result, status = get_gadm_istat(header, data, contextbroker)

    data = {
        "type": "ace", 
        "latitude": '43.77996790468745',
        "longitude": '11.244942607789538',
        "organization": organization
    }
    result, status = get_polygon(header, data, contextbroker)
 

-- last update 20-06-2025 --