Skip to main content

Geographic search

In this tutorial you will learn how to:

  • Use the S2 Geometry library to manipulate geographic data
  • Define search areas
  • Index geographic coordinates to speed up geographic queries

Import libraries

Firstly, import S2 Geometry and some classes from Shapelets Core:

import s2geometry as s2
from shapelets.data import DataType, GeoPoint
from shapelets.indices import ScalarIndexBuilder

Define some locations

Let's create some points given their latitude and longitude coordinates, expressed in degrees.

parador = s2.S2LatLng.FromDegrees(40.078749, -2.126374).ToPoint()
parking_recreo_peral = s2.S2LatLng.FromDegrees(40.079800, -2.131684).ToPoint()

Set up search area

Now we will define our search area. First, we obtain the distance between the two points we defined in the previous step. This distance is expressed as an angle. The center of our search area will be the point Parador and the radius will be the distance between the two points. Since defined regions will be approximated as unions of cells, we can also configure the min/max levels of precision of the cells and the maximum number of cells we want to use.

radius = s2.S1ChordAngle(parador, parking_recreo_peral)
search_area = s2.S2Cap(parador, radius)
coverer = s2.S2RegionCoverer()
coverer.set_min_level(0)
coverer.set_max_level(16)
coverer.set_max_cells(2147483647)
list_cells = coverer.GetCovering(search_area)

Build scalar index

In this step, we will create a scalar index and add some points to it. Once added, points will be automatically indexed and stored.

builder = ScalarIndexBuilder.for_type(DataType.geo_point())
builder.add(0, GeoPoint(40.074867, -2.139567))
builder.add(1, GeoPoint(40.077797, -2.128250))
builder.add(2, GeoPoint(40.080498, -2.128537))
builder.add(3, GeoPoint(40.065109, -2.134577))
builder.add(4, GeoPoint(40.090803, -2.083737))
index = builder.finalize()

Get results

Finally, we can query the index to retrieve all the points covered by our region, defined as a union of cells.

print(index.covered_by(list_cells))