How geometry querying works

Contents

  1. The GeoJSON Specification
  2. GeoJSON Objects
  3. Our Entities
  4. Filtering

# The GeoJSON Specification

At the core of the products we produce at Intelligence Fusion is geographically located incident data providing a birdseye view of the global threat landscape. Our team of in house analysts scour sources daily to report and plot incidents with locational precision making our data best in class. Our incident data is also associated to other entities such as countries and organisational static assets offering our customers a deeper insight and understanding as to how they can assess the data available to protect their operations, assets and people. All of our geographic logic internally is built around the GeoJSON Specification.

Abstract

GeoJSON is a geospatial data interchange format based on JavaScript Object Notation (JSON). It defines several types of JSON objects and the manner in which they are combined to represent data about geographic features, their properties, and their spatial extents. GeoJSON uses a geographic coordinate reference system, World Geodetic System 1984, and units of decimal degrees.

At its core, GeoJSON objects are built using longitude and latitude coordinates, in that order, and are formatted in a way that allows them to dictate how they should be drawn on the map.

# GeoJSON objects

Low level objects:

High level objects:

Low level objects

# Point

The lowest level of GeoJSON object is a Point. A Point is made up of a longitude and latitude.

{
  "type": "Point",
  "coordinates": [-0.140634, 51.501476]
}

Points can only have one set of coordinates, as they represent a single point on a map.

# MultiPoint

MultiPoint objects are a collection of Points, or a collection of coordinates.

{
  "type": "MultiPoint",
  "coordinates": [
    [-0.140634, 51.501476],
    [-0.146041, 51.501122]
  ]
}

MultiPoints display one point on the map for every Point it comprises of. It shows that these coordinates are grouped in some way but with no visual indication as to how. In this example, we are showing that Buckingham Palace and Buckingham Palace Gardens are related to each other, but still individual locations on the map in their own right.

# LineString

A LineString is a collection of Points where we indicate that a line needs to be drawn from one Point to the next, in the order that it is represented. For this reason, the coordinate formatting is the same as a MultiPoint. This is useful when drawing an route on a map, such as a road.

{
  "type": "LineString",
  "coordinates": [
    [-0.140634, 51.501476],
    [-0.146041, 51.501122]
  ]
}

In order for a LineString to be valid, there must be at least 2 sets of Points.

If a LineString has more than 3 Points, and the same start and end Points, it is “closed”. This means all the Points are connected. While still a LineString, this can also be referred to as a LinearRing.

# MultiLineString

A MultiLineString is a collection of LineStrings. Each LineString is drawn separately but there is still a semantic connection between the two elements. Such as indicating areas around Buckingham Palace and the Gardens where tourists may stand.

{
  "type": "MultiLineString",
  "coordinates": [
    [
      [-0.040634, 51.401476],
      [-0.240634, 51.601476],
      [-0.240634, 51.601476]
    ],
    [
      [-0.046041, 51.401122],
      [-0.246041, 51.601122],
      [-0.246041, 51.601122]
    ]
  ]
}

A MultiLineString can contain a combination of both normal LineStrings and LinearRings. There is also a small overflow here where the LineStrings intersect in certain places. This is allowed, but not required.

# Polygon

A Polygon is a collection of LinearRings, in order to draw a valid shape on the map. This shape is also filled, indicating that everything between these points is also part of the shape we want to draw. This could be the total surface area of Buckingham Palace.

{
  "type": "Polygon",
  "coordinates": [
    [
      [-0.040634, 51.401476],
      [-0.240634, 51.601476],
      [-0.240634, 51.601476],
      [-0.040634, 51.401476]
    ]
  ]
}

A Polygon can have “holes”. This is indicated by additional - optional - LinearRings being used to identify where the holes in this Polygon should be. The first LinearRing should define the exterior of the Polygon, and any additional LinearRings define holes in the interior.

The GeoJSON spec draws the exterior ring of a Polygon counterclockwise and any interior rings clockwise in order to work out where to “cut” the Polygon. We can use a Polygon with a hole to define the area outside of Buckingham Palace that is protected, excluding the Palace itself.

{
  "type": "Polygon",
  "coordinates": [
    [
      [-0.040634, 51.401476],
      [-0.240634, 51.601476],
      [-0.240634, 51.601476],
      [-0.040634, 51.401476]
    ],
    [
      [-0.090634, 51.451476],
      [-0.190634, 51.551476],
      [-0.190634, 51.551476],
      [-0.090634, 51.451476]
    ]
  ]
}

# MultiPolygon

