12 Location

As a mobile app developer, you can use the Oracle Mobile Cloud Service (MCS) Location API to access details about location devices, places and assets that have been registered in MCS.

What Can I Do With Location?

In this age of context, users expect information to be presented based on their current situation and individual needs and preferences. One of the most important contextual data points is location. The impact of location-aware mobile apps on users and businesses is growing faster every day.

  • Everyone knows about using navigation apps for location data, including getting directions to a street address and finding restaurants, hotels, airports, hospitals, and just about anything else you might need in a geographic area.

  • You can implement location-based functionality in a wide range of apps, like focused queries and location-aware history.

  • Your apps can use location data to send notifications targeted to mobile devices in a geographic area or a certain mobile user or asset only in a specific geographic area.

  • Location-aware applications can also contribute a lot to business intelligence and analytics, including customer profiling and demographics, competitive analysis and supply chain tracking.

This chapter discusses how to use these Location APIs to perform common tasks. For more details on using the platform APIs, see REST APIs for Oracle Mobile Cloud Service.

Setting Up Location Devices, Places and Assets

Location devices, places and assets provide the tools you need to create location-aware mobile apps.

  • A location device is any device that provides location services, like a Bluetooth proximity beacon. Location devices transmit an ID within a defined space, so mobile apps can use these signals to trigger notifications and other actions. The following location protocols are currently supported:
    • AltBeacon is an open source protocol for Bluetooth proximity beacons. For more information and the full specification, see altbeacon.org and https://github.com/AltBeacon/spec.

    • Eddystone is Google’s open protocol for Bluetooth proximity beacons. For details, see https://github.com/google/eddystone.

    • iBeacon is the Apple protocol for Bluetooth proximity beacons. For details, see https://developer.apple.com/ibeacon/.

  • A place is a physical location associated with one or more location devices.

  • An asset is a mobile physical object that’s associated with one or more location devices.

To set up a location in MCS, define the related places and/or assets and register the associated location devices in the MCS UI under Applications > Location. You can also use the Location Management API to create, update and delete location devices, places and assets from custom code. For details, see Accessing the Location Management API from Custom Code.

Defining Places

A place is a physical location associated with one or more location devices. You can define places through the UI individually or by uploading a CSV file. You can also use the Location Management API to create, update and delete places from custom code. For details, see Accessing the Location Management API from Custom Code.

Note:

To manage places in the MCS UI, you need to be assigned the MobileEnvironment_LocationMgmt MCS team member role in the environment.
  1. Click icon to open the side menu to open the side menu and select Applications > Location.
  2. From the Places tab, click New Place to define a place using the UI. This tab shows all the places defined. To edit an existing place, select it in the list and click Edit Place.
  3. If you are creating a new place, enter a name, and an optional label and description. If you enter a new label, it will be saved and can be used to categorize other places, location devices and assets. Click Create.
  4. On the Overview tab of the Location Place Editor, enter the GPS coordinates for the place. You can also define a geofence by radius or polygon. To associate the place with another existing place, select that place from the Parent dropdown.
  5. Click the Attributes tab to define custom attributes for the place. Create new attributes or copy them from an existing place. You can use attributes to associate a content URI with the place, for example a coupon or flier that a mobile app downloads when the user is nearby. Attributes can also be used to filter results in queries that use the Location Platform API.
  6. Click the Devices tab to associate location devices with the place. You can register a new device from this page (Registering Location Devices) or select from location devices already registered. A device can be associated with a single place or asset, not both. By default, only the devices for the current place are displayed, but you can expand the list by selecting Show all devices associated with children of this place.
  7. When you are done configuring the place, click Save.
Uploading Places Using a CSV File
You can upload multiple places using a CSV file.
  1. From the Location : Places page, click Upload Places.
  2. Browse to the .csv file and click Upload.
    The CSV file for uploading places must follow the following format:
    #version=1.0
    #name,#label,#description,#GPSPoint,#GPSCircle,#GPSPolygon,#list of Attributes
    name,label,description,lat:lon,lat:lon:radius,lat1:lon1;lat2:lon2;lat3:lon3,key1=val1,key2=val2
    
    The first line specifies the version, and the second line is for usability. Any line that starts with # is considered a comment line and is ignored.
    The data starts on line 3. For each line of data, you can define one type of place:
    • For specific GPS coordinates (GPSPoint), include the latitude and longitude.

    • For a circle geofence (GPSCircle), include the latitude and longitude of the center point, and the radius. In Oracle Spatial, GPS circles are converted to polygons, which might cause the radius to be recalculated.

    • For a polygon geofence (GPSPolygon), include the latitude and longitude for each corner of the polygon.

    Make sure to include commas for any empty properties to define the entry correctly. For example, the CSV file below defines a GPSPoint.
    #version=1.0
    #name,#label,#description,#GPSPoint,#GPSCircle,#GPSPolygon,#list of Attributes
    FixitFast Redwood City Warehouse,Warehouse,FixitFast Warehouse in Redwood City,37.8453:-121.7845,,,key1=val1,prop2=val2,prop3=val3
    

    Note:

    The expected encoding for the CSV file is Unicode UTF-8, so it’s best to use a text editor to edit CSV files. Opening a CSV file in Excel or another spreadsheet application can corrupt the encoding or add extra lines. If you use another application to edit your CSV files, confirm that the encoding is correct in a text editor before uploading the file.

