Five-Minute Tutorial
This tutorial assumes that you are already familiar with OpenStreetMap and its data model. If not, read our Introduction to OSM or visit the official OSM website.
Create a Feature Library
Download and install the GOL command-line utility
Download some OSM data (in PBF format). We suggest starting with a subset for a single country (or smaller part). For example, Germany (file size: 3.5 GB) can be downloaded from GeoFabrik or BBBike.
Turn the PBF file into a Geographic Object Library:
gol build germany germany-latest.osm.pbf
On a multi-core workstation with at least 24 GB of RAM, this should take a few minutes; on an 8-GB dual-core laptop, expect 20 minutes or more. The output will look like this:
Building germany.gol from germany-latest.osm.pbf using default settings... Analyzed germany-latest.osm.pbf in 20s Sorted 86,432,126 features in 1m 13s Validated 1023 tiles in 36s Compiled 1023 tiles in 1m 24s Linked 1023 tiles in 8s Build completed in 3m 43s
Use Feature Libraries in Java
Add this Maven dependency to your project:
<dependency>
<groupId>com.geodesk</groupId>
<artifactId>geodesk</artifactId>
<version>0.2.1</version>
</dependency>
Import the GeoDesk packages:
import com.geodesk.feature.*;
import com.geodesk.geom.*;
Open the library:
FeatureLibrary germany = new FeatureLibrary("germany.gol");
Create a query:
Features lighthouses = germany.select("na[man_made=lighthouse][name][height]");
This returns a collection of Feature
objects representing lighthouses that have names and whose height has been recorded (na
indicates that we want features that are mapped as nodes or areas — see Geo-Object Query Language).
Iterate through the features:
for(Feature f: lighthouses)
{
System.out.format("%s is %f meters tall.\n",
f.stringValue("name"), f.doubleValue("height"));
}
Typically we want only a specific subset of the collection. The most common case is a bounding-box query:
Box bbox = Box.ofWSEN(8.42, 53.75, 9.07, 53.98);
// longitude/latitude West, South, East, North
for(Feature f: lighthouses.in(bbox)) ...
Other filters include:
Filter by type:
.nodes()
,.ways()
,.relations()
Spatial predicates:
.containing(...)
,intersecting(...)
,crossing(...)
Filters can be combined:
roads.ways("[bridge]").in(bbox).crossing(rhineRiver)
Work with individual features
Retrieve a feature’s tags:
Tags tags = feature.tags();
Map<String,Object> tagMap = feature.tags().toMap();
Get a specific tag value by key:
feature.stringValue("opening_hours") // returns empty string if tag not present
feature.intValue("maxspeed") // 0 if tag not present or non-numeric
Get its type and ID:
FeatureType type = feature.type(); // NODE, WAY or RELATION
long osmId = feature.id();
Its location:
feature.lon() // degrees longitude
feature.lat() // degrees latitude
feature.x() // Mercator-projected X-coordinate
feature.y() // Mercator-projected Y-coordinate
Its length (meters) or area (square meters):
feature.length() // 0 if not linear
feature.area() // 0 if not an area
Its JTS geometry:
feature.toGeometry() // Point for a Node
// LineString or LinearRing for a non-area Way
// Polygon for a Way that represents an area
// Polygon or MultiPolygon for an area Relation
// GeometryCollection for all other Relations
Ways
Retrieve the nodes that make up a way:
way.nodes() // all nodes
way.nodes("[barrier]") // only barriers
Or simply iterate the way:
for(var node: way) ...
(Iteration only retrieves nodes that have tags or are part of a relation; nodes()
returns all nodes).
Retrieve the ways to which a node belongs:
node.parents().ways()
node.parents("w[highway]")
Relations
Retrieve a relation’s members:
for(Feature member: rel.members())
Or simply iterate:
for(Feature member: rel) ...
Discover a member’s role:
member.role() // "stop", "main_stream", etc.
Get the relations to which a feature belongs:
feature.parents().relations()
feature.parents("r[route]")
Wrapping up
GeoDesk enables you to:
- Create compact spatial databases (“Feature libraries”) based on OpenStreetMap data
- Select features using a powerful query language and access their properties (“tags”) and geometries
- Traverse the relationships between nodes, ways and relations
- Leverage the Java Topology Suite for advanced geometric operations
Learn more
- Full documentation
- GOL utility — customize and maintain feature libraries
- JavaDocs
- Example code