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