Defining Location Assets

An asset is a physical object that’s associated with one or more location devices, typically something mobile and valuable like a forklift or hospital bed. You can define location assets through the UI individually or by uploading a CSV file. You can also use the Location Management API to create, update and delete location assets from custom code. For details, see Accessing the Location Management API from Custom Code.

Note:

To manage location assets in the MCS UI, you need to be assigned the MobileEnvironment_LocationMgmt MCS team member role in the environment.
  1. Click icon to open the side menu to open the side menu and select Applications > Location.
  2. From the Assets tab, click New Asset to define a location asset using the UI. This tab shows all the assets defined. To edit an existing asset, select it in the list and click Edit Asset.
  3. If you are creating a new asset, enter a name, and a label and description if you choose. Labels will be saved and can be used to categorize other location assets. If the device(s) you want to associate with the asset are already registered, you can select them on this page. (A device can be associated with a single place or asset, not both.) Click Create.
  4. On the Overview tab of the Location Asset Editor, you can update your entries.
  5. Click the Attributes tab to define custom attributes for the asset. Create new attributes or copy them from an existing asset. You can use attributes to associate a content URI with the asset, for example a coupon or flier that a mobile app downloads when the user is nearby. Attributes can also be used to filter results in queries that use the Location Platform API.
  6. When you are done configuring the asset, click Save.
Uploading Assets Using a CSV File
You can upload multiple assets using a CSV file.
  1. From the Location : Assets page, click Upload Assets.
  2. Browse to the .csv file and click Upload.
    The CSV file for uploading assets must follow the following format:
    #version=1.0
    #name,#description,#label,#list of Attributes
    Name,Description,label,key1=val1,key2=val2
    
    The first line specifies the version, and the second line is for usability. Any line that starts with # is considered a comment line and is ignored.
    The data starts on line 3, as shown in the example below. Make sure to include commas for any empty properties to define the entry correctly.
    #version=1.0
    #name,#description,#label,#list of Attributes
    RC_WH_01_F01_B023,Beacon #23 in the FixItFast Warehouse in Redwood City,beacon,
    FiF Warehouse Forklift #6,MyMed DA332 forklift,forklift,EquipmentManufacturer=MyMed,MyMed serial number=OU812-9845873 
    Hospital Bed #233,MyMed model 1225 hospital bed,hospital bed,EquipmentManufacturer=MedBed,SJId=6754843090

    Note:

    The expected encoding for the CSV file is Unicode UTF-8, so it’s best to use a text editor to edit CSV files. Opening a CSV file in Excel or another spreadsheet application can corrupt the encoding or add extra lines. If you use another application to edit your CSV files, confirm that the encoding is correct in a text editor before uploading the file.

Registering Location Devices

A location device is any device that provides location services, like a Bluetooth proximity beacon. You can define location devices through the UI or by uploading a CSV file.
  1. Click icon to open the side menu to open the side menu and select Applications > Location.
  2. From the Devices tab, click New Device to register a location device using the UI. This tab shows all the location devices defined. To edit an existing device, select it in the list and click Edit Device. (You can also register devices from the Devices tab in the Location Places Editor.)
  3. If you are creating a new location device, enter a name and a description. Select the Protocol:
    • altBeacon
    • Eddystone
    • iBeacon

    Note:

    The protocol can’t be changed after a device is registered.
    Click Create.
  4. On the Overview tab of the Location Device Editor, enter the identifying information for the location device. The required values depend on the selected protocol:
    • For iBeacon, enter the UUID, Minor and Major values.
    • For altBeacon, enter ID1, ID2 and ID3.
    • For Eddystone, enter the Namespace, Instance and URL.
    If the place and/or asset you want to associate with the device is already defined, select it from the dropdown list. A device can be associated with a single place or asset, not both.
  5. Click the Attributes tab to define custom properties for the device. Create new attributes or copy them from an existing device. You can use attributes to associate a content URI with the device, for example a coupon or flier that a mobile app downloads when the user is nearby. Attributes can also be used to filter results in queries that use the Location Platform API.
  6. When you are done configuring the device, click Save.
