Geolocation field type and distance comparison

GraphQL queries for filtering by geolocation and distance from a fixed point

Skedulo supports GraphQL queries on the GeoLocation field type so that you can filter records based on the distance between a geolocation field and a fixed point. You can:

  • Query records based on their distance to a fixed location.
  • Filter the results based on a distance greater than or less than a fixed number.

The results are then returned in an order based on distance; either increasing (nearest to farthest) or decreasing (farthest to nearest).

This can be useful for populating the region field on a job based on the address. You can also use this feature to include or exclude resources within a specified distance or find the resource that is closest to a job location.

Filter and order geolocations

Regions include latitude and longitude fields, which are stored as a compound POINT field for standard geolocation fields. In Skedulo, Lat and Lng fields have suffix Latitude and Longitude. The compound field always has suffix Location.

You can query these compound POINT fields to filter and order the results of geolocation and distance comparison queries. Compound fields are not supported in any query field list and cannot be queried from or written to.

The Skedulo web application includes the GraphiQL web extension so that you can build and test GraphQL queries. Use either GraphiQL, or your preferred API client to create the geolocation and distance comparison query.

Geolocation and distance comparison query

The GeoLocation query uses an EQL Filter to filter the regions based on their distance from a fixed GeoLocation point. The orderBy filter displays the results in either descending (DESC) or ascending (ASC) order of distance from the specified location. The orderBy mode is ASC by default.

In the following basic GraphQL example, we have created a query that requests the following information:

  • A list of regions, including the UID and Name fields.
  • Regions filtered in descending order based on their distance from the specified location, so the results will show the farthest region first, and the nearest region last.
  • The fixed geolocation from which we want to determine the region’s distance is -27.8, 153.3, which corresponds to Brisbane, Australia.
query queryRegions($filter: EQLQueryFilterRegions) {
  regions(filter: $filter, orderBy: "DISTANCE(GeoLocation, GEOLOCATION(-27.8, 153.3)) DESC"){
    edges {
      node {
        UID
        Name
      }
    }
  }
}

We want to include regions that are within a set distance from the geolocation. The following filter variable uses the DISTANCE expression to specify that we want to display regions that are less than (>) 50000 meters from the geolocation for Brisbane:

{
  "filter": "DISTANCE(GeoLocation, GEOLOCATION(-27.8, 153.3)) < 50000"
}

The following is an example response for the above query, where there are three regions listed within 50000 meters (50 kilometers) of GeoLocation -27.8, 153.3 (Brisbane).

{
  "data": {
    "regions": {
      "edges": [
        {
          "node": {
            "UID": "000314de-f629-4202-8a5b-c61f195f2fb0",
            "Name": "Ipswich"
          }
        },
        {
          "node": {
            "UID": "0003e3a4-7bc5-441f-9e11-d8e4b7fbfad5",
            "Name": "Redcliffe Penninsula"
          }
        },
        {
          "node": {
            "UID": "00038f3e-9e38-45e9-9e7b-9dec514a1199",
            "Name": "Bayside"
          }
        }
      ]
    }
  }
}

Changing the orderBy filter to ASC will return the same results in the reverse order.

You can add more fields to the GraphQL query to return more information about the regions. For example, the following query also returns the Latitude and Longitude, Timezone and lists resources for which the region is their primary region.

query queryRegions($filter: EQLQueryFilterRegions) {
  regions(filter: $filter, orderBy: "DISTANCE(GeoLocation, GEOLOCATION(-27.8, 153.3)) DESC"){
    edges {
      node {
        UID
        Name
        GeoLatitude
        GeoLongitude
        Timezone
        Resources {
        	UID
        	Name
        }
      }
    }
  }
}

This query returns the following response:

{
  "data": {
    "regions": {
      "edges": [
        {
          "node": {
            "UID": "000314de-f629-4202-8a5b-c61f195f2fb0",
            "Name": "Ipswich",
            "Description": "Brisbane West (Ipswich/Rosewood)",
            "GeoLatitude": -27.633331,
            "GeoLongitude": 152.583331,
            "Timezone": "Australia/Brisbane",
            "Resources": [
              {
                "UID": "000520bd-63a1-47a0-9c80-9a343cb35ec6",
                "Name": "David Kimi"
              }
            ]
          }
        },
        {
          "node": {
            "UID": "0003e3a4-7bc5-441f-9e11-d8e4b7fbfad5",
            "Name": "Redcliffe Penninsula",
            "Description": "Redcliffe (Brisbane North)",
            "GeoLatitude": -27.1353,
            "GeoLongitude": 153.558,
            "Timezone": "Australia/Brisbane",
            "Resources": [
              {
                "UID": "0005a7e9-b1aa-44da-937f-310b921b75cc",
                "Name": "John Smith"
              }
            ]
          }
        },
        {
          "node": {
            "UID": "00038f3e-9e38-45e9-9e7b-9dec514a1199",
            "Name": "Bayside",
            "Description": "Brisbane bayside (Victoria Point)",
            "GeoLatitude": -27.356,
            "GeoLongitude": 153.1735,
            "Timezone": "Australia/Brisbane",
            "Resources": [
              {
                "UID": "000521e3-b4ab-417e-8fc2-23647246b085",
                "Name": "Mary Brown"
              }
            ]
          }
        }
      ]
    }
  }
}

You can also change the filter variable to return the regions farther or nearer using a different distance value, or by changing the comparison operator to show regions that are more than the specified distance value from the geolocation.

For example, the following variation to the filter distance comparison filters regions that are more than (>) 20000 meters (20 kilometers) from Brisbane:

{
  "filter": "DISTANCE(GeoLocation, GEOLOCATION(-27.8, 153.3)) > 20000"
}