Child pages
  • Geospatial
Skip to end of metadata
Go to start of metadata

Geospatial Field Type

Geospatial data identifies geographic locations on earth. Apstrata stores geospatial data as pairs of longitude and latitude coordinates, represented in decimal degrees. It uses a spherical model of the earth and does not consider altitude or roads. Apstrata queries can calculate the distance (in kilometers) between geospatial points as the arc formed on the surface of a bounding sphere representation of the earth.

Apstrata enables you to store geospatial data into your documents and to easily build queries mixing geospatial data with other types of data. This is very handy when it comes to implement features such as locating facilities according to a given position and some additional criteria (e.g., find the chinese restaurants that have a menu around 15$ and that are located within 1000 meters from my current location).

Another example, the Eiffel Tower in Paris, France, is located at the following coordinates: 48.8580°, 2.2951°.

Apstrata queries allow applications to obtain all points that are within a certain distance of a reference point. To do this, Apstrata assumes the distance is the radius of a circle centered on the reference point. It returns all points that lie inside the smallest bounding box of this circle. This means that there is always the possibility of obtaining points that are outside the area covered by the circle, but still within the area covered by the bounding box. Since most queries are expected to operate over a few hundred meters, this error margin is acceptable and allows Apstrata queries to operate in a performant fashion.

 

The below is a third example of the geospatial feature:

  • Consider the circle of radius R.
  • Its area is equal to pi * R * R.
  • Each edge of its bounding square will have a length of 2 * R.
  • The bounding square will have an area of 4 * R * R.
  • Area of the circle / Area of the square = pi / 4 = 0.78539816339.

This means that a sample query for all restaurants located within a hundred meters of my current position may return some of the restaurants that are 125 meters away from me, instead of just the ones that are 100 meters away.

Working with Geospatial

Working with the geospatial feature of Apstrata is actually pretty straightforward. All that is needed is to save documents containing geospatial data types, then build queries to extract data from these documents.

Saving Geospatial Data in Documents

Saving documents that contain geospatial data is actually not different from saving documents containing any other type of data. You only need to apply the expected format for the concerned fields and specify that these fields are of type geospatial, as explained in more details in the below section.

Field of type 'geospatial':

Saving a field of type "geospatial" requires providing a pair of longitude and latitude coordinates represented in decimal degrees.

[fieldname]=[LATITUDE],[LONGITUDE]

Where LATITUDE  and LONGITUDE should match numbers that have at most 3 digits before a decimal and 4 digits after, and optionally leading + or -.

Example:
EiffelTowerCoordinates = 48.8580,2.2951

StatueOfLibertyCoordinates =40.6892,-74.0447

Make sure that you specify the type of the field containing the geospatial data by passing "[fieldName].apsdb.fieldType=geospatial" to your call to "SaveDocument".

Querying Documents that Contain Geospatial Data

Querying documents that contain geospatial data is also similar to querying documents containing other types of data. A difference however relies in the operator that can be used in the query: geospatial fields do not support the nominal comparison operators (i.e., : =, !=, >, >=, <, <=, in, in-all or like). Instead, when dealing with geospatial fields, the "within" operator should be used. It allows queries to search for geospatial locations that lie within a specified distance from a reference point. Consequently, this operator requires two parameters:

  • A geospatial reference point (represented as a pair of latitude/longitude decimal degrees)
  • A distance value (in kilometers)

The below example illustrates a query condition that can be used to find all locations that are 200m away from the Eiffel Tower: location<geospatial> within (48.8580, 2.2951, 0.200).

Apstrata Queries can also return Derived Fields. These are fields that can be returned by a query, but do not exist in the document. Specifically, the "distance" between geospatial points is a derived field recognized by Apstrata.

When returning fields, the distance formula can be expressed in several ways:

  • It can be passed a pair of geospatial points, each represented as a latitude and longitude pair. (Example: distance ('1.0', '2.0', '3.0', '4.0') returns the distance between the geopatial coordinates (1.0, 2.0) and (3.0, 4.0)).
  • It can be passed a pair of geospatial fields. (Example: distance (gpsLocation1, gpsLocation2)).
  • It can be passed a geospatial field and a geospatial point. (Example: distance(gpsLocation, '1.0', '2.0')).

In all cases, the value returned will be the distance in kilometers between the two geospatial locations.
Please note that derived fields are returned as a separate element in the response, as seen in the example below.

 

Request parameters:
 
apsdb.query=country<string>="France" and location<geospatial> within (48.8580, 2.2951, 200)
apsdb.includeFieldType=true
apsdb.queryFields=country,apsdb.documentKey,distance(location,'48.8580', '2.2951')
apsdb.sort=distance(location,48.8580,2.2951)<ASC>
JSON Response:
 
{"response": {
  "metadata": {
    "requestId": "21961fdf-8cd6-4c39-97f0-26a3095c0eb4",
    "status": "success",
    "statusCode": "200"
  },
  "result": {
    "count": "2",
    "documents": [
      {
        "key": "8D954C3442033A59F8E934B85794A221",
        "versionNumber": "1.0",
        "country": "France",
        "apsdb.documentKey": "testDocu",
        "location": "47.0,4.0",
        "_type": {
          "country": "string",
          "apsdb.documentKey": "string",
          "location": "geospatial"
        },
        "_derivedFields": {
          "distance(location,'48.8580','2.2951')": "242.5116"
        }
      },
      {
        "key": "716A3A6467A967835CED2C4CB1B4C9CD",
        "versionNumber": "1.0",
        "country": "France",
        "apsdb.documentKey": "testDocuFar",
        "location": "68.0,14.0",
        "_type": {
          "country": "string",
          "apsdb.documentKey": "string",
          "location": "geospatial"
        },
        "_derivedFields": {
          "distance(location,'48.8580','2.2951')": "2225.9267"
        }
      }
    ]
  }
}}

 

 

  • No labels