Uploading Location Devices Using a CSV File
You can upload multiple location devices using a CSV file.
  1. From the Location : Devices page, click Upload Devices.
  2. Browse to the .csv file and click Upload.
    The CSV file for uploading devices must follow the following format:
    #version=1.0
    #name,#description,#uuid,#major,#minor,#id1,#id2,#id3,#namespace,#instance,#url,#list of Attributes
    Name,Description,uuid,major,minor,id1,id2,id3,namespace,instance,url,key1=val1,key2=val2
    The first line specifies the version, and the second line is for usability. Any line that starts with # is considered a comment line and is ignored.
    The data starts on line 3. For each line of data, you can define one protocol type. The required properties depend on the protocol type:
    • For iBeacon, include uuid, major and minor properties.

    • For altBeacon, include id1, id2 and id3 properties.

    • For Eddystone, include the namespace, instance and URL.

    Make sure to include commas for any empty properties to define the entry correctly. For example, the CSV file below registers an iBeacon location device by defining values for the uuid, major and minor properties.
    #version=1.0
    #name,#description,#uuid,#major,#minor,#id1,#id2,#id3,#namespace,#instance,#url,#list of Attributes
    RC_WH_01_F01_B001,Beacon on 1st Floor in FixitFast Warehouse in Redwood City,B9407F30-F5F8-466E-AFF9-25556B57FE6D,1.0,1.1,,,,,,,key1=val1,key2=val2,key3=val3

    Note:

    The expected encoding for the CSV file is Unicode UTF-8, so it’s best to use a text editor to edit CSV files. Opening a CSV file in Excel or another spreadsheet application can corrupt the encoding or add extra lines. If you use another application to edit your CSV files, confirm that the encoding is correct in a text editor before uploading the file.

Calling the Location API from Your App

Make your mobile apps location-aware by querying for and retrieving location devices, places and assets using the Location API. You can use the SDK for your platform or access the API directly through REST endpoints.

Team members with the MobileEnvironment_System role can use the Location Management REST API to add and maintain places, devices, and assets.

Querying for Location Devices, Places and Assets

The Location API allows you to write complex queries for location devices, places and assets. You can call the REST endpoint directly or use one of the SDKs to construct a query.

The available query parameters depend on the object type.
Querying for Location Devices
Query for location devices using the following REST endpoints:
  • GET {baseUri}/mobile/platform/location/devices?name={name} to query by the device name.

  • POST {baseUri}/mobile/platform/location/devices/query to query using parameters in a JSON payload as described below.

To define your query, include a JSON payload with the following options:
Parameter Description
name Filters results by a partial match of this string with the name defined for the device in the UI. Not case sensitive.
description Filters results by a partial match of this string with the description defined for the device in the UI. Not case sensitive.
search Filters results by a partial match of this string with the name or description defined for the device in the UI. Not case sensitive.
attributes Filters results by a match of the name-value pairs in the Attributes object, using the attributes defined for the device in the UI.
protocol Filters results by device protocol type(s):
  • iBeacon

  • altBeacon

  • eddystone

associatedAssetId The asset ID to search for. (Returns location devices associated with the specified asset.)
listOfDevices An array of device IDs to search for.
iBeacon_uuid The UUID of the iBeacon device(s) to search for.
iBeacon_major The major version of the iBeacon device to search for.
iBeacon_minor The minor version of the iBeacon device to search for.
altBeacon_id1 ID1 of the altBeacon to search for.
altBeacon_id2 ID2 of the altBeacon to search for.
altBeacon_id3 ID3 of the altBeacon to search for.
eddystone_namespace The namespace of the Eddystone device to search for.
eddystone_instance The instance of the Eddystone device to search for.
eddystone_url The URL of the Eddystone device to search for.
orderBy An enumeration of the field(s) to order results by. Can include any top-level attribute. Append the direction to order results by:
  • :asc for ascending

  • :desc for descending

