/** * Prefills BBox with minimum values so that it can increase. */ public static BBox createInverse(boolean elevation) { if (elevation) { return new BBox(Double.MAX_VALUE, -Double.MAX_VALUE, Double.MAX_VALUE, -Double.MAX_VALUE, Double.MAX_VALUE, -Double.MAX_VALUE, true); } else { return new BBox(Double.MAX_VALUE, -Double.MAX_VALUE, Double.MAX_VALUE, -Double.MAX_VALUE, Double.NaN, Double.NaN, false); } }
@Override public LinearKeyAlgo setBounds(double minLonInit, double maxLonInit, double minLatInit, double maxLatInit) { bounds = new BBox(minLonInit, maxLonInit, minLatInit, maxLatInit); latDelta = (bounds.maxLat - bounds.minLat) / latUnits; lonDelta = (bounds.maxLon - bounds.minLon) / lonUnits; return this; }
@Override public BBox getBounds() { return new BBox(minLon, maxLon, minLat, maxLat); }
@Override public BBox getBounds() { return new BBox(-180, 180, -90, 90); } };
@Override public BBox clone() { return new BBox(minLon, maxLon, minLat, maxLat, minEle, maxEle, elevation); }
@Override public BBox deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException { double[] bounds = jsonParser.readValueAs(double[].class); return new BBox(bounds); } }
@JsonProperty public void setExtent(Double[] extent) { if (extent == null || extent.length == 0) { return; } if (extent.length == 4) { // Extend is in Left, Top, Right, Bottom; which is very uncommon, Photon uses the same this.extent = new BBox(extent[0], extent[2], extent[3], extent[1]); } else { throw new RuntimeException("Extent had an unexpected length: " + extent.length); } }
@Override public SpatialKeyAlgo setBounds(double minLonInit, double maxLonInit, double minLatInit, double maxLatInit) { bounds(new BBox(minLonInit, maxLonInit, minLatInit, maxLatInit)); return this; }
@Override public BBox getBounds() { return new BBox(-180, 180, -90, 90); } };
/** * Wrapper Method for {@link SpatialRuleLookupBuilder#buildIndex(JsonFeatureCollection, String, SpatialRuleFactory, double, BBox)}. * This method simply passes a world-wide BBox, this won't limit the SpatialRuleLookup. */ public static SpatialRuleLookup buildIndex(JsonFeatureCollection jsonFeatureCollection, String jsonIdField, SpatialRuleFactory spatialRuleFactory) { return buildIndex(jsonFeatureCollection, jsonIdField, spatialRuleFactory, .1, new BBox(-180, 180, -90, 90)); } }
@Override public BBox createBBox(double lat, double lon, double radiusInMeter) { if (radiusInMeter <= 0) throw new IllegalArgumentException("Distance must not be zero or negative! " + radiusInMeter + " lat,lon:" + lat + "," + lon); // length of a circle at specified lat / dist double dLon = (360 / (calcCircumference(lat) / radiusInMeter)); // length of a circle is independent of the longitude double dLat = (360 / (DistanceCalcEarth.C / radiusInMeter)); // Now return bounding box in coordinates return new BBox(lon - dLon, lon + dLon, lat - dLat, lat + dLat); }
@Override public BBox getBounds() { return new BBox(-180, 180, -90, 90); } };
public BBox setBounds(int minX, int maxX, int minY, int maxY) { double minLon = getLon(minX); double maxLon = getLon(maxX); double maxLat = getLat(minY); double minLat = getLat(maxY); bounds = new BBox(minLon, maxLon, minLat, maxLat); return bounds; } }
@Test public void testBounds() throws IOException { final FileReader reader = new FileReader(COUNTRIES_FILE); SpatialRuleLookup spatialRuleLookup = SpatialRuleLookupBuilder.buildIndex(Jackson.newObjectMapper().readValue(reader, JsonFeatureCollection.class), "ISO_A3", new CountriesSpatialRuleFactory(), .1, new BBox(-180, 180, -90, 90)); BBox almostWorldWide = new BBox(-179, 179, -89, 89); // Might fail if a polygon is defined outside the above coordinates assertTrue("BBox seems to be not contracted", almostWorldWide.contains(spatialRuleLookup.getBounds())); }
@Test public void testSmallBoundsBigPolygon() { List<SpatialRule> spatialRules = new ArrayList<>(); spatialRules.add(getSpatialRule(new Polygon(new double[]{-100, -100, 100, 100}, new double[]{-100, 100, 100, -100}), "big")); SpatialRuleLookup spatialRuleLookup = new SpatialRuleLookupArray(spatialRules, 1, true, new BBox(1, 2, 1, 2)); assertEquals("big", spatialRuleLookup.lookupRule(1.5, 1.5).getId()); }
@Test public void testNoIntersection() throws IOException { final FileReader reader = new FileReader(COUNTRIES_FILE); SpatialRuleLookup spatialRuleLookup = SpatialRuleLookupBuilder.buildIndex(Jackson.newObjectMapper().readValue(reader, JsonFeatureCollection.class), "ISO_A3", new CountriesSpatialRuleFactory(), .1, new BBox(-180, -179, -90, -89)); assertEquals(SpatialRuleLookup.EMPTY, spatialRuleLookup); }
@Test public void testIntersection() throws IOException { /* We are creating a BBox smaller than Germany. We have the German Spatial rule activated by default. So the BBox should not contain a Point lying somewhere close in Germany. */ final FileReader reader = new FileReader(COUNTRIES_FILE); SpatialRuleLookup spatialRuleLookup = SpatialRuleLookupBuilder.buildIndex(Jackson.newObjectMapper().readValue(reader, JsonFeatureCollection.class), "ISO_A3", new CountriesSpatialRuleFactory(), .1, new BBox(9, 10, 51, 52)); assertFalse("BBox seems to be incorrectly contracted", spatialRuleLookup.getBounds().contains(49.9, 8.9)); }
@Test public void testExactAdjacentBorder() { List<SpatialRule> spatialRules = new ArrayList<>(); // Two rules that divide the tile in half spatialRules.add(getSpatialRule(new Polygon(new double[]{1, 1, 1.5, 1.5}, new double[]{1, 2, 2, 1}), "top")); spatialRules.add(getSpatialRule(new Polygon(new double[]{1.5, 1.5, 2, 2}, new double[]{1, 2, 2, 1}), "bottom")); SpatialRuleLookup spatialRuleLookup = new SpatialRuleLookupArray(spatialRules, 1, true, new BBox(1, 4, 1, 4)); assertEquals("top", spatialRuleLookup.lookupRule(1.4, 1.5).getId()); assertEquals("bottom", spatialRuleLookup.lookupRule(1.6, 1.5).getId()); }
@Test public void testSmallScenario() { List<SpatialRule> spatialRules = new ArrayList<>(); spatialRules.add(getSpatialRule(new Polygon(new double[]{1, 1, 2, 2}, new double[]{1, 2, 2, 1}), "1")); spatialRules.add(getSpatialRule(new Polygon(new double[]{1, 1, 3.6, 3.6}, new double[]{3, 4, 4, 3}), "2")); SpatialRuleLookup spatialRuleLookup = new SpatialRuleLookupArray(spatialRules, 1, false, new BBox(1, 4, 1, 4)); Assert.assertEquals(AccessValue.EVENTUALLY_ACCESSIBLE, spatialRuleLookup.lookupRule(1.2, 1.7).getAccessValue(null, TransportationMode.MOTOR_VEHICLE, AccessValue.ACCESSIBLE)); assertEquals(AccessValue.EVENTUALLY_ACCESSIBLE, spatialRuleLookup.lookupRule(1.2, 3.7).getAccessValue(null, TransportationMode.MOTOR_VEHICLE, AccessValue.ACCESSIBLE)); assertEquals(AccessValue.ACCESSIBLE, spatialRuleLookup.lookupRule(2.2, 1.7).getAccessValue(null, TransportationMode.MOTOR_VEHICLE, AccessValue.ACCESSIBLE)); }
@Test public void testInstantiation() { double minLon = 0; double minLat = 2; double maxLat = 6; double maxLon = 5; BBox bounds = new BBox(minLon, maxLon, minLat, maxLat); LinearKeyAlgo algo1 = new LinearKeyAlgo(4, 4).setBounds(bounds); LinearKeyAlgo algo2 = new LinearKeyAlgo(4, 4).setBounds(minLon, maxLon, minLat, maxLat); assertEquals(algo1.getLonDelta(), algo2.getLonDelta(), 1e-7); assertEquals(algo1.getLatDelta(), algo2.getLatDelta(), 1e-7); } }