This is the documentation for previous versions of GeoDesk (1.0 to 1.3). For the most recent version, please visit docs.geodesk.com.Queries and Feature Collections
Geospatial applications typically work with subsets of features in a library, such as buildings in a town, or waterways in a particular region. These subsets are represented as feature collections, which are the result of queries.
Feature collections are lightweight objects that merely described what should be returned; they don’t actually contain any objects and take up minimal space. In other words, query execution is lazy: Features are fetched only once they are needed, in response to iteration or a call to
count().Feature collections can be ordered or unordered. Only the nodes of a way and the members of a relation are ordered; all other query results are returned in arbitrary order.
Start working with collections by creating a root collection, which contains all features in a given Geographic Object Library:
Features(const char* golFileName);
From this collection, you can create others:
Features france("path/to/france.gol");
...
Features shops = france("na[shop]");
Features thingsInParis = france(paris); // Feature or geometry
Features shopsInParis = shops & thingsInParis;
Filtering features
To select a subset of Features, add the constraint in parentheses, or apply a filter method. This always creates a new collection, leaving the original Features object unmodified.
By bounding box
Select the features whose bounding boxes intersect the given Box:

Features france("france.gol");
Box parisBounds = Box::ofWSEN(
2.2, 48.8, 2.5, 48.9);
Features thingsInParis = france(parisBounds);
By type and tags
Apply a query written in GOQL (Geographic Object Query Language) to select features based on their type and tags:

Features restaurants = world(
"na[amenity=restaurant]");
// nodes and areas
Nodes fireHydrants = world(
"n[emergency=fire_hydrant]");
// only nodes
Ways safeForCycling = world(
"w[highway=cycleway,path,living_street],"
"w[highway][maxspeed < 30]");
// linear ways
Using filter methods
Apply a spatial filter or topological filter, or a custom filter:
states.within(usa)
features("w[highway]").membersOf(route66)
parks.filter(MyFilters::containsWaterFountains);
Using set intersection
Select only features that are in both sets:
Features museums = world("na[tourism=museum]");
Features inParis = world.within(paris);
Features parisMuseums = museums(inParis);
Alternatively, you can use the & operator:
Features parisMuseums = museums & inParis;
Obtaining Feature objects
Simply iterate:
for(Feature hotel : hotels)
{
std::cout << hotel["name"] << std::endl;
}
Create a std::vector, or populate an existing one:
std::vector<Feature> list = streets;
streets.addTo(myVector);
Check if the set is empty:
if (pubs.within(dublin))
printf("Great, we can grab a beer in this town!");
if (!street.nodes("[traffic_calming=bump]"))
printf("No speed bumps on this street.");
Obtaining a single Feature
first
Returns the first feature in a collection:
std::optional<Feature> city = france("n[place=city][name=Paris]").first();
Note that only the nodes of ways and members of relations are ordered collections; all others are unordered sets, which means you’ll receive a random feature if there are more than one. If the collection is empty, first() returns nullopt.
one
Returns the one and only feature of the collection. Throws a QueryException if the collection is empty or contains more than one feature.
Feature paris = world("n[place=city][name=Paris]").one();
// will likely throw a QueryException,
// because there's also Paris, Texas
Testing for membership
To check if a feature belongs to a given set, use contains():
Features sushiRestaurants =
world("na[amenity=restaurant][cuisine=sushi]");
if (sushiRestaurants.contains(restaurant))
std::cout << restaurant["name"] << " serves sushi";
Scalar queries
count
The total number of features in the collection:
printf("%d restaurants found.", restaurants.count());
area
The total area (square meters as double) of all areas in this set.
printf("London has %f square meters of parks.",
parks.within(london).area());
length
The total length (meters as double) of all features in this set. For areas, their circumference is used.
printf("The French motorway network is %f km long.",
france("w[highway=motorway]").length() / 1000);
Spatial filters
Features can be filtered by their spatial relationship to other geometric objects (typically a GEOSGeometry or another Feature).
containing
Selects features whose geometry contains A:
- Every point of A is a point of the candidate feature, and the interiors of the two geometries have at least one point in common.
Features containing(Feature);
Features containing(GEOSGeometry);
Features containingXY(Coordinate);
Features containingLonLat(double, double);
For example:
// In which park (if any) is this statue of Claude Monet?
return features("a[leisure=park]")
.containing(statueOfMonet).first();
// The county, state and country for this point -- should return
// San Diego County, California, USA (in no particular order)
return features("a[boundary=administrative][admin_level <= 6]")
.containingLonLat(-117.25, 32.99);
coveredBy
Selects features whose geometry is covered by A:
- No point of the candidate feature’s geometry lies outside of A.
Features coveredBy(Feature);
Features coveredBy(GEOSGeometry);
crossing
Selects features whose geometry crosses A:
- The geometries of A and the candidate feature have some (but not all) interior points in common
- The dimension of the intersection must be less than the maximum dimension of the candidate and A.
Features crossing(Feature);
Features crossing(GEOSGeometry);
For example:
// All railway bridges across the Mississippi River
Features railwayBridges = features("w[railway][bridge]");
return railwayBridges.crossing(mississippi);
intersecting
Selects features whose geometry intersects A:
- The geometries of A and the candidate feature have at least one point in common.
Features intersecting(Feature);
Features intersecting(GEOSGeometry);
maxMetersFrom
Selects features whose distance to A is less or equal to m meters (measured between the closest points of the candidate feature and A).
Features maxMetersFrom(double, Feature);
Features maxMetersFrom(double, GEOSGeometry);
Features maxMetersFrom(double, Coordinate);
Features maxMetersFromLonLat(double, double, double);
For example:
// All bus stops within 500 meters of the given restaurant
Features nearbyBusStops = features("n[highway=bus_stop]")
.maxMetersFrom(500, restaurant);
// All features within 3 km of the given point
return features.maxMetersFromLonLat(3000, 76.41, 40.12);
within
Selects features that lie entirely within A:
- Every point of the candidate feature is a point in A, and their interiors have at least one point in common.
Features within(Feature);
Features within(GEOSGeometry);
Topological filters
These methods return a subset of those features that have a specific topological relationship with another Feature.
connectedTo
Selects all features that have at least one node (vertex) in common with the given Feature or Geometry.
Features connectedTo(Feature);
Features connectedTo(GEOSGeometry);
nodesOf
The nodes of the given way. Returns an empty set if the feature is a Node or Relation.
Nodes nodesOf(Feature);
membersOf
Features that are members of the given relation, or nodes of the given way. Returns an empty set if the feature is a Node.
Features membersOf(Feature);
parentsOf
Relations that have the given feature as a member, as well as ways to which the given node belongs.
Features parentsOf(Feature);
Custom filters
Use filter() with your own filter predicate:
// Find all parks whose area is at least 1 km²
// (one million square meters)
Features parks = world("a[leisure=park]");
Features largeParks = parks.filter([](Feature park)
{ return park.area() > 1'000'000; });
Important: The predicate must be threadsafe, as the query may be executed in parallel.