For example, name:asc.
offset By default, 0 to start results at the first item. Specify an offset number to start results in a different place.
limit By default, 40 items are returned. You can specify a different maximum number of results, up to 100. Generally meant to be used with offset for pagination.
format By default, the response is in long format and results include the device id, name, description, attributes, createdOn and createdBy, as well as the place ID and identifying details about the device. Specify short to return only the device id, name, description and protocol.
The following example shows the request body in JSON format, requesting information about the iBeacon with the given properties.
{
  "protocol":"iBeacon",
  "iBeacon_major": "2.0",
  "iBeacon_minor": "2.2",
  "iBeacon_uuid": "B9407F30-F5F8-466E-AFF9-25556B57FE6D"
}
If the query is successful, the response will be 200, and the body will include the matching location device and its associated place or asset if it has one. For example:
{
  "items": [
    {
      "id": 15,
      "createdOn": "2015-11-11T21:15:34.341+0000",
      "createdBy": "thomas.smith@fif.com",
      "modifiedOn": "2015-11-11T21:15:34.341+0000",
      "modifiedBy": "thomas.smith@fif.com",
      "name": "RC_WH_01_F01_B003",
      "description": "Beacon on 1st Floor in FixItFast Warehouse in Redwood City",
		  "place": {
		    "name": "FixitFast Redwood City Warehouse",
	      "label": "FixitFast Warehouse",
	      "description": "FixitFast Warehouse in Redwood City",
        "address" : {
          "gpsPoint" : {
            "latitude": 37.5548,
            "longitude": -121.1566
          }
        },
        "attributes" : {
          "EquipmentManufacturer": "Abc Corp"
        },
        "links": [
           {
             "rel": "canonical",
             "href": "/internal-tools/1.0/envs/dev/location/places/9876"
           },
           {
             "rel": "self",
             "href": "/internal-tools/1.0/envs/dev/location/places/9876"
           }
         ]
	     },
  	   "beacon": {
        "iBeacon": {
          "major": "2.0",
          "minor": "2.2",
          "uuid": "B9407F30-F5F8-466E-AFF9-25556B57FE6D"
        }
      },
      "attributes": {
        "manufacturer": "Gimbal",
        "status": "Active",
        "manufacturerId": "10D39AE7-020E-4467-9CB2-DD36366F899D",
        "visibility": "Public"
      },
    },
  "totalResults": 1,
  "offset": 0,
  "limit": 20,
  "count": 1,
  "hasMore": false
}
The example below queries for altBeacon devices with “Warehouse” in the name or description and specifies the short response format, ordered by name, with a limit of 5 items.
{
    "protocol":"altBeacon",
    "orderBy":"name",
    "limit":"5",
    "format":"short",
    "search":"Warehouse"
}
If the query is successful, the response is 200 and the body contains just the id, name, description and protocol for the 5 returned devices.
{
    "items":[
        {
            "id":33,
            "name":"RC_WH_01_B09_C004",
            "description":"Beacon on 2nd Floor in FixItFast Warehouse in Redwood City",
            "protocol":"altBeacon"
        },
        {
            "id":12,
            "name":"RC_WH_01_F01_B001",
            "description":"Beacon on 1st Floor in FixItFast Warehouse in Redwood City",
            "protocol":"altBeacon"
        },
        {
            "id":61,
            "name":"RC_WH_01_F01_B008",
            "description":"Beacon on 2nd Floor in Fix*tFast Warehouse in Redwood City",
            "protocol":"altBeacon"
        },
        {
            "id":58,
            "name":"RC_WH_02_F01_B011",
            "description":"Beacon on 1st Floor in FixitFast Warehouse in Redwood City",
            "protocol":"altBeacon"
        },
        {
            "id":114,
            "name":"RC_WH_01_K22_A999",
            "description":"Beacon on 3rd Floor in FixitFast Warehouse in Redwood City",
            "protocol":"altBeacon"
        }
    ],
    "totalResults":5,
    "offset":0,
    "limit":5,
    "count":5,
    "hasMore":false
}
Querying for Places
Query for places with specific parameters using the following REST endpoints:
  • GET {baseUri}/mobile/platform/location/places?name={name} to query by the place name.

  • POST {baseUri}/mobile/platform/location/places/query to query using parameters in a JSON payload as described below.

To define your query, include a JSON payload with the following options:
Parameter Description
name Filters results by a partial match of this string with the name defined for the place in the UI. Not case sensitive.
description Filters results by a partial match of this string with the description defined for the place in the UI. Not case sensitive.
search Filters results by a partial match of this string with the name, label or description defined for the place in the UI. Not case sensitive.
attributes Filters results by a match of the name-value pairs in the Attributes object, using the attributes defined for the place in the UI.
label Filters results by a partial match of this string with the label specified for the place in the UI. Not case sensitive.
listOfPlaces An array of place IDs to search for.
descendantOf Specify a place ID to search for direct descendants.
nearestTo Specify a gpsPoint (latitude, longitude) to return the closest place. This parameter can’t be combined with other query parameters.
inGeoFence Specify a gpsCircle (latitude, longitude, radius) to return all places within that geofence.
descendantDevices Set to true to include the descendantDevices property in the results, which lists the devices associated with this place and all its child places. These results are always in short format.
orderBy An enumeration of the field(s) to order results by. Can include any top-level attribute. Append the direction to order results by:
  • :asc for ascending

  • :desc for descending

For example, name:asc.
offset By default, 0 to start results at the first item. Specify an offset number to start results in a different place.
limit By default, 40 items are returned. You can specify a different maximum number of results, up to 100. Generally meant to be used with offset for pagination.
format By default, the response is in long format and results include the place id, name, description, attributes, label, creation and modification data, as well as the place address, and a list of the devices within the place and the place’s parent. Specify short to return only the place id, name, description and label.
The following example shows the request body in JSON format, requesting information about places with the label “commercial” within the specified GPS circle, ordering results by name in ascending order and limiting results to 100:
{
  "label":"block 1",
  "inGeoFence": {
    "gpsCircle": {
      "latitude": 37.488179,
      "longitude": -122.229011,
      "radius": 32186
    }
   },
  "orderBy":"name:asc",
  "limit":100
}
If the query is successful, the response will be 200, and the body will include an array of matching places. In this example, only 2 places matched the query:
{
  "items": [
    {
      "id": 16,
      "createdOn": "2016-03-08T22:09:19.968+0000",
      "createdBy": "joe",
      "modifiedOn": "2016-03-08T22:09:19.968+0000",
      "modifiedBy": "joe",
      "name": "l1b1",
      "label": "lot 1 block 1",
      "parentPlace": 15,
      "description": "Lot 1 block 1 New City",
      "hasChildren": false,
      "address": {
        "gpsCircle": {
          "longitude": -120.87449998,
          "latitude": 37.98560003,
          "radius": 29999.99999997
        }
      },
      "links": [
        {
          "rel": "canonical",
          "href": "/mobile/platform/location/places/16"
        },
        {
          "rel": "self",
          "href": "/mobile/platform/location/places/16"
        }
      ]
    },
    {
      "id": 17,
      "createdOn": "2016-03-08T22:09:20.065+0000",
      "createdBy": "joe",
      "modifiedOn": "2016-03-08T22:09:20.065+0000",
      "modifiedBy": "joe",
      "name": "l2b1",
      "label": "lot2 block 1",
      "parentPlace": 15,
      "description": "Lot 2 block 1 New City",
      "hasChildren": false,
      "address": {
        "gpsPolygon": {
          "vertices": [
            {
              "longitude": -121.7845,
              "latitude": 37.8453
            },
            {
              "longitude": -120.9853,
              "latitude": 37.1248
            },
            {
              "longitude": -121.7758,
              "latitude": 37.6983
            }
          ]
        }
      },
      "links": [
        {
          "rel": "canonical",
          "href": "/mobile/platform/location/places/17"
        },
        {
          "rel": "self",
          "href": "/mobile/platform/location/places/17"
        }
      ]
    }
  ],
  "totalResults": 2,
  "offset": 0,
  "limit": 100,
  "count": 2,
  "hasMore": false
}
Querying for Assets
Query for assets with specific parameters using the following REST endpoints:
  • GET {baseUri}/mobile/platform/location/assets?name={name} to query by the asset name.

  • POST {baseUri}/mobile/platform/location/assets/query to query using parameters in a JSON payload as described below.

To define your query, include a JSON payload with the following options:
Parameter Description
name Filters results by a partial match of this string with the name defined for the asset in the UI. Not case sensitive.
description Filters results by a partial match of this string with the description defined for the asset in the UI. Not case sensitive.
search Filters results by a partial match of this string with the name, label or description defined for the asset in the UI. Not case sensitive.
attributes Filters results by a match of the name-value pairs in the Attributes object, using the attributes defined for the asset in the UI.
label Filters results by a partial match of this string with the label specified for the asset in the UI.
listOfAssets An array of asset IDs to search for.
associatedDeviceId A device ID to search for. Returns the asset associated with this device ID. When you use this query parameter, don't combine it with other parameters.
nearestTo Specify a gpsPoint (latitude, longitude) to return the closest asset. Can’t be combined with other parameters.
inGeoFence Specify a gpsCircle (latitude, longitude, radius) to return all assets within that geofence.
orderBy An enumeration of the field(s) to order results by. Can include any top-level attribute. Append the direction to order results by:
  • :asc for ascending

  • :desc for descending

For example, name:asc.
offset By default, 0 to start results at the first item. Specify an offset number to start results in a different place.
limit By default, 40 items are returned. You can specify a different maximum number of results, up to 100. Generally meant to be used with offset for pagination.
format By default, the response is in long format and results include the asset id, name, description, attributes, label, creation and modification data, as well as the associated place, and the IDs of associated devices. Specify short to return only the asset id, name, description and label.
The following example shows the request body in JSON format, requesting information about assets with the label “bed” and the custom property “EquipmentManufacturer” set to “Example Company”, ordering results by the created date in ascending order:
{
    "label":"bed",
    "attributes":{
        "EquipmentManufacturer":"Example Company"
    },
    "orderBy":"createdOn:asc",
    "format":"long"
}
If the query is successful, the response will be 200, and the body will include an array of matching assets:
{
    "items":[
        {
            "id":333,
            "createdBy":"jdoe",
            "createdOn":"2015-08-06T18:37:59.424Z",
            "modifiedOn":"2015-08-06T18:37:59.424Z",
            "modifiedBy":"jdoe",
            "name":"hospital bed #233",
            "label":"hospital bed",
            "description":"model 1225 hospital bed",
            "lastKnownLocation":{
                "placeId":244
            },
            "devices":[
                3409
            ],
            "attributes":{
                "EquipmentManufacturer": "Example Company",
                "SJId": "6754843090"
            }
        },
        {
            "id":888,
            "createdBy":"jdoe",
            "createdOn":"2015-10-16T09:24:41.354Z",
            "modifiedOn":"2015-10-16T09:24:41.354Z",
            "modifiedBy":"jdoe",
            "name":"hospital bed #233",
            "label":"hospital bed",
            "description":"model 1225 hospital bed",
            "lastKnownLocation":{
                "placeId":360
            },
            "devices":[
                658
            ],
             "attributes":{
                "EquipmentManufacturer": "Example Company",
                "SJId": "6754843090"
            }
        }
    ],
    "totalResults":2,
    "offset":0,
    "limit":100,
    "count":2,
    "hasMore":false
}
Using the SDK to Query for Location Objects: iOS
The OMCLocationQuery class in the iOS SDK allows you to construct queries for location devices, places and assets.

To access the Location API through the iOS SDK, use the OMCMobileBackendManager class as described in Calling Platform APIs Using the SDK for iOS.

Below is an example of using the iOS SDK to query for a place by name.
OMCLocation* location = [[OMCMobileBackendManager sharedManager].defaultMobileBackend location];
 
NSString* searchString = @"store";
 
// search by name
// sort results by name, in ascending order
// results will be in "short" format
OMCLocationPlaceQuery* query = [location buildPlaceQuery];
query.name = searchString;
query.orderByAttribute = OMCLocationDeviceContainerQueryOrderByAttributeTypeName;
query.format = OMCLocationObjectQueryFormatTypeShort;
 
__block OMCLocationPlaceQueryResult* result;
do {
    result = nil;
    __block NSError* error = nil;
    __block BOOL executing = YES;
    [query executeWithCompletionHandler:^(OMCLocationPlaceQueryResult* result_, NSError* error_) {
        result = result_;
        error = error_;
        executing = NO;
    }];
 
    while (executing) {
        [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeInterval:0.5 sinceDate:[NSDate date]]];
    }
 
    if (error) {
        // handle error...
    } else {
        for (OMCLocationPlace* place in result.items) {
            // process each place...
            NSLog(@"place name: %@", place.name);
        }
    }
    query = result.nextQuery;
} while ((result != nil) && result.hasMore);
 
