Skip to content

Version 0.2

Latest
Compare
Choose a tag to compare
@clarisma clarisma released this 13 Apr 17:21

This release introduces the streamlined API we've announced in 0.1.10.

Most importantly, we've simplified the type system. OpenStreetMap features are represented as nodes, ways and relations, and GeoDesk has corresponding Node, Way and Relation interfaces, which derive from the Feature supertype. In 0.2, these subtypes still exist as marker interfaces, but their specialized methods have moved to the supertype. This means that all features can simply be treated as a Feature, which removes the need for casting and awkward generics. When working with feature sets, you'll no longer need to declare Features<?> or Features<Node> -- you'll simply use Features.

This change aligns more closely with how users think about OSM data. Most points-of-interest can be modeled as nodes, ways or relations -- for example, a museum could be marked as a single point, a simple polygon (as a closed way) or a building with a courtyard (requiring a multipolygon relation). In those cases where the OSM type matters, use .isNode(), .isWay() or .isRelation() (or type()).

We've prepared a Migration Guide to ensure your upgrade goes smoothly.

Breaking changes

  • The Features interface is no longer generic. Iterating over Features always
    returns Feature objects.

  • The typed methods (memberNodes(), parentRelations(), etc.) have been
    removed. To constrain a type, use members().nodes(), parents().relations(),
    or include the feature type in a query string (members("n"), parents("r")).

  • All classes from com.geodesk.core (such as Box and Heading) have moved to com.geodesk.geom

Enhancements

  • Applying spatial filters is now much simpler. Instead of using the Filters factory class, filters can now be invoked directly on the Features object.

    So instead of

    biotopes.select(Filters.coveredBy(area))

    simply use

    biotopes.coveredBy(area)

    Note that several spatial filter methods have changed names:

    contains() -> containing()
    crosses() -> crossing()
    intersects() -> intersecting()
    overlaps() -> overlapping()
    touches() -> touching()

    These changes make your code read more naturally:

    bridges.crossing(river)
    adminAreas.touching(county)

    This change also resolves the ambiguity concerning contains():

    • Features.contains(Object) checks if the given feature is part of this feature set.
    • Features.containing(Feature) returns the features whose geometry contains the given feature.

Deprecations

  • The Filters factory class has been deprecated and may be removed in future releases.
    The preferred way to use filters is to call the filter methods on Features, as discussed above.