How geometry querying works
Contents
# 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]
}
Point
s can only have one set of coordinates, as they represent a single point on a map.
# MultiPoint
MultiPoint
objects are a collection of Point
s, or a collection of coordinates.
{
"type": "MultiPoint",
"coordinates": [
[-0.140634, 51.501476],
[-0.146041, 51.501122]
]
}
MultiPoint
s 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 Point
s 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 Point
s.
If a LineString
has more than 3 Point
s, and the same start and end Point
s, it is “closed”. This means all the Point
s are connected. While still a LineString
, this can also be referred to as a LinearRing
.
# MultiLineString
A MultiLineString
is a collection of LineString
s. 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 LineString
s and LinearRing
s. There is also a small overflow here where the LineString
s intersect in certain places. This is allowed, but not required.
# Polygon
A Polygon
is a collection of LinearRing
s, 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 - LinearRing
s 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 LinearRing
s 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 Polygon
s. Like with MultiPoint
s, there is no visual indication that these Polygon
s 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 Feature
s. A FeatureCollection
can have one or more Feature
s.
{
"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"
}
}
]
}
FeatureCollection
s 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 GeometryCollection
s containing MultiPolygon
s 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 GeometryCollection
s 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 FeatureCollection
s 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 Feature
s 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 GeometryCollection
s 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 Point
s, 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 Feature
s 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. MultiPolygon
s 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.