For more information on place queries, see Querying for Places.
Using the SDK to Query for Location Objects: Android
The LocationQuery class in the Android SDK allows you to construct queries for location devices, places and assets.

To access the Location API through the Android SDK, use the MobileBackendManager class as described in Calling Platform APIs Using the SDK for Android.

Below is an example of using the Android SDK to query for a place by name:
Location location = MobileBackendManager.getManager().getDefaultMobileBackend(mActivity).getServiceProxy(Location.class);
Object lock = new Object();
 
String searchString = "store";
final AtomicReferenceString searchString = "store";
final AtomicReference<LocationObjectQueryResult> mResult = new AtomicReference<LocationObjectQueryResult>();
final AtomicReference<ServiceProxyException> mError = new AtomicReference<ServiceProxyException>();

// search by name
// sort results by name, in ascending order
// results will be in "short" format
LocationPlaceQuery query = location.buildPlaceQuery();
query.setName(searchString);
query.setOrderByAttributeType(LocationDeviceContainerQuery.LocationDeviceContainerQueryOrderByAttributeType
    .LocationDeviceContainerQueryOrderByAttributeTypeName);
query.setFormat(LocationObjectQuery.LocationObjectQueryFormatType.LocationObjectQueryFormatTypeShort);

do{
    query.execute(new LocationObjectsQueryCallback(){
        @Override
        void onComplete(LocationObjectQueryResult result, ServiceProxyException exception){
                mError.set(exception);
                mResult.set(result);
 
                synchronized(lock){
                    lock.notifyAll();
                }
        }
    });
 
    synchronized(lock) {
        lock.wait();
    }
 
    if(mError.get() != null){
        //handle error
    }  
    else{
        for(LocationObject object : mResult.get().getItems()){
            LocationPlace place = (LocationPlace) object;
            // process each place...
        }
    }
 
    query = mResult().get().getNextQuery();
 
} while(mResult.get() != null && mResult.get().hasMore());
For more information on place queries, see Querying for Places.

