Skip to content
Snippets Groups Projects
Commit 60c53dd0 authored by Powers, Peter M.'s avatar Powers, Peter M.
Browse files

expanded map-region rectangle

parent 63fc9caf
No related branches found
No related tags found
1 merge request!235Model revisions
package gov.usgs.earthquake.nshmp.calc;
import static com.google.common.base.Preconditions.checkArgument;
import static gov.usgs.earthquake.nshmp.Text.LOG_INDENT;
import static gov.usgs.earthquake.nshmp.geo.BorderType.MERCATOR_LINEAR;
import static java.util.stream.Collectors.toUnmodifiableList;
......@@ -188,7 +187,7 @@ public final class Sites {
mapRegionIndex = 1;
Feature mapPoly = features.get(0);
LocationList mapPolyBorder = mapPoly.asPolygonBorder();
mapBounds = Optional.of(validateExtents(mapPolyBorder).bounds());
mapBounds = Optional.of(GeoJson.validateBoundingBox(mapPolyBorder).bounds());
boundsName = mapPoly.properties().getString(Site.Key.NAME).orElse("Map Extents");
}
......@@ -204,7 +203,7 @@ public final class Sites {
Region calcRegion = null;
try {
Bounds b = validateExtents(sitesPolyBorder).bounds();
Bounds b = GeoJson.validateBoundingBox(sitesPolyBorder).bounds();
calcRegion = Regions.createRectangular(mapName, b.min, b.max);
} catch (IllegalArgumentException iae) {
calcRegion = Regions.create(mapName, sitesPolyBorder, MERCATOR_LINEAR);
......@@ -230,35 +229,6 @@ public final class Sites {
.collect(toUnmodifiableList());
}
private static LocationList validateExtents(LocationList locations) {
/* Rectangular linear ring check. */
checkArgument(
locations.size() == 5,
"Extents polygon must contain 5 coordinates: %s",
locations);
/* Order agnostic rectilinear lat-lon check. */
Location p1 = locations.get(0);
Location p2 = locations.get(1);
Location p3 = locations.get(2);
Location p4 = locations.get(3);
boolean rectangular = (p1.latitude == p2.latitude)
? (p3.latitude == p4.latitude &&
p1.longitude == p4.longitude &&
p2.longitude == p3.longitude)
: (p1.latitude == p4.latitude &&
p2.latitude == p3.latitude &&
p1.longitude == p2.longitude &&
p3.longitude == p4.longitude);
checkArgument(
rectangular,
"Extents polygon does not define a lat-lon Mercator rectangle: %s",
locations);
return locations;
}
private static final int TO_STRING_LIMIT = 5;
private static final String SITE_INDENT = LOG_INDENT + " ";
......
......@@ -435,7 +435,7 @@ public class Region {
/*
* Initialize a rectangular region from two opposing corners expanding north
* and east border slightly to satisfy constains operations
* and east border slightly to satisfy contains operations
*/
void initRectangular(Location loc1, Location loc2) {
......
......@@ -23,6 +23,10 @@ import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import gov.usgs.earthquake.nshmp.Text;
import gov.usgs.earthquake.nshmp.geo.Bounds;
import gov.usgs.earthquake.nshmp.geo.Location;
import gov.usgs.earthquake.nshmp.geo.LocationList;
import gov.usgs.earthquake.nshmp.geo.Locations;
/**
* Entry point for creating and parsing <a href="http://geojson.org">GeoJSON</a>
......@@ -191,6 +195,81 @@ public abstract class GeoJson {
return new FromUrl(json);
}
/**
* Checks that bounding box location list contains 5 coordinates defining a
* mercator lat/lon rectangle.
*
* @param locations to check
* @return the supplied locaiton list
*/
public static LocationList validateBoundingBox(LocationList locations) {
/* Rectangular linear ring check. */
checkArgument(
locations.size() == 5,
"Extents polygon must contain 5 coordinates: %s",
locations);
/* Order agnostic rectilinear lat-lon check. */
Location p1 = locations.get(0);
Location p2 = locations.get(1);
Location p3 = locations.get(2);
Location p4 = locations.get(3);
boolean rectangular = (p1.latitude == p2.latitude)
? (p3.latitude == p4.latitude &&
p1.longitude == p4.longitude &&
p2.longitude == p3.longitude)
: (p1.latitude == p4.latitude &&
p2.latitude == p3.latitude &&
p1.longitude == p2.longitude &&
p3.longitude == p4.longitude);
checkArgument(
rectangular,
"Extents polygon does not define a lat-lon Mercator rectangle: %s",
locations);
return locations;
}
/**
* Checks that the supplied location list defines a rectangular lat/lon area
* and returns a slightly expanded version that will enclosepoints on the
* borders of the area. Points coincident with east and north edges of
* polygons are considered inside as a result.
*/
public static LocationList expandRectangularArea(LocationList locations) {
Bounds b = validateBoundingBox(locations).bounds();
double lat1 = b.min.latitude;
double lat2 = b.max.latitude;
double lon1 = b.min.longitude;
double lon2 = b.max.longitude;
// checkArgument(lat1 != lat2, "Input lats cannot be the same");
// checkArgument(lon1 != lon2, "Input lons cannot be the same");
double minLat = Math.min(lat1, lat2);
double minLon = Math.min(lon1, lon2);
double maxLat = Math.max(lat1, lat2);
double maxLon = Math.max(lon1, lon2);
double offset = Locations.TOLERANCE;
// ternaries prevent exceedance of max lat-lon values
maxLat += (maxLat <= 90.0 - offset) ? offset : 0.0;
maxLon += (maxLon <= 180.0 - offset) ? offset : 0.0;
minLat -= (minLat >= -90.0 + offset) ? offset : 0.0;
minLon -= (minLon >= -180.0 + offset) ? offset : 0.0;
LocationList expanded = LocationList.of(
Location.create(minLon, minLat),
Location.create(minLon, maxLat),
Location.create(maxLon, maxLat),
Location.create(maxLon, minLat));
// initBordered(locs, MERCATOR_LINEAR);
return expanded;
}
/**
* A reusable GeoJSON builder.
*/
......
......@@ -33,8 +33,10 @@ import com.google.gson.annotations.SerializedName;
import gov.usgs.earthquake.nshmp.calc.CalcConfig;
import gov.usgs.earthquake.nshmp.geo.Location;
import gov.usgs.earthquake.nshmp.geo.LocationList;
import gov.usgs.earthquake.nshmp.geo.Locations;
import gov.usgs.earthquake.nshmp.geo.json.Feature;
import gov.usgs.earthquake.nshmp.geo.json.GeoJson;
import gov.usgs.earthquake.nshmp.gmm.Gmm;
import gov.usgs.earthquake.nshmp.gmm.GroundMotionModel;
import gov.usgs.earthquake.nshmp.gmm.NehrpSiteClass;
......@@ -354,7 +356,8 @@ public final class HazardModel implements Iterable<SourceTree> {
MapRegion(Feature feature) {
this.feature = feature;
this.area = new Area(Locations.toPath(feature.asPolygonBorder()));
LocationList areaLocs = GeoJson.expandRectangularArea(feature.asPolygonBorder());
this.area = new Area(Locations.toPath(areaLocs));
}
boolean contains(Location loc) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment