// License: GPL. For details, see LICENSE file. package org.openstreetmap.josm.tools; import java.awt.geom.Area; import java.awt.geom.Path2D; import java.util.Collection; import org.openstreetmap.josm.data.coor.LatLon; import org.openstreetmap.josm.data.osm.BBox; import org.openstreetmap.josm.data.osm.Relation; import org.openstreetmap.josm.data.osm.Way; /** * Implementation of simple boolean {@link GeoProperty}. */ public class DefaultGeoProperty implements GeoProperty<Boolean> { private final Area area; /** * Create DefaultGeoProperty based on a collection of closed ways. * * @param ways the ways forming the area */ public DefaultGeoProperty(Collection<Way> ways) { Path2D path = new Path2D.Double(); path.setWindingRule(Path2D.WIND_EVEN_ODD); for (Way w : ways) { Geometry.buildPath2DLatLon(w.getNodes(), path); } this.area = new Area(path); } /** * Create DefaultGeoProperty based on a multipolygon relation. * * @param multipolygon the multipolygon */ public DefaultGeoProperty(Relation multipolygon) { this.area = Geometry.getAreaLatLon(multipolygon); } @Override public Boolean get(LatLon ll) { return area.contains(ll.lon(), ll.lat()); } @Override public Boolean get(BBox box) { Area abox = new Area(box.toRectangle()); Geometry.PolygonIntersection is = Geometry.polygonIntersection(abox, area, 1e-10 /* using deg and not meters */); switch (is) { case FIRST_INSIDE_SECOND: return Boolean.TRUE; case OUTSIDE: return Boolean.FALSE; default: return null; } } }