Retrieving Location Objects and Properties

Use the Location API to retrieve location devices, places and assets and their associated properties.

The following REST endpoints allow you to retrieve location objects:
  • Location devices: GET {baseUri}/mobile/platform/location/devices

  • Assets: GET {baseUri}/mobile/platform/location/assets

  • Places: GET {baseUri}/mobile/platform/location/places

You can retrieve an object by ID or by name:
  • To retrieve an object by ID, include the ID in the path, for example: GET {baseUri}/mobile/platform/location/devices/12345.

  • To retrieve an object by name, pass the name of an existing object to the endpoint in the name query parameter, for example GET {baseUri}/mobile/platform/location/devices?name=RC_WH_01_F01_B001.

The SDKs make it easy to retrieve location objects and their attributes to begin monitoring or implement other location-aware functionality. The sections that follow include examples and sample code.
Using the SDK to Retrieve a Location Object: iOS
The examples below show how to use the iOS SDK to retrieve a place and its properties by ID.

To access the Location API through the iOS SDK, use the OMCMobileBackendManager class as described in Calling Platform APIs Using the SDK for iOS.

The example below uses the place ID to retrieve the properties for the place:
OMCLocation* location = [[OMCMobileBackendManager sharedManager].defaultMobileBackend location];
 
// query for all places
// sort results by name, in ascending order
// results will be in "short" format
OMCLocationPlaceQuery* query = [location buildPlaceQuery];
query.orderByAttribute = OMCLocationDeviceContainerQueryOrderByAttributeTypeName;
query.format = OMCLocationObjectQueryFormatTypeShort;
 
__block OMCLocationPlaceQueryResult* result = nil;
__block NSError* error = nil;
__block BOOL executing = YES;
[query executeWithCompletionHandler:^(OMCLocationPlaceQueryResult* result_, NSError* error_) {
    result = result_;
    error = error_;
    executing = NO;
}];
 
while (executing) {
    [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeInterval:0.5 sinceDate:[NSDate date]]];
}
 
// take the first item from the results
// it will be in "short" format...
OMCLocationPlace* shortPlace = result.items.firstObject;
 
// ...now, fetch the "entire" place directly
__block OMCLocationPlace* place = nil;
error = nil;
executing = YES;
[location placeWithID: shortPlace.id_ completionHandler:^(OMCLocationPlace* place_, NSError* error_) {
    place = place_;
    error = error_;
    executing = NO;
}];
 