A MultiPolygon is a collection of Polygons. Like with MultiPoints, there is no visual indication that these Polygons are connected with each other and the relationship is purely semantic (unless their coordinates intersect). This is useful when indicating that two areas are not physically connected however belong to the same geographical region, like when identifying that the islands around the United Kingdom are still part of the United Kingdom. To keep the example simple, we can use Buckingham Palace and its Gardens again

{
  "type": "MultiPolygon",
  "coordinates": [
    [
      [
        [-0.040634, 51.401476],
        [-0.240634, 51.601476],
        [-0.240634, 51.601476],
        [-0.040634, 51.401476]
      ]
    ],
    [
      [
        [-0.046041, 51.401122],
        [-0.246041, 51.601122],
        [-0.246041, 51.601122],
        [-0.046041, 51.401122]
      ]
    ]
  ]
}

High level objects

# Feature

A Feature contains a geometry in the form of one of the low level objects above, and an optional “properties” key to help give meaning to the location being identified. These properties can be anything, as they are classed as a foreign member and do not need to adhere to the original specification.

{
  "type": "Feature",
  "geometry": {
    "type": "Point",
    "coordinates": [-0.140634, 51.501476]
  },
  "properties": {
    "name": "Buckingham Palace"
  }
}

# FeatureCollection

Like the name states, a FeatureCollection is a collection of Features. A FeatureCollection can have one or more Features.

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [-0.140634, 51.501476]
      },
      "properties": {
        "name": "Buckingham Palace"
      }
    },
    {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [-0.146041, 51.501122]
      },
      "properties": {
        "name": "Buckingham Palace Gardens"
      }
    }
  ]
}

FeatureCollections are useful when identifying related collections of geometries that each need to have their own data properties, such as oil pipelines with different nodes belonging to different corporations and different emergency protocols.

# GeometryCollection

A GeometryCollection is a collection of low level geometry objects identified via a “geometries” property. A GeometryCollection can have one or more geometries and each geometry can be a different type, as long as each is valid.

{
  "type": "GeometryCollection",
  "geometries": [
    {
      "type": "Point",
      "coordinates": [-0.140634, 51.501476]
    },
    {
      "type": "Polygon",
      "coordinates": [
        [
          [-0.040634, 51.401476],
          [-0.240634, 51.601476],
          [-0.240634, 51.601476],
          [-0.040634, 51.401476]
        ]
      ]
    }
  ]
}

This is useful when you need to reduce a set of geographical locations down to just the information that is important for rendering on the map or filtering.

# Our Entities

Countries

Country geometries are generally represented as GeometryCollections containing MultiPolygons as they cover large, intricate sections of the map. Each geometry does not typically need to have its own properties as the country data is stored alongside this geometry information.

Incidents

Incident geometries are generally represented as GeometryCollections containing one or more of the lower level geometry types as an incident can occur in a single point on a map, multiple points, or across a large area. Areas of interest are marked internally as “map features” so that each geometry in this collection can have access to its own properties in a similar, but more detailed way than just using a FeatureCollection. These map features can also have custom icons and descriptions. The incident map feature geometries are collated for filtering purposes and referred to internally as an incident map.

Static Assets

Static asset geometries are represented as FeatureCollections because, like with the pipeline example above, every Feature of a static asset may need to contain its own set of unique properties, however we still want to treat the static asset itself as a combination of all of these Features.

The Features inside this FeatureCollection can have as little or as many properties as needed, and each Feature can be a different geometry type.

When creating static assets, you must supply the “geometry” request parameter as a valid FeatureCollection.

When you set the location of a static asset, it’s geometry is distilled down to a coordinate string which is then queried against the GeometryCollections of the countries in order to determine which countries a static asset resides in. This helps improve query speed and makes it easier to handle the geometry information internally.

# Filtering

When filtering entities by geometry, these coordinate strings are also used to prevent any unneccessary data being used inside the request query string. The string is a raw representation of a Feature object with all spaces removed.

For Points, the query string may look like [[-0.140634,51.501476]]. The external set of square brackets identifies that we are looking for a Feature, so a second set can also be included when indicating multiple Features like [[-0.140634,51.501476]][[-0.146041,51.501122]].

The internal set of square brackets is the geometry itself, which for a Point, we only need one set of brackets for. This level of nesting increases as we introduce more complex geometry types. MultiPolygons may look like [[[[[-0.040634,51.401476],[-0.240634,51.601476],[-0.240634,51.601476],[-0.040634,51.401476]]],[[[-0.046041,51.401122],[-0.246041,51.601122],[-0.246041,51.601122],[-0.046041,51.401122]]]]].

It’s easy to see how creating or filtering any kind of geometric entity can soon become very complex. Thankfully for our web platform customers, this is all handled for you in the background, and we supply a set of tools to allow you to draw your desired geometries directly onto the map which are then formatted correctly in the background before sending requests to the relevant API.