Skip to main content

Geospatial Data and Queries

This section explains how to create, use and query geospatial data stored within OpenDataDSL

Introduction​

In OpenDataDSL, you can store geospatial data as the following types of geometrical objects:

  • Point - a single coordinate
  • LineString - an array of 2 or more points
  • MultiPoint - an array of points
  • MultiLineString - an array of LineStrings
  • Polygon - an array of linear rings where the first and last point must be the same
  • MultiPolygon - an array of polygons
  • GeometryCollection - an array of any other geometrical objects

You can add a property to an object which can be of any of the types described above.

Creating Geometries​

There are constructor functions that you can use to construct any of the available geometries as described in this section:

Point​

A point is constructed with a single coordinate in the format:

[longitude, latitude]

So, you can construct a point like so:

var = Point([long, lat])

// Example
location = Point([51.5386, -0.4956])

LineString​

A LineString is constructed as empty and then add coordinates to it or using an array of coordinates as follows:

// Use the empty constructor and add coordinates
road1 = LineString()
road1.add(-73.96943, 40.78519)
road1.add(Point([52.35672, 4.91120]))

// Add the coordinates in the constructor
road2 = LineString([[-73.96943, 40.78519],[-73.96943, 41.78519]])

MultiPoint​

A MultiPoint is the same as a LineString as shown below:

// Use the empty constructor and add coordinates
road1 = MultiPoint()
road1.add(-73.96943, 40.78519)
road1.add(Point([52.35672, 4.91120]))

// Add the coordinates in the constructor
road2 = MultiPoint([[-73.96943, 40.78519],[-73.96943, 41.78519]])

MultiLineString​

A MultiLineString can be constructed as empty and then add LineString or MultiPoint objects to it or can be constructed with the coordinates passed in.

// Use an empty constructor and add the coordinates
road1 = MultiPoint([[-73.96943, 40.78519],[-73.96943, 41.78519]])
road2 = MultiPoint([[-73.96943, 40.78519],[-73.96943, 41.78519]])
mls = MultiLineString()
mls.add(road1)
mls.add(road2)

// Add the coordinates in the constructor
mls = MultiLineString([LineString([[0,0],[1,1]]),LineString([[2,2],[3,3]])])

Polygon​

A polygon can be constructed in 3 ways:

  • An empty polygon
  • A single ring polygon
  • A multi-ring polygon
mp1 = MultiPoint([[ 50, -1 ], [52, -1], [52, 1], [50, 1], [ 50, -1 ]])
mp2 = MultiPoint([[ 50, -1 ], [52, -1], [52, 1], [50, 1], [ 50, -1 ]])

// Create an empty polygon and add rings to it
poly1 = Polygon()
poly1.add(MultiPoint([[ 50, -1 ], [52, -1], [52, 1], [50, 1], [ 50, -1 ]]))
poly1.add(mp2)

// Create a polygon with a single ring
poly2 = Polygon([[ 50, -1 ], [52, -1], [52, 1], [50, 1], [ 50, -1 ]])

// Create a mulit-ring polygon
poly3 = Polygon([mp1, mp2])

MultiPolygon​

A MultiPolygon can be constructed as empty or passing in a list of polygons, e.g.

// Create some polygons
poly1 = Polygon()
poly1.add(MultiPoint([[ 50, -1 ], [52, -1], [52, 1], [50, 1], [ 50, -1 ]]))
poly2 = Polygon([[ 50, -1 ], [52, -1], [52, 1], [50, 1], [ 50, -1 ]])

// Construct an empty multi polygon and add a polygon
mp = MultiPolygon()
mp.add(poly1)

// Create a MultiPolygon using our 2 polygons
mp2 = MultiPolygon([poly1, poly2])

GeometryCollection​

A MultiPolygon can be constructed as empty or passing in a list of geometries, e.g.

// Create some geometries
road2 = MultiPoint([[-73.96943, 40.78519],[-73.96943, 41.78519]])
location = Point([51.5386, -0.4956])

// Create an empty GeometryCollection and add our geometries
gc = GeometryCollection()
gc.add(road2)
gc.add(location)

// Construct a GeometryCollection using our geometries
coll = GeometryCollection([road1, polygon, mp])

Adding Geometry to Objects​

You can add any of the geometries to an object as a property which can then be used to make geospatial queries, Here is an example of creating an object with a geolocation and saving it:

BritishMuseum = object as TestGeometry
name = "British Museum"
location = Point([51.51958, -0.12695])
end
save ${object:BritishMuseum}

Using Geospatial Queries to find objects​

You can use the find command to search for items that are within or intersect a polygon or a spherical radius of a point.

To check for items that are within a radius of a point, you use the within operator with a sphere object. The sphere object is constructed using a point and a radius in radians as follows:

// Syntax
s = Sphere([longitude, latitude], radius)

// Creating a 20 mile radius around the British Museum
// 3963.2 is the radius of the earth in miles
bm20 = Sphere([51.51958, -0.12695], 20/3963.2)

Examples​

// Find a list of items that are within a 20 mile radius of a point
items = find ${object:"TestGeometry"} where location within Sphere([ 51.72961, 0.47612 ], 20 / 3963.2)

// Find items that are within a defined polygon
items = find ${object:"TestGeometry"} where location within Polygon([[ 50, -1 ], [52, -1], [52, 1], [50, 1], [ 50, -1 ]])

// Pre-define a polygon, then find items that are within that polygon
london = Polygon([[51.5386, -0.4956],[51.6445, -0.0753],[51.5205, 0.1753],[51.3479, -0.1163],[51.5386, -0.4956]])
items = find ${object:"TestGeometry"} where location within london

// Find items that intersect with a polygon
items = find ${object:"TestGeometry"} where location intersects london