while (executing) {
    [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeInterval:0.5 sinceDate:[NSDate date]]];
}
 
// process place...
NSLog(@"place name: %@", place.name);
If you’ve already retrieved an object, you can use an SDK refresh method to get the latest properties. The code below uses refresh to retrieve the latest properties for a place:
...
// take the first item from the results
// it will be in "short" format...
OMCLocationPlace* place = result.items.firstObject;
 
// ...now, refresh the place
error = nil;
executing = YES;
[place refreshWithCompletionHandler:^(NSError* error_) {
    error = error_;
    executing = NO;
}];
 
while (executing) {
    [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeInterval:0.5 sinceDate:[NSDate date]]];
}
 
// process place...
NSLog(@"place name: %@", place.name);
You can also use the iOS SDK to retrieve specific properties, as shown in the examples that follow.
Using the SDK to Retrieve iBeacon Identifiers: iOS
The first step to monitoring a place that uses beacons is to retrieve the beacon identifiers, as shown in the iOS SDK example below.
CLLocationManager *locationManager = [[CLLocationManager alloc] init]; // iOS CoreLocation object
 
OMCLocation* location = [[OMCMobileBackendManager sharedManager].defaultMobileBackend location];
         
OMCLocationPlaceQuery *queryPlace = [location buildPlaceQuery];
         
queryPlace.name = @"Chris's Emporium";
queryPlace.limit = @1;
// Order-bys are required as name is search by wildcard, not exact match
queryPlace.orderByAttribute = OMCLocationDeviceContainerQueryOrderByAttributeTypeName;
queryPlace.orderByOrder = OMCLocationObjectQueryOrderByOrderTypeAscending;
         
[queryPlace executeWithCompletionHandler:^(OMCLocationObjectQueryResult<OMCLocationPlaceQuery *,OMCLocationPlace *>* queryResult, NSError * _Nullable queryError) {
    OMCLocationPlace *place = queryResult.items.firstObject;

    [place devicesWithCompletionHandler:^(NSArray<OMCLocationDevice *> *locationDevices, NSError * error) {
        // Following code assumes 1 device for place
         OMCLocationDevice *device = [locationDevices firstObject];
         OMCLocationIBeacon *beacon = (OMCLocationIBeacon*)device.beacon;
         NSUUID *beaconUuid = beacon.uuid;
         CLBeaconMajorValue beaconMajor = (CLBeaconMajorValue)beacon.major.integerValue;
         CLBeaconMinorValue beaconMinor = (CLBeaconMinorValue)beacon.minor.integerValue;
         
         CLBeaconRegion *beaconRegion = [[CLBeaconRegion alloc]initWithProximityUUID:beaconUuid major:beaconMajor minor:beaconMinor identifier:@"MyBeaconRegion"];
         beaconRegion.notifyOnEntry = YES;
         beaconRegion.notifyOnExit = YES;
 
         beaconRegion.delegate = // Assign instance of CLLocationManagerDelegate to handle beacon events
  
         [locationManager startMonitoringForRegion:beaconRegion]; // Invokes CLLocationManagerDelegate didEnterRegion/didExitRegion
         [locationManager startRangingBeaconsInRegion:beaconRegion]; // Invokes CLLocationManagerDelegate inRegion
    }];
}];
Using the SDK to Define a Geofence: iOS
You can use a geofence to define a monitoring area as a place, as shown in the iOS SDK example below.
CLLocationManager *locationManager = [[CLLocationManager alloc] init]; // iOS CoreLocation object
 
OMCLocation* location = [[OMCMobileBackendManager sharedManager].defaultMobileBackend location];
         
OMCLocationPlaceQuery *queryPlace = [location buildPlaceQuery];
         
queryPlace.name = @"Chris's Emporium";
queryPlace.limit = @1;
// Order-bys are required as name is search by wildcard, not exact match
queryPlace.orderByAttribute = OMCLocationDeviceContainerQueryOrderByAttributeTypeName;
queryPlace.orderByOrder = OMCLocationObjectQueryOrderByOrderTypeAscending;
         
[queryPlace executeWithCompletionHandler:^(OMCLocationObjectQueryResult<OMCLocationPlaceQuery *,OMCLocationPlace *>* queryResult, NSError * queryError) {
         OMCLocationPlace *place = queryResult.items.firstObject;
                       
         OMCLocationGeoCircle *geocircle = (OMCLocationGeoCircle *)[place address];         
         OMCLocationGeoPoint *geopoint = [geocircle center];
             
         CLLocationDegrees latitude = [[geopoint latitude]doubleValue];
         CLLocationDegrees longitude = [[geopoint longitude]doubleValue];
         CLLocationDistance radius = [[geocircle radius]doubleValue];
         CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(latitude, longitude);
 
         CLCircularRegion *circularRegion = [[CLCircularRegion alloc]initWithCenter:coordinate radius:radius identifier:@"MyGeofenceRegion"];           
         circularRegion.notifyOnEntry = YES;
         circularRegion.notifyOnExit = YES;
 
         circularRegion.delegate = // Assign instance of CLLocationManagerDelegate to handle events
  
         [locationManager startMonitoringForRegion:circularRegion]; // Invokes CLLocationManagerDelegate didEnterRegion/didExitRegion
    }];
}];
Using the SDK to Retrieve Custom Attributes: iOS
Many location objects use custom attributes. The iOS SDK makes it easy to access these properties, as shown in the examples below.

Retrieving a Custom Attribute for a Place

The iOS SDK example below retrieves a custom attribute for a place:
CLLocationManager *locationManager = [[CLLocationManager alloc] init]; // iOS CoreLocation object
 
OMCLocation* location = [[OMCMobileBackendManager sharedManager].defaultMobileBackend location];
         
OMCLocationPlaceQuery *queryPlace = [location buildPlaceQuery];
queryPlace.name = @"Chris's Emporium";
queryPlace.limit = @1;
// Order-bys are required as name is search by wildcard, not exact match
queryPlace.orderByAttribute = OMCLocationDeviceContainerQueryOrderByAttributeTypeName;
queryPlace.orderByOrder = OMCLocationObjectQueryOrderByOrderTypeAscending;
         
[queryPlace executeWithCompletionHandler:^(OMCLocationObjectQueryResult<OMCLocationPlaceQuery *,OMCLocationPlace *>* queryResult, NSError * queryError) {
         OMCLocationPlace *place = queryResult.items.firstObject;
           
         NSString *myCustomProperty = [place attributeForKey:@"MyCustomProperty"];
         NSLog(@"My Custom Property = %@", myCustomProperty);
}];

Retrieving a Custom Attribute for a Location Device

The iOS SDK example below is very similar to the one above, but uses OMCLocationDevice to retrieve a custom attribute for a beacon:
OMCLocation* location = [[OMCMobileBackendManager sharedManager].defaultMobileBackend location];
 
// Query iBeacon
OMCLocationDeviceQuery *queryDevice = [location buildDeviceQuery];
NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:@"0AC59CA4-DFA6-442C-8C65-22247851344C"];
NSNumber *major = @4;
NSNumber *minor = @200;
queryDevice.beacon = [OMCLocationIBeacon iBeaconWithUUID:uuid major:major minor:minor];
             
[queryDevice executeWithCompletionHandler:^(OMCLocationObjectQueryResult<OMCLocationDeviceQuery *,OMCLocationDevice *>* queryResult, NSError * queryError) {
         OMCLocationDevice *device = queryResult.items.firstObject;

         // Retrieve device/beacon custom property
         NSString *customProperty = (NSString *) [device attributeForKey:@"MyCustomProperty"];
}];
Using the SDK to Retrieve a Location Object: Android

To access the Location API through the Android SDK, use the MobileBackendManager class as described in Calling Platform APIs Using the SDK for Android.

The example below uses the place ID to retrieve the properties for the place:
Location location = MobileBackendManager.getManager().getDefaultMobileBackend(mActivity).getServiceProxy(Location.class);
Object lock = new Object();
 
final AtomicReference<LocationObjectQueryResult> mResult = new AtomicReference<LocationObjectQueryResult>();
final AtomicReference<LocationPlace> mError = new AtomicReference<LocationPlace>();

// query for all places
// sort results by name, in ascending order
// results will be in "short" format
LocationPlaceQuery query = location.buildPlaceQuery();
query.setName(searchString);
query.setOrderByAttributeType(LocationDeviceContainerQuery.LocationDeviceContainerQueryOrderByAttributeType
    .LocationDeviceContainerQueryOrderByAttributeTypeName);
query.setFormat(LocationObjectQuery.LocationObjectQueryFormatType.LocationObjectQueryFormatTypeShort);
 
query.execute(new LocationObjectsQueryCallback(){
    @Override
    void onComplete(LocationObjectQueryResult result, ServiceProxyException exception){
            mResult.set(result);
 
            synchronized(lock){
                lock.notifyAll();
            }
    }
});
 
synchronized(lock){
    lock.wait();
}
 
// take the first item from the results
// it will be in "short" format...
LocationPlace place = (LocationPlace) mResult.get().getItems().get(0);
 
// ...now, fetch the "entire" place directly
location.fetchPlace(place.getID(), new LocationObjectQueryCallback(){
    @Override
    void onComplete(LocationObject object, ServiceProxyException exception){
        LocationPlace detailedPlace = (LocationPlace) object;
        mPlace.set(detailedPlace);
 
        synchronized(lock){
            lock.notifyAll();
        }
    }
});
 
synchronized(lock){
    lock.wait();
}
// process place...
Log.i(TAG, "place name is " + mPlace.get().getName());
If you’ve already retrieved an object, you can use an SDK refresh method to get the latest properties. The code below uses refresh to retrieve the latest properties for a place:
...
// take the first item from the results
// it will be in "short" format...
LocationPlace place = (LocationPlace) mResult.get().getItems().get(0);

// ...now, refresh the place
place.refresh(new LocationObjectFetchCallback(){
    @Override
    void onComplete(LocationObject object, ServiceProxyException exception){
        if(exception != null)
            //handle error
 
        synchronized(lock) {
            lock.notifyAll();
        }
    }
});
 
synchronized(lock){
    lock.wait();
}
// process place...
Log.i(TAG, "place name is " + place.getName());