diff --git a/src/lib/build.gradle b/src/lib/build.gradle new file mode 100644 index 0000000000000000000000000000000000000000..8b137891791fe96927ad78e64b0aad7bded08bdc --- /dev/null +++ b/src/lib/build.gradle @@ -0,0 +1 @@ + diff --git a/src/lib/src/main/java/gov/usgs/earthquake/nshmp/netcdf/Netcdf.java b/src/lib/src/main/java/gov/usgs/earthquake/nshmp/netcdf/Netcdf.java new file mode 100644 index 0000000000000000000000000000000000000000..5c13df52084f3a2bcac317f429588f895edd4007 --- /dev/null +++ b/src/lib/src/main/java/gov/usgs/earthquake/nshmp/netcdf/Netcdf.java @@ -0,0 +1,97 @@ +package gov.usgs.earthquake.nshmp.netcdf; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.logging.Level; +import java.util.logging.Logger; + +import gov.usgs.earthquake.nshmp.geo.Location; +import gov.usgs.earthquake.nshmp.gmm.NehrpSiteClass; +import gov.usgs.earthquake.nshmp.netcdf.data.BoundingData; +import gov.usgs.earthquake.nshmp.netcdf.data.NetcdfData; +import gov.usgs.earthquake.nshmp.netcdf.data.NetcdfShape; +import gov.usgs.earthquake.nshmp.netcdf.data.StaticData; +import gov.usgs.earthquake.nshmp.netcdf.reader.Reader; + +/** + * Abstarct class for NetCDF types: hazard curves and ground motions. + * + * @author U.S. Geological Survey + */ +public abstract class Netcdf<T> { + + protected final Path netcdfPath; + protected final NetcdfDataType dataType; + protected final NetcdfData netcdfData; + protected NetcdfShape netcdfShape; + + private static final Logger LOGGER = Logger.getLogger("ucar"); + + static { + /* Update ucar logger */ + LOGGER.setLevel(Level.SEVERE); + } + + public Netcdf(Path netcdfPath) { + this.netcdfPath = netcdfPath; + + if (Files.notExists(netcdfPath)) { + throw new IllegalArgumentException("Path to Netcdf file [" + netcdfPath + "] does not exist"); + } + + dataType = NetcdfDataType.getDataType(netcdfPath); + var reader = getNetcdfData(netcdfPath); + netcdfData = reader.netcdfData(); + netcdfShape = reader.netcdfShape(); + } + + /** + * Returns the bounding data from a specific site. + * + * @param site The site to get the bounding data + */ + public abstract BoundingData<T> boundingData(Location site); + + /** + * Returns the data type. + */ + public NetcdfDataType dataType() { + return dataType; + } + + /** + * Returns the NetCDF data. + */ + public abstract NetcdfData netcdfData(); + + /** + * Returns the NetCDF path. + */ + public Path netcdfPath() { + return netcdfPath; + } + + /** + * Returns the NetCDF shape` + */ + public NetcdfShape netcdfShape() { + return netcdfShape; + } + + /** + * Returns the static data from a specific site. + * + * @param site The site to get the static data + */ + public abstract StaticData<T> staticData(Location site); + + /** + * Returns the static data from a site and site class. + * + * @param site The site to get the static data + * @param siteClass The site class to get the static data + */ + public abstract T staticData(Location site, NehrpSiteClass siteClass); + + abstract Reader getNetcdfData(Path netcdfPath); +} diff --git a/src/lib/src/main/java/gov/usgs/earthquake/nshmp/netcdf/NetcdfDataType.java b/src/lib/src/main/java/gov/usgs/earthquake/nshmp/netcdf/NetcdfDataType.java new file mode 100644 index 0000000000000000000000000000000000000000..d7bb13c55cb393d6fad60b864e903487580fee39 --- /dev/null +++ b/src/lib/src/main/java/gov/usgs/earthquake/nshmp/netcdf/NetcdfDataType.java @@ -0,0 +1,32 @@ +package gov.usgs.earthquake.nshmp.netcdf; + +import java.io.IOException; +import java.nio.file.Path; + +import gov.usgs.earthquake.nshmp.netcdf.reader.NetcdfUtils.Key; + +import ucar.nc2.dataset.NetcdfDatasets; + +/** + * Supported NetCDF data types. + */ +public enum NetcdfDataType { + + GROUND_MOTIONS, + HAZARD_CURVES; + + /** + * Returns the data type read from a NetCDF file with attribute "dataType". + * + * @param netcdfPath Path to NetCDF file + */ + public static NetcdfDataType getDataType(Path netcdfPath) { + try (var ncd = NetcdfDatasets.openDataset(netcdfPath.toString())) { + var group = ncd.getRootGroup(); + var vDataType = group.attributes().findAttribute(Key.DATA_TYPE); + return NetcdfDataType.valueOf(vDataType.getStringValue()); + } catch (IOException e) { + throw new RuntimeException("Could not read Netcdf file [" + netcdfPath + " ]"); + } + } +} diff --git a/src/lib/src/main/java/gov/usgs/earthquake/nshmp/netcdf/SiteClass.java b/src/lib/src/main/java/gov/usgs/earthquake/nshmp/netcdf/SiteClass.java new file mode 100644 index 0000000000000000000000000000000000000000..3d38dc3a675277445b9a50ab902750290320b34b --- /dev/null +++ b/src/lib/src/main/java/gov/usgs/earthquake/nshmp/netcdf/SiteClass.java @@ -0,0 +1,104 @@ +package gov.usgs.earthquake.nshmp.netcdf; + +import java.util.Arrays; + +/** + * This should be imported. For now, it is copied from + * nshmp-haz-v2/src/gov.usgs.earthquake.nshmp.site.NehrpSiteClass.java + * + * Placeholder enum for likely move to Nehrp site class identifier instead of + * Vs30. + * + * <p>These site class identifiers map to NEHRP site clases, but the intent is + * that they can be used more generally for models in other parts of the world + * where the GMMs are not necessarily parameterized in terms of vs30 to define + * site response. For instance, NZ/JP site classes might use A, B, C, and D as a + * proxy for the local I, II, III, and IV identifiers. In the U.S., models will + * need to specify the Vs30 value that each site class corresponds to. Although + * the values were consistent over prior models, now that multiple site classes + * are supported (in 2018) across the entire U.S., there have been changes + * proposed for balloting by the BSSC to make the Vs30 definitions of site + * classes consistent in how they are calculated. + * + * @author Peter Powers + */ +public enum SiteClass { + + /* + * Notes on calculation of Vs30 for site class: + * + * Question: Why is it that the soil shear wave velocity shown in the Unified + * Hazard Tool is not equal to the average of the values shown in ASCE 7-10 + * table 20.3-1? + * + * For instance: 259 m/s (Site Class D), from the Unified Hazard Tool, is not + * equal to (600 ft/s + 1200 ft/s)/2 * .3048 = 274 m/s + * + * Answer (Sanaz): we take the geometric mean: sqrt(1200*600)*0.3048 = + * 258.6314 , which rounds to 259m/s. + * + * + */ + + /* OLD Vs30, NEW Vs30 */ + + /* 2000 2000 */ + A("Site class A (Vs30 2000)", 2000), + + /* 1500 1500 (new) */ + AB("Site class AB (Vs30 1500)", 1500), + + /* 1150 1080 */ + B("Site class B (Vs30 1080)", 1080), + + /* 760 760 */ + BC("Site class BC (Vs30 760)", 760), + + /* 537 530 */ + C("Site class C (Vs30 530)", 530), + + /* 360 365 */ + CD("Site class CD (Vs30 365)", 365), + + /* 259 260 */ + D("Site class D (Vs30 260)", 260), + + /* 180 185 */ + DE("Site class DE (Vs30 185)", 185), + + /* 150 150 (new) */ + E("Site class E (Vs30 150)", 150); + + private final String display; + private final int vs30; + + private SiteClass(String display, int vs30) { + this.display = display; + this.vs30 = vs30; + } + + /** + * Returns the Vs30 associated with the {@code SiteClass}. + */ + public int vs30() { + return vs30; + } + + /** + * Returns a {@code SiteClass} associated with the vs30. + * + * @param vs30 The vs30 of the site class + */ + public static SiteClass ofValue(int vs30) { + return Arrays.stream(values()) + .filter(siteClass -> siteClass.vs30 == vs30) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException( + "No matching site class to Vs30 [" + vs30 + "]")); + } + + @Override + public String toString() { + return display; + } +} diff --git a/src/lib/src/main/java/gov/usgs/earthquake/nshmp/netcdf/data/BoundingData.java b/src/lib/src/main/java/gov/usgs/earthquake/nshmp/netcdf/data/BoundingData.java new file mode 100644 index 0000000000000000000000000000000000000000..6fcda9d66b1a82164c270f380531c26bc3a8c709 --- /dev/null +++ b/src/lib/src/main/java/gov/usgs/earthquake/nshmp/netcdf/data/BoundingData.java @@ -0,0 +1,45 @@ +package gov.usgs.earthquake.nshmp.netcdf.data; + +import static com.google.common.base.Preconditions.checkState; + +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; + +import gov.usgs.earthquake.nshmp.geo.Location; + +/** + * Location to static data mapper. + * + * @author U.S. Geological Survey + */ +public class BoundingData<T> extends LinkedHashMap<Location, StaticData<T>> { + + public BoundingData() {} + + private BoundingData(Map<Location, StaticData<T>> boundingHazards) { + putAll(boundingHazards); + } + + public static <T> Builder<T> builder() { + return new Builder<T>(); + } + + public static class Builder<T> { + Map<Location, StaticData<T>> boundingData; + + private Builder() { + boundingData = new HashMap<>(); + } + + public Builder<T> put(Location location, StaticData<T> staticData) { + boundingData.put(location, staticData); + return this; + } + + public BoundingData<T> build() { + checkState(!boundingData.isEmpty(), "Must add static data"); + return new BoundingData<>(boundingData); + } + } +} diff --git a/src/lib/src/main/java/gov/usgs/earthquake/nshmp/netcdf/data/NetcdfData.java b/src/lib/src/main/java/gov/usgs/earthquake/nshmp/netcdf/data/NetcdfData.java new file mode 100644 index 0000000000000000000000000000000000000000..41b07528eb87a8c6c70f774b008c765736627b6f --- /dev/null +++ b/src/lib/src/main/java/gov/usgs/earthquake/nshmp/netcdf/data/NetcdfData.java @@ -0,0 +1,156 @@ +package gov.usgs.earthquake.nshmp.netcdf.data; + +import static com.google.common.base.Preconditions.checkState; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; + +import gov.usgs.earthquake.nshmp.geo.Bounds; +import gov.usgs.earthquake.nshmp.geo.Location; +import gov.usgs.earthquake.nshmp.geo.Regions; +import gov.usgs.earthquake.nshmp.gmm.Imt; +import gov.usgs.earthquake.nshmp.gmm.NehrpSiteClass; + +/** + * Data info from the NetCDF file. + * + * @author U.S. Geological Survey + */ +public class NetcdfData { + private final Bounds bounds; + private final List<Imt> imts; + private final double[] latitudes; + private final double[] longitudes; + private final ScienceBaseMetadata scienceBaseMetadata; + private final List<NehrpSiteClass> siteClasses; + private final Map<NehrpSiteClass, Double> vs30Map; + + protected NetcdfData(Builder builder) { + var minLatitude = Arrays.stream(builder.latitudes).min().getAsDouble(); + var maxLatitude = Arrays.stream(builder.latitudes).max().getAsDouble(); + var minLongitude = Arrays.stream(builder.longitudes).min().getAsDouble(); + var maxLongitude = Arrays.stream(builder.longitudes).max().getAsDouble(); + + bounds = Regions.createRectangular( + "", + Location.create(minLongitude, minLatitude), + Location.create(maxLongitude, maxLatitude)).bounds(); + imts = builder.imts; + latitudes = builder.latitudes; + longitudes = builder.longitudes; + scienceBaseMetadata = builder.scienceBaseMetadata; + siteClasses = builder.siteClasses; + vs30Map = builder.vs30Map; + } + + /** + * Returns the bounds + */ + public Bounds bounds() { + return bounds; + } + + /** + * Return the Imts + */ + public List<Imt> imts() { + return List.copyOf(imts); + } + + /** + * Returns the latitudes. + */ + public double[] latitudes() { + return latitudes.clone(); + } + + /** + * Returns the longitudes. + */ + public double[] longitudes() { + return longitudes.clone(); + } + + /** + * Returns the science base info + */ + public ScienceBaseMetadata scienceBaseMetadata() { + return scienceBaseMetadata; + } + + /** + * Return the site classes + */ + public List<NehrpSiteClass> siteClasses() { + return List.copyOf(siteClasses); + } + + /** + * Returns the VS30 map + */ + public Map<NehrpSiteClass, Double> vs30Map() { + return new TreeMap<>(vs30Map); + } + + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + List<Imt> imts; + double[] latitudes; + double[] longitudes; + List<NehrpSiteClass> siteClasses; + ScienceBaseMetadata scienceBaseMetadata; + Map<NehrpSiteClass, Double> vs30Map; + + Builder() {} + + public Builder imts(List<Imt> imts) { + this.imts = imts; + return this; + } + + public Builder latitudes(double[] latitudes) { + this.latitudes = latitudes; + return this; + } + + public Builder longitudes(double[] longitudes) { + this.longitudes = longitudes; + return this; + } + + public Builder scienceBaseMetadata(ScienceBaseMetadata scienceBaseMetadata) { + this.scienceBaseMetadata = scienceBaseMetadata; + return this; + } + + public Builder siteClasses(List<NehrpSiteClass> siteClasses) { + this.siteClasses = siteClasses; + return this; + } + + public Builder vs30Map(Map<NehrpSiteClass, Double> vs30Map) { + this.vs30Map = vs30Map; + return this; + } + + public NetcdfData build() { + checkBuildState(); + return new NetcdfData(this); + } + + void checkBuildState() { + checkState(!imts.isEmpty(), "Must add imts"); + checkState(!(latitudes.length == 0), "Must add latitude"); + checkState(!(longitudes.length == 0), "Must add longitudes"); + checkState(scienceBaseMetadata != null, "Must set science base metadata"); + checkState(!siteClasses.isEmpty(), "Must add site classes"); + checkState(!vs30Map.isEmpty(), "Must add vs30s"); + } + } + +} diff --git a/src/lib/src/main/java/gov/usgs/earthquake/nshmp/netcdf/data/NetcdfShape.java b/src/lib/src/main/java/gov/usgs/earthquake/nshmp/netcdf/data/NetcdfShape.java new file mode 100644 index 0000000000000000000000000000000000000000..698207bf4ae2a9d5c1c4cd5b24ad11ac491a8633 --- /dev/null +++ b/src/lib/src/main/java/gov/usgs/earthquake/nshmp/netcdf/data/NetcdfShape.java @@ -0,0 +1,139 @@ +package gov.usgs.earthquake.nshmp.netcdf.data; + +import static com.google.common.base.Preconditions.checkState; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +/** + * Create NetCDF shapes and keep track of indices. + * + * @author U.S. Geological Survey + */ +public class NetcdfShape { + + private final Map<IndexKey, Integer> indexMap; + + private NetcdfShape(Builder builder) { + indexMap = builder.indexMap; + } + + /** + * Returns builder to build a NetCDF shape. + */ + public static Builder builder() { + return new Builder(); + } + + /** + * Returns a builder to build an array shape for NetCDF origin and shapes. + */ + public BuildShape buildShape() { + return new BuildShape(); + } + + public class BuildShape { + List<KeySize> keySizes; + Optional<Integer> pad = Optional.empty(); + boolean reduce = false; + + private BuildShape() { + keySizes = new ArrayList<>(); + } + + /** + * Add key and associated size for shape. + * + * @param key The key + * @param size The size + */ + public BuildShape add(IndexKey key, int size) { + checkState(indexMap.containsKey(key), String.format("Key [%s] not found in shape", key)); + keySizes.add(new KeySize(key, size)); + return this; + } + + /** + * Change to padding value of 0. + * + * Not used if reducing shape. + * + * @param value The value to pad the array shape + */ + public BuildShape pad(int value) { + pad = Optional.of(value); + return this; + } + + /** + * Reduce the array to only added keys in builder. + */ + public BuildShape reduce() { + reduce = true; + return this; + } + + /** + * Returns the shape array. + */ + public int[] build() { + if (reduce) { + var reducePad = -1; + return build(reducePad).stream() + .mapToInt(Integer::intValue) + .filter(val -> val != reducePad) + .toArray(); + } else { + return build(pad.orElse(0)).stream().mapToInt(Integer::intValue).toArray(); + } + } + + private List<Integer> build(int pad) { + var shape = new ArrayList<>(Collections.nCopies(indexMap.size(), pad)); + keySizes.forEach(keySize -> { + shape.set(indexMap.get(keySize.indexKey), keySize.size); + }); + + return shape; + } + } + + public static class KeySize { + public final IndexKey indexKey; + public final int size; + + private KeySize(IndexKey indexKey, int size) { + this.indexKey = indexKey; + this.size = size; + } + } + + public static enum IndexKey { + IML, + IMT, + LATITUDE, + LONGITUDE, + SITE_CLASS; + } + + public static class Builder { + Map<IndexKey, Integer> indexMap; + + private Builder() { + indexMap = new HashMap<>(); + } + + public Builder add(IndexKey key, int index) { + indexMap.put(key, index); + return this; + } + + public NetcdfShape build() { + return new NetcdfShape(this); + } + } +} diff --git a/src/lib/src/main/java/gov/usgs/earthquake/nshmp/netcdf/data/ScienceBaseInfo.java b/src/lib/src/main/java/gov/usgs/earthquake/nshmp/netcdf/data/ScienceBaseInfo.java new file mode 100644 index 0000000000000000000000000000000000000000..a57b2422537863b90b4404d86dfadfd4eb2b6e2a --- /dev/null +++ b/src/lib/src/main/java/gov/usgs/earthquake/nshmp/netcdf/data/ScienceBaseInfo.java @@ -0,0 +1,38 @@ +package gov.usgs.earthquake.nshmp.netcdf.data; + +public class ScienceBaseInfo { + + final String id; + final String file; + final CatalogFileInfo[] files; + final String scienceBaseVersion; + final String title; + final String url; + + ScienceBaseInfo( + String id, + String file, + CatalogFileInfo[] files, + String scienceBaseVersion, + String title, + String url) { + this.id = id; + this.file = file; + this.files = files; + this.scienceBaseVersion = scienceBaseVersion; + this.title = title; + this.url = url; + } + + static class CatalogFileInfo { + final String file; + final String siteClass; + final String vs30; + + CatalogFileInfo(String file, String siteClass, String vs30) { + this.file = file; + this.siteClass = siteClass; + this.vs30 = vs30; + } + } +} diff --git a/src/lib/src/main/java/gov/usgs/earthquake/nshmp/netcdf/data/ScienceBaseMetadata.java b/src/lib/src/main/java/gov/usgs/earthquake/nshmp/netcdf/data/ScienceBaseMetadata.java new file mode 100644 index 0000000000000000000000000000000000000000..556087b6420b90c137bbc5d126dad2854e149377 --- /dev/null +++ b/src/lib/src/main/java/gov/usgs/earthquake/nshmp/netcdf/data/ScienceBaseMetadata.java @@ -0,0 +1,38 @@ +package gov.usgs.earthquake.nshmp.netcdf.data; + +import com.google.common.reflect.TypeToken; +import com.google.gson.Gson; + +import gov.usgs.earthquake.nshmp.netcdf.NetcdfDataType; +import gov.usgs.earthquake.nshmp.netcdf.reader.NetcdfUtils.Key; + +import ucar.nc2.Group; + +public class ScienceBaseMetadata { + + public final String catalogId; + public final NetcdfDataType dataType; + public final String description; + public final double gridStep; + public final String history; + public final String label; + public final String region; + public final ScienceBaseInfo[] scienceBaseInfo; + public final int year; + + static final Gson GSON = new Gson(); + + public ScienceBaseMetadata(Group targetGroup) { + catalogId = targetGroup.findAttribute(Key.ID).getStringValue(); + dataType = NetcdfDataType.valueOf(targetGroup.findAttribute(Key.DATA_TYPE).getStringValue()); + description = targetGroup.findAttribute(Key.DESCRIPTION).getStringValue(); + gridStep = targetGroup.findAttribute(Key.GRID_STEP).getNumericValue().doubleValue(); + history = targetGroup.findAttribute(Key.HISTORY).getStringValue(); + label = targetGroup.findAttribute(Key.LABEL).getStringValue(); + region = targetGroup.findAttribute(Key.REGION).getStringValue(); + scienceBaseInfo = GSON.fromJson( + targetGroup.findAttribute(Key.SCIENCE_BASE_INFO).getStringValue(), + new TypeToken<ScienceBaseInfo[]>() {}.getType()); + year = targetGroup.findAttribute(Key.YEAR).getNumericValue().intValue(); + } +} diff --git a/src/lib/src/main/java/gov/usgs/earthquake/nshmp/netcdf/data/StaticData.java b/src/lib/src/main/java/gov/usgs/earthquake/nshmp/netcdf/data/StaticData.java new file mode 100644 index 0000000000000000000000000000000000000000..21642ae253a2c6c1974a48a8a8779e7aeb2505e6 --- /dev/null +++ b/src/lib/src/main/java/gov/usgs/earthquake/nshmp/netcdf/data/StaticData.java @@ -0,0 +1,46 @@ +package gov.usgs.earthquake.nshmp.netcdf.data; + +import static com.google.common.base.Preconditions.checkState; + +import java.util.EnumMap; + +import gov.usgs.earthquake.nshmp.gmm.NehrpSiteClass; + +/** + * NEHRP site class to data mapper. + * + * @author U.S. Geological Survey + */ +public class StaticData<T> extends EnumMap<NehrpSiteClass, T> { + + public StaticData() { + super(NehrpSiteClass.class); + } + + StaticData(EnumMap<NehrpSiteClass, T> data) { + super(NehrpSiteClass.class); + putAll(data); + } + + public static <T> Builder<T> builder() { + return new Builder<T>(); + } + + public static class Builder<T> { + EnumMap<NehrpSiteClass, T> data; + + private Builder() { + data = new EnumMap<>(NehrpSiteClass.class); + } + + public Builder<T> put(NehrpSiteClass siteClass, T data) { + this.data.put(siteClass, data); + return this; + } + + public StaticData<T> build() { + checkState(!data.isEmpty(), "Must add data"); + return new StaticData<T>(data); + } + } +} diff --git a/src/lib/src/main/java/gov/usgs/earthquake/nshmp/netcdf/reader/BoundingReader.java b/src/lib/src/main/java/gov/usgs/earthquake/nshmp/netcdf/reader/BoundingReader.java new file mode 100644 index 0000000000000000000000000000000000000000..83f5c2e3cfab7d21a6a56b1678b7b6667cc80cb1 --- /dev/null +++ b/src/lib/src/main/java/gov/usgs/earthquake/nshmp/netcdf/reader/BoundingReader.java @@ -0,0 +1,135 @@ +package gov.usgs.earthquake.nshmp.netcdf.reader; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +import gov.usgs.earthquake.nshmp.geo.Location; +import gov.usgs.earthquake.nshmp.geo.LocationList; +import gov.usgs.earthquake.nshmp.netcdf.Netcdf; +import gov.usgs.earthquake.nshmp.netcdf.data.BoundingData; +import gov.usgs.earthquake.nshmp.netcdf.data.NetcdfData; +import gov.usgs.earthquake.nshmp.netcdf.data.NetcdfShape; +import gov.usgs.earthquake.nshmp.netcdf.data.NetcdfShape.IndexKey; +import gov.usgs.earthquake.nshmp.netcdf.data.StaticData; + +import ucar.ma2.Array; + +/** + * Abstract class to read in NetCDF file and create the bounding locations and + * associated data. + * + * @author U.S. Geological Survey + */ +public abstract class BoundingReader<T> { + + private final NetcdfData netcdfData; + private BoundingData<T> boundingData; + private List<BoundingLocation> boundingLocations = new ArrayList<>(); + + BoundingReader(Netcdf<T> netcdf, Location site) { + this.netcdfData = netcdf.netcdfData(); + boundingLocations = setBoundingLocations(netcdf, site); + boundingData = setBoundingData(netcdf, site, boundingLocations); + } + + /** + * Returns the bounding data associated with a location + */ + public BoundingData<T> boundingData() { + return boundingData; + } + + /** + * Returns the bounding locations + */ + LocationList boundingLocations() { + var locations = boundingLocations.stream() + .map(boundingLocation -> boundingLocation.location) + .collect(Collectors.toList()); + + return LocationList.copyOf(locations); + } + + abstract StaticData<T> calculateTargetData( + List<BoundingLocation> boundingLocations, + BoundingData<T> boundingData, + double fracLon, + double fracLat); + + abstract BoundingData<T> extractDataAt( + Netcdf<T> netcdf, + List<BoundingLocation> boundingLocations, + int idxLonLL, + int idxLatLL); + + /** + * Get data for target point + * + * @param d1 data at first point (p1) + * @param d2 data at second point (p2) + * @param frac fractional distance between p1 and p2 to target point + */ + abstract StaticData<T> getTargetData(StaticData<T> d1, StaticData<T> d2, double frac); + + /* + * Read hazard curves from netCDF variable into map of hazards by SiteClass + * and Imt + * + * TODO: if target is on a grid point (or on a grid lat or lon), no need to + * read 4 bounding points ? + */ + abstract StaticData<T> mapDataFromArray( + Netcdf<T> netcdf, + Array array); + + /** + * Set the bounding data + */ + abstract BoundingData<T> setBoundingData( + Netcdf<T> netcdf, + Location site, + List<BoundingLocation> boundingLocations); + + static class BoundingLocation { + final Location location; + final int[] origin; + + BoundingLocation( + NetcdfShape netcdfShape, + Location location, + int longitudeIndex, + int latitudeIndex) { + this.location = location; + origin = netcdfShape.buildShape() + .add(IndexKey.LATITUDE, latitudeIndex) + .add(IndexKey.LONGITUDE, longitudeIndex) + .build(); + } + } + + private List<BoundingLocation> setBoundingLocations(Netcdf<T> netcdf, Location site) { + var boundingLocations = new ArrayList<BoundingLocation>(); + var longitudes = netcdfData.longitudes(); + var latitudes = netcdfData.latitudes(); + + var idxLonLL = NetcdfUtils.getIdxLTEQ(longitudes, site.longitude); + var idxLatLL = NetcdfUtils.getIdxLTEQ(latitudes, site.latitude); + + var lonLeft = longitudes[idxLonLL]; + var lonRight = longitudes[idxLonLL + 1]; + var latLower = latitudes[idxLatLL]; + var latUpper = latitudes[idxLatLL + 1]; + + boundingLocations.add( + new BoundingLocation(netcdf.netcdfShape(), Location.create(lonLeft, latLower), 0, 0)); + boundingLocations.add( + new BoundingLocation(netcdf.netcdfShape(), Location.create(lonLeft, latUpper), 0, 1)); + boundingLocations.add( + new BoundingLocation(netcdf.netcdfShape(), Location.create(lonRight, latUpper), 1, 1)); + boundingLocations.add( + new BoundingLocation(netcdf.netcdfShape(), Location.create(lonRight, latLower), 1, 0)); + + return boundingLocations; + } +} diff --git a/src/lib/src/main/java/gov/usgs/earthquake/nshmp/netcdf/reader/NetcdfUtils.java b/src/lib/src/main/java/gov/usgs/earthquake/nshmp/netcdf/reader/NetcdfUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..d03775dd2fadd9c9a00baa1d7f79331f7d8c6e3a --- /dev/null +++ b/src/lib/src/main/java/gov/usgs/earthquake/nshmp/netcdf/reader/NetcdfUtils.java @@ -0,0 +1,257 @@ +package gov.usgs.earthquake.nshmp.netcdf.reader; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; + +import java.io.IOException; +import java.util.Arrays; + +import com.google.common.math.DoubleMath; + +import gov.usgs.earthquake.nshmp.data.XySequence; +import gov.usgs.earthquake.nshmp.geo.Location; +import gov.usgs.earthquake.nshmp.geo.LocationList; +import gov.usgs.earthquake.nshmp.netcdf.data.BoundingData; +import gov.usgs.earthquake.nshmp.netcdf.data.StaticData; + +import ucar.ma2.DataType; +import ucar.nc2.Group; + +public class NetcdfUtils { + + // Tolerance for longitude/latitude comparisons + static final double LOCATION_TOLERANCE = 0.000001; + + /** + * Creates a border going clockwise of the given longitudes and latitudes. + * + * @param longitudes The longitudes + * @param latitudes The latitudes + * @return + */ + public static LocationList buildBorder(double[] longitudes, double[] latitudes) { + var builder = LocationList.builder(); + + for (var lat : latitudes) { + builder.add(longitudes[0], lat); + } + + // omit duplicate points at corners + for (var i = 1; i < longitudes.length; i++) { + builder.add(longitudes[i], latitudes[latitudes.length - 1]); + } + + for (var i = latitudes.length - 2; i >= 0; i--) { + builder.add(longitudes[longitudes.length - 1], latitudes[i]); + } + + for (var i = longitudes.length - 2; i >= 0; i--) { + builder.add(longitudes[i], latitudes[0]); + } + + return builder.build(); + } + + /* + * Calculate fractional distance from a1 to t, between a1 and a2 + */ + static double calcFrac(double a1, double a2, double t) { + if (Math.abs(t - a1) < LOCATION_TOLERANCE) { + // target value == a1 + return 0.0; + } else if (Math.abs(t - a2) < LOCATION_TOLERANCE) { + // target value == a2 + return 1.0; + } else { + // calculate fractional distance to t between a[i] and a[i+1] + return (t - a1) / (a2 - a1); + } + } + + /* + * Calculate fractional distance from a[i] to t, between a[i] and a[i+1] + */ + static double calcGridFrac(double[] a, int i, double t) { + return calcFrac(a[i], a[i + 1], t); + } + + /** + * Check whether bounding ground motions contain the same: Site classes, IMTs + * per each site class, and ground motions. + * + * @param a static data A + * @param b static B + */ + static void checkBoundingGroundMotion( + StaticData<XySequence> a, + StaticData<XySequence> b) { + checkState(a.size() == b.size(), "Maps are not the same size"); + checkState(a.keySet().containsAll(b.keySet()), "Site classes do not match"); + a.keySet().forEach(key -> checkXySequence(a.get(key), b.get(key))); + } + + /** + * Checks bounding hazard maps contain the same: Site classes, IMTs per each + * site class, and ground motions per each IMT + * + * @param boundingData The bounding ground motions + */ + static void checkBoundingGroundMotions( + BoundingData<XySequence> boundingData, + Location location) { + checkArgument(boundingData.containsKey(location), "Location not in bounding hazards"); + boundingData.keySet().stream() + .filter(loc -> loc.equals(location)) + .forEach(key -> { + checkBoundingGroundMotion(boundingData.get(location), boundingData.get(key)); + }); + } + + /** + * Check that the X values are identical. + * + * @param a Sequence A + * @param b Sequence B + */ + public static void checkXySequence(XySequence a, XySequence b) { + checkState( + Arrays.equals(a.xValues().toArray(), b.xValues().toArray()), + "Hazard curves xValues are not the same"); + } + + /** + * Get a 1D array from a netCDF group. + * + * @param group The netCDF group + * @param key The key to read from the group + * @param dataType The data type to read + * @throws IOException + */ + static Object get1DArray(Group group, String key, DataType dataType) throws IOException { + var var = group.findVariableLocal(key); + checkNotNull( + var, + String.format("Could not find variable [%s] in group [%s]", key, group.getFullName())); + + return var.read().get1DJavaArray(dataType); + } + + /** + * Returns a {@code double[]} from a netCDF group + * + * @param group The netCDF group + * @param key The key to read from the group + * @throws IOException + */ + static double[] getDoubleArray(Group group, String key) throws IOException { + return (double[]) get1DArray(group, key, DataType.DOUBLE); + } + + /* + * find index of first element in a (sorted ascending) that is less than or + * equal to target value t. If target value is equal to the maximum value in a + * (the last element), an index of a.length - 1 is returned. + */ + static int getIdxLTEQ(double[] a, double t) { + // assumes array is in sorted order (a[i] < a[i+1]) + // make sure target is within the range of the array + var n = a.length; + + if (t < a[0] || t > a[n - 1]) { + // should never get here thanks to NshmpNetcdfCoordinates.checkCoords() + throw new IllegalArgumentException( + String.format("Target [%.4f] outside of valid range: %.4f <= t <= %.4f", t, a[0], + a[n - 1])); + } + + // if (t == a[0]) { + if (DoubleMath.fuzzyEquals(a[0], t, LOCATION_TOLERANCE)) { + return 0; + } + // if (t == a[n - 1]) { + if (DoubleMath.fuzzyEquals(a[n - 1], t, LOCATION_TOLERANCE)) { + return n - 2; // return second to last index number + } + + var idx = Arrays.binarySearch(a, t); + if (idx < 0) { + // "exact" match not found, so use index of first value less than target + // this is insertion_point - 1 + // returned idx = -insertion_point - 1 + idx = -1 * (idx + 1) - 1; + // array[idx] <= target + } + + return idx; + } + + /** + * Returns a {@code int[]} from a netCDF group + * + * @param group The netCDF group + * @param key The key to read from the group + * @throws IOException + */ + static int[] getIntArray(Group group, String key) throws IOException { + return (int[]) get1DArray(group, key, DataType.INT); + } + + /** + * Returns a {@code String[]} from a netCDF group + * + * @param group The netCDF group + * @param key The key to read from the group + * @throws IOException + */ + static String[] getStringArray(Group group, String key) throws IOException { + return (String[]) get1DArray(group, key, DataType.STRING); + } + + /* + * Linear interpolation of data values to a target point + */ + static StaticData<XySequence> linearInterpolateGroundMotions( + StaticData<XySequence> v1, + StaticData<XySequence> v2, + double frac) { + checkBoundingGroundMotion(v1, v2); + + var targetMap = StaticData.<XySequence> builder(); + + v1.keySet().forEach(siteClass -> { + var v1Data = v1.get(siteClass).yValues().toArray(); + var v2Data = v2.get(siteClass).yValues().toArray(); + var target = new double[v1Data.length]; + + for (int i = 0; i < v1Data.length; i++) { + target[i] = v1Data[i] * (1 - frac) + v2Data[i] * frac; + } + + var xValues = v1.get(siteClass).xValues().toArray(); + targetMap.put(siteClass, XySequence.create(xValues, target)); + }); + + return targetMap.build(); + } + + public static class Key { + public static final String DESCRIPTION = "description"; + public static final String GRID_STEP = "gridStep"; + public static final String ID = "id"; + public static final String LABEL = "label"; + public static final String DATA_TYPE = "dataType"; + public static final String GROUND_MOTION = "groundMotion"; + public static final String HAZARD = "hazard"; + public static final String HISTORY = "history"; + public static final String IMLS = "iml"; + public static final String IMT = "imt"; + public static final String LAT = "lat"; + public static final String LON = "lon"; + public static final String REGION = "region"; + public static final String SCIENCE_BASE_INFO = "scienceBaseInfo"; + public static final String SITE_CLASS = "siteClass"; + public static final String VS30 = "vs30"; + public static final String YEAR = "year"; + } +} diff --git a/src/lib/src/main/java/gov/usgs/earthquake/nshmp/netcdf/reader/Reader.java b/src/lib/src/main/java/gov/usgs/earthquake/nshmp/netcdf/reader/Reader.java new file mode 100644 index 0000000000000000000000000000000000000000..80f176fe02cb3a9ee6398e51e4b32a64cd4b645a --- /dev/null +++ b/src/lib/src/main/java/gov/usgs/earthquake/nshmp/netcdf/reader/Reader.java @@ -0,0 +1,106 @@ +package gov.usgs.earthquake.nshmp.netcdf.reader; + +import java.io.IOException; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import com.google.common.reflect.TypeToken; +import com.google.gson.Gson; + +import gov.usgs.earthquake.nshmp.Maths; +import gov.usgs.earthquake.nshmp.gmm.Imt; +import gov.usgs.earthquake.nshmp.gmm.NehrpSiteClass; +import gov.usgs.earthquake.nshmp.netcdf.data.NetcdfData; +import gov.usgs.earthquake.nshmp.netcdf.data.NetcdfShape; +import gov.usgs.earthquake.nshmp.netcdf.data.ScienceBaseMetadata; +import gov.usgs.earthquake.nshmp.netcdf.reader.NetcdfUtils.Key; + +import ucar.ma2.DataType; +import ucar.nc2.Group; + +/** + * Read in NetCDF file. + * + * @author U.S. Geological Survey + */ +public abstract class Reader { + + Group targetGroup; + NetcdfData netcdfData; + private NetcdfShape netcdfShape; + + static final String FLAG_KEY = "flag_key"; + static final Gson GSON = new Gson(); + + public Reader(Group targetGroup) throws IOException { + this.targetGroup = targetGroup; + netcdfData = readData(targetGroup); + netcdfShape = buildNetcdfShape(targetGroup); + } + + public NetcdfShape netcdfShape() { + return netcdfShape; + } + + public NetcdfData netcdfData() { + return netcdfData; + } + + abstract NetcdfShape buildNetcdfShape(Group group); + + NetcdfData readData(Group targetGroup) throws IOException { + var vSiteClass = targetGroup.findVariableLocal(Key.SITE_CLASS); + var vImts = targetGroup.findVariableLocal(Key.IMT); + var vVs30 = targetGroup.findVariableLocal(Key.VS30); + var stringStringMapType = new TypeToken<Map<String, String>>() {}.getType(); + + // get list of IMT enums + Map<String, String> imtFlagKeys = GSON + .fromJson(vImts.findAttribute(FLAG_KEY) + .getValues().toString(), stringStringMapType); + var imts = Arrays.stream((int[]) vImts.read().get1DJavaArray(DataType.INT)) + .boxed() + .map(imtInt -> imtFlagKeys.get(Integer.toString((imtInt)))) + .map(imt -> Imt.valueOf(imt)) + .collect(Collectors.toUnmodifiableList()); + + // get list of SiteClass enums + Map<String, String> siteClassFlagKeys = GSON + .fromJson(vSiteClass.findAttribute(FLAG_KEY) + .getValues().toString(), stringStringMapType); + List<NehrpSiteClass> siteClasses = + Arrays.stream((int[]) vSiteClass.read().get1DJavaArray(DataType.INT)).boxed() + .map(siteClassInt -> siteClassFlagKeys.get(Integer.toString(siteClassInt))) + .map(siteClass -> NehrpSiteClass.valueOf(siteClass)) + .collect(Collectors.toUnmodifiableList()); + + // Get vs30 map + Map<String, Double> vs30FlagKeys = GSON + .fromJson(vVs30.findAttribute(FLAG_KEY).getValues().toString(), + new TypeToken<Map<String, Double>>() {}.getType()); + Map<NehrpSiteClass, Double> vs30Map = vs30FlagKeys.entrySet().stream() + .collect(Collectors.toUnmodifiableMap(entry -> NehrpSiteClass.valueOf(entry.getKey()), + Map.Entry::getValue)); + + var latitudes = Arrays.stream(NetcdfUtils.getDoubleArray(targetGroup, Key.LAT)) + // TODO: Dynamic set location precision from NetCDF + .map(lat -> Maths.round(lat, 3)) + .toArray(); + + var longitudes = Arrays.stream(NetcdfUtils.getDoubleArray(targetGroup, Key.LON)) + // TODO: Dynamic set location precision from NetCDF + .map(lon -> Maths.round(lon, 3)) + .toArray(); + + return NetcdfData.builder() + .imts(imts) + .latitudes(latitudes) + .longitudes(longitudes) + .scienceBaseMetadata(new ScienceBaseMetadata(targetGroup)) + .siteClasses(siteClasses) + .vs30Map(vs30Map) + .build(); + } +} diff --git a/src/lib/src/main/java/gov/usgs/earthquake/nshmp/netcdf/www/NetcdfService.java b/src/lib/src/main/java/gov/usgs/earthquake/nshmp/netcdf/www/NetcdfService.java new file mode 100644 index 0000000000000000000000000000000000000000..b3d161ec06019a733abd9551f4f5300011f203f7 --- /dev/null +++ b/src/lib/src/main/java/gov/usgs/earthquake/nshmp/netcdf/www/NetcdfService.java @@ -0,0 +1,228 @@ +package gov.usgs.earthquake.nshmp.netcdf.www; + +import static gov.usgs.earthquake.nshmp.netcdf.www.NetcdfWsUtils.GSON; + +import java.util.Map; +import java.util.logging.Logger; + +import gov.usgs.earthquake.nshmp.Maths; +import gov.usgs.earthquake.nshmp.data.XySequence; +import gov.usgs.earthquake.nshmp.geo.Location; +import gov.usgs.earthquake.nshmp.gmm.NehrpSiteClass; +import gov.usgs.earthquake.nshmp.netcdf.Netcdf; +import gov.usgs.earthquake.nshmp.netcdf.data.ScienceBaseMetadata; +import gov.usgs.earthquake.nshmp.netcdf.www.Query.Service; +import gov.usgs.earthquake.nshmp.netcdf.www.meta.DoubleParameter; +import gov.usgs.earthquake.nshmp.www.Response; + +import io.micronaut.http.HttpRequest; +import io.micronaut.http.HttpResponse; + +/** + * Abstract service handler for {@code NetcdfController}. + * + * @see NetcdfController + * + * @author U.S. Geological Survey + */ +public abstract class NetcdfService { + + protected static final Logger LOGGER = Logger.getLogger(NetcdfService.class.getName()); + + Netcdf<?> netcdf; + + protected NetcdfService(Netcdf<?> netcdf) { + this.netcdf = netcdf; + } + + /** + * Returns the metadata response. + * + * @param httpRequest The HTTP request + */ + abstract Response<String, Metadata> getMetadataResponse(HttpRequest<?> httpRequest); + + /** + * Returns the service name + */ + abstract String getServiceName(); + + /** + * Returns the netcdf object associated with the specific data type. + */ + abstract Netcdf<?> netcdf(); + + /** + * Returns the static curves at a specific location. + * + * @param <T> The response type + * @param request The request data + * @param url The URL for the service call + */ + abstract <T> Response<RequestData, T> processCurves(RequestData request, String url); + + /** + * Returns the static curves at a specific location and site class. + * + * @param <T> The response type + * @param request The request data + * @param url The URL for the service call + */ + abstract <T> Response<RequestDataSiteClass, T> processCurvesSiteClass( + RequestDataSiteClass request, + String url); + + /** + * Process the service request and returns the reponse. + * + * @param httpRequest The HTTP request + * @param query The HTTP query + * @param service The NetCDF service + */ + abstract Response<?, ?> processRequest(HttpRequest<?> httpRequest, Query query, Service service); + + /** + * Handler of HTTP request, returns the service response. + * + * @param httpRequest The HTTP request + * @param query The service query + */ + public HttpResponse<String> handleServiceCall(HttpRequest<?> httpRequest, Query query) { + try { + var url = httpRequest.getUri().toString(); + LOGGER.info("Request: " + url); + LOGGER.fine("Query:\n" + GSON.toJson(query)); + + if (query.longitude == null && query.latitude == null) { + return metadata(httpRequest); + } + var service = getService(query); + Response<?, ?> svcResponse = processRequest(httpRequest, query, service); + var response = GSON.toJson(svcResponse); + LOGGER.fine("Result:\n" + response); + return HttpResponse.ok(response); + } catch (Exception e) { + var url = httpRequest.getUri().toString(); + return NetcdfWsUtils.handleError(e, getServiceName(), url); + } + } + + private Service getService(Query query) { + if (query.siteClass != null) { + return Service.CURVES_BY_SITE_CLASS; + } else { + return Service.CURVES; + } + } + + private HttpResponse<String> metadata(HttpRequest<?> httpRequest) { + var svcResponse = getMetadataResponse(httpRequest); + var response = GSON.toJson(svcResponse); + LOGGER.fine("Result:\n" + response); + return HttpResponse.ok(response); + } + + class Metadata { + final String description; + final String[] syntax; + final SourceModel model; + final DoubleParameter longitude; + final DoubleParameter latitude; + final DoubleParameter vs30; + final NetcdfMetadata netcdfMetadata; + + Metadata(HttpRequest<?> request, String description) { + var url = request.getUri().toString(); + url = url.endsWith("/") ? url.substring(0, url.length() - 1) : url; + this.description = description; + syntax = new String[] { + url + "/{longitude:number}/{latitude:number}", + url + "?longitude={number}&latitude={number}", + url + "/{longitude:number}/{latitude:number}/{siteClass:NehrpSiteClass}", + url + "?longitude={number}&latitude={number}&siteClass={NehrpSiteClass}", + }; + + var bounds = netcdf().netcdfData().bounds(); + longitude = new DoubleParameter( + "Longitude", + "°", + Maths.round(bounds.min.longitude, 3), + Maths.round(bounds.max.longitude, 3)); + latitude = new DoubleParameter( + "Latitude", + "°", + Maths.round(bounds.min.latitude, 3), + Maths.round(bounds.max.latitude, 3)); + model = new SourceModel(); + vs30 = new DoubleParameter( + "Vs30", + "m/s", + 150, + 1500); + netcdfMetadata = new NetcdfMetadata(); + } + } + + class NetcdfMetadata { + final String netcdfFile; + final ScienceBaseMetadata scienceBaseMetadata; + + NetcdfMetadata() { + var fileName = netcdf.netcdfPath().getFileName(); + netcdfFile = fileName == null ? netcdf().netcdfPath().toString() : fileName.toString(); + scienceBaseMetadata = netcdf().netcdfData().scienceBaseMetadata(); + } + } + + class SourceModel { + final String name; + final Map<NehrpSiteClass, Double> siteClasses; + + SourceModel() { + name = netcdf().netcdfData().scienceBaseMetadata().label; + siteClasses = netcdf().netcdfData().vs30Map(); + } + } + + static class ResponseMetadata extends RequestDataSiteClass { + final String xLabel; + final String yLabel; + + ResponseMetadata( + String xLabel, + String yLabel, + Location site, + NehrpSiteClass siteClass) { + super(site, siteClass); + this.xLabel = xLabel; + this.yLabel = yLabel; + } + } + + static class ResponseData<T extends ResponseMetadata> { + final T metadata; + final XySequence data; + + ResponseData(T metadata, XySequence data) { + this.metadata = metadata; + this.data = data; + } + } + + static class RequestData { + Location site; + + RequestData(Location site) { + this.site = site; + } + } + + static class RequestDataSiteClass extends RequestData { + NehrpSiteClass siteClass; + + RequestDataSiteClass(Location site, NehrpSiteClass siteClass) { + super(site); + this.siteClass = siteClass; + } + } +} diff --git a/src/lib/src/main/java/gov/usgs/earthquake/nshmp/netcdf/www/NetcdfWsUtils.java b/src/lib/src/main/java/gov/usgs/earthquake/nshmp/netcdf/www/NetcdfWsUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..79dafabeadec0284ad344845b51910568287f8f0 --- /dev/null +++ b/src/lib/src/main/java/gov/usgs/earthquake/nshmp/netcdf/www/NetcdfWsUtils.java @@ -0,0 +1,79 @@ +package gov.usgs.earthquake.nshmp.netcdf.www; + +import static com.google.common.base.CaseFormat.UPPER_CAMEL; +import static com.google.common.base.CaseFormat.UPPER_UNDERSCORE; + +import java.lang.reflect.Type; +import java.util.logging.Logger; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonSerializationContext; +import com.google.gson.JsonSerializer; + +import gov.usgs.earthquake.nshmp.Maths; +import gov.usgs.earthquake.nshmp.geo.Location; +import gov.usgs.earthquake.nshmp.gmm.Imt; +import gov.usgs.earthquake.nshmp.gmm.NehrpSiteClass; +import gov.usgs.earthquake.nshmp.www.Response; +import gov.usgs.earthquake.nshmp.www.WsUtils.EnumSerializer; +import gov.usgs.earthquake.nshmp.www.WsUtils.NaNSerializer; +import gov.usgs.earthquake.nshmp.www.meta.Status; + +import io.micronaut.http.HttpResponse; + +public class NetcdfWsUtils { + static final Gson GSON; + + private static final Logger LOGGER = Logger.getLogger(NetcdfWsUtils.class.getName()); + + static { + GSON = new GsonBuilder() + .registerTypeAdapter(Imt.class, new EnumSerializer<Imt>()) + .registerTypeAdapter(NehrpSiteClass.class, new EnumSerializer<NehrpSiteClass>()) + .registerTypeAdapter(Double.class, new NaNSerializer()) + .registerTypeAdapter(Location.class, new LocationSerializer()) + .disableHtmlEscaping() + .serializeNulls() + .setPrettyPrinting() + .create(); + } + + public static HttpResponse<String> handleError( + Throwable e, + String name, + String url) { + var msg = e.getMessage() + " (see logs)"; + var svcResponse = new Response<>(Status.ERROR, name, url, msg, url); + var response = GSON.toJson(svcResponse); + LOGGER.severe(name + " -\n" + response); + e.printStackTrace(); + return HttpResponse.serverError(response); + } + + static enum Key { + LATITUDE, + LONGITUDE, + SITE_CLASS, + IMT; + + @Override + public String toString() { + return UPPER_UNDERSCORE.to(UPPER_CAMEL, name()); + } + } + + public static final class LocationSerializer implements JsonSerializer<Location> { + + @Override + public JsonElement serialize(Location location, Type type, JsonSerializationContext context) { + JsonObject jObj = new JsonObject(); + jObj.addProperty("longitude", Maths.round(location.longitude, 5)); + jObj.addProperty("latitude", Maths.round(location.latitude, 5)); + + return jObj; + } + } +} diff --git a/src/lib/src/main/java/gov/usgs/earthquake/nshmp/netcdf/www/Query.java b/src/lib/src/main/java/gov/usgs/earthquake/nshmp/netcdf/www/Query.java new file mode 100644 index 0000000000000000000000000000000000000000..c1a5bffee4dfabd6cde7fcfa6293257ba248959d --- /dev/null +++ b/src/lib/src/main/java/gov/usgs/earthquake/nshmp/netcdf/www/Query.java @@ -0,0 +1,21 @@ +package gov.usgs.earthquake.nshmp.netcdf.www; + +import gov.usgs.earthquake.nshmp.gmm.NehrpSiteClass; + +public class Query { + public final Double longitude; + public final Double latitude; + public final NehrpSiteClass siteClass; + + public Query(Double longitude, Double latitude, NehrpSiteClass siteClass) { + this.longitude = longitude; + this.latitude = latitude; + this.siteClass = siteClass; + } + + public static enum Service { + BOUNDING, + CURVES, + CURVES_BY_SITE_CLASS, + } +} diff --git a/src/lib/src/main/java/gov/usgs/earthquake/nshmp/netcdf/www/SwaggerController.java b/src/lib/src/main/java/gov/usgs/earthquake/nshmp/netcdf/www/SwaggerController.java new file mode 100644 index 0000000000000000000000000000000000000000..ec3e9dfc765f07f26416d4678e715ac009e5720c --- /dev/null +++ b/src/lib/src/main/java/gov/usgs/earthquake/nshmp/netcdf/www/SwaggerController.java @@ -0,0 +1,46 @@ +package gov.usgs.earthquake.nshmp.netcdf.www; + +import java.nio.charset.StandardCharsets; +import java.util.stream.Collectors; + +import com.google.common.io.Resources; + +import gov.usgs.earthquake.nshmp.www.NshmpMicronautServlet; + +import io.micronaut.http.HttpRequest; +import io.micronaut.http.HttpResponse; +import io.micronaut.http.MediaType; +import io.micronaut.http.annotation.Controller; +import io.micronaut.http.annotation.Get; +import io.swagger.v3.oas.annotations.Hidden; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.inject.Inject; + +/** + * Expose OpenAPI YAML file. + * + * @author U.S. Geological Survey + */ +@Tag( + name = "Swagger", + description = "Swagger OpenAPI YAML") +@Hidden +@Controller("/swagger") +public class SwaggerController { + + @Inject + private NshmpMicronautServlet servlet; + + @Get(produces = MediaType.TEXT_EVENT_STREAM) + public HttpResponse<String> doGet(HttpRequest<?> request) { + try { + var url = Resources.getResource("META-INF/swagger/nshmp-ws-static.yml"); + var yml = Resources.readLines(url, StandardCharsets.UTF_8) + .stream() + .collect(Collectors.joining("\n")); + return HttpResponse.ok(yml); + } catch (Exception e) { + return NetcdfWsUtils.handleError(e, "Swagger", request.getUri().getPath()); + } + } +} diff --git a/src/lib/src/main/java/gov/usgs/earthquake/nshmp/netcdf/www/meta/DoubleParameter.java b/src/lib/src/main/java/gov/usgs/earthquake/nshmp/netcdf/www/meta/DoubleParameter.java new file mode 100644 index 0000000000000000000000000000000000000000..6a4bd319d258a4b28f2a585c7231213739de187d --- /dev/null +++ b/src/lib/src/main/java/gov/usgs/earthquake/nshmp/netcdf/www/meta/DoubleParameter.java @@ -0,0 +1,16 @@ +package gov.usgs.earthquake.nshmp.netcdf.www.meta; + +public final class DoubleParameter { + + private final String name; + private final String units; + private final double min; + private final double max; + + public DoubleParameter(String name, String units, double min, double max) { + this.name = name; + this.units = units; + this.min = min; + this.max = max; + } +} diff --git a/src/lib/src/main/resources/application.yml b/src/lib/src/main/resources/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..448a7d535a1b583240dcdbd0dacac534c08ad192 --- /dev/null +++ b/src/lib/src/main/resources/application.yml @@ -0,0 +1,17 @@ +micronaut: + io: + watch: + paths: src + restart: true + router: + static-resources: + swagger: + enabled: true + paths: classpath:swagger + mapping: /** + +nshmp-ws-static: + # Hazard example + netcdf-file: ${netcdf:src/main/resources/hazard-example.nc} + # Ground motions example + # netcdf-file: ${netcdf:src/main/resources/rtsa-example.nc} diff --git a/src/lib/src/main/resources/eclipse.importorder b/src/lib/src/main/resources/eclipse.importorder new file mode 100644 index 0000000000000000000000000000000000000000..2ef1b480f52563e1089abcb404d3476e8a89931b --- /dev/null +++ b/src/lib/src/main/resources/eclipse.importorder @@ -0,0 +1,7 @@ +#Organize Import Order +0=java +1=javax +2=org +3=com +4=gov +5=ucar diff --git a/src/lib/src/main/resources/hazard-example.nc b/src/lib/src/main/resources/hazard-example.nc new file mode 100644 index 0000000000000000000000000000000000000000..521866c0689b6ad029a2bfd7f3461ad9e69363f4 Binary files /dev/null and b/src/lib/src/main/resources/hazard-example.nc differ diff --git a/src/lib/src/main/resources/logback.xml b/src/lib/src/main/resources/logback.xml new file mode 100644 index 0000000000000000000000000000000000000000..f74e41693090ae1b24cabe0642f4ec814564c4a1 --- /dev/null +++ b/src/lib/src/main/resources/logback.xml @@ -0,0 +1,17 @@ +<configuration> + + <appender name="STDOUT" + class="ch.qos.logback.core.ConsoleAppender"> + <withJansi>true</withJansi> + <!-- encoders are assigned the type ch.qos.logback.classic.encoder.PatternLayoutEncoder + by default --> + <encoder> + <pattern>%cyan(%d{HH:mm:ss.SSS}) %gray([%thread]) + %highlight(%-5level) %magenta(%logger{36}) - %msg%n</pattern> + </encoder> + </appender> + + <root level="info"> + <appender-ref ref="STDOUT" /> + </root> +</configuration> diff --git a/src/lib/src/main/resources/nshmp.eclipse-format.xml b/src/lib/src/main/resources/nshmp.eclipse-format.xml new file mode 100644 index 0000000000000000000000000000000000000000..181dbd16d380cb5688372df1ca124177b8c583f0 --- /dev/null +++ b/src/lib/src/main/resources/nshmp.eclipse-format.xml @@ -0,0 +1,916 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<profiles version="13"> + <profile kind="CodeFormatterProfile" name="nshmp" version="13"> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_after_ellipsis" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment" + value="common_lines" /> + <setting + id="org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries" + value="true" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation" + value="common_lines" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.blank_lines_after_imports" + value="1" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement" + value="common_lines" /> + <setting + id="org.eclipse.jdt.core.formatter.comment.format_javadoc_comments" + value="true" /> + <setting id="org.eclipse.jdt.core.formatter.indentation.size" + value="2" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration" + value="common_lines" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for" + value="insert" /> + <setting id="org.eclipse.jdt.core.formatter.disabling_tag" + value="@formatter:off" /> + <setting + id="org.eclipse.jdt.core.formatter.continuation_indentation" + value="2" /> + <setting + id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" + value="81" /> + <setting + id="org.eclipse.jdt.core.formatter.blank_lines_before_imports" + value="1" /> + <setting + id="org.eclipse.jdt.core.formatter.blank_lines_after_package" + value="1" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_after_binary_operator" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement" + value="common_lines" /> + <setting + id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant" + value="16" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.comment.indent_root_tags" + value="true" /> + <setting + id="org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch" + value="true" /> + <setting id="org.eclipse.jdt.core.formatter.enabling_tag" + value="@formatter:on" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.comment.count_line_length_from_starting_position" + value="false" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" + value="16" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line" + value="false" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations" + value="2" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references" + value="0" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column" + value="false" /> + <setting + id="org.eclipse.jdt.core.compiler.problem.enumIdentifier" + value="error" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_block" + value="true" /> + <setting + id="org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration" + value="end_of_line" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.comment.line_length" value="80" /> + <setting id="org.eclipse.jdt.core.formatter.use_on_off_tags" + value="true" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments" + value="false" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.brace_position_for_method_declaration" + value="end_of_line" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch" + value="16" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body" + value="0" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line" + value="false" /> + <setting + id="org.eclipse.jdt.core.formatter.alignment_for_binary_expression" + value="16" /> + <setting + id="org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause" + value="common_lines" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call" + value="16" /> + <setting + id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header" + value="true" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.brace_position_for_block" + value="end_of_line" /> + <setting + id="org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration" + value="end_of_line" /> + <setting + id="org.eclipse.jdt.core.formatter.brace_position_for_lambda_body" + value="end_of_line" /> + <setting id="org.eclipse.jdt.core.formatter.compact_else_if" + value="true" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line" + value="false" /> + <setting + id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration" + value="16" /> + <setting + id="org.eclipse.jdt.core.formatter.alignment_for_type_parameters" + value="0" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation" + value="16" /> + <setting + id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration" + value="16" /> + <setting + id="org.eclipse.jdt.core.compiler.problem.assertIdentifier" + value="error" /> + <setting + id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment" + value="false" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment" + value="false" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_binary_operator" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_unary_operator" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer" + value="32" /> + <setting + id="org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column" + value="true" /> + <setting + id="org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve" + value="1" /> + <setting + id="org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation" + value="common_lines" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_ellipsis" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.comment.format_line_comments" + value="true" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.align_type_members_on_columns" + value="false" /> + <setting + id="org.eclipse.jdt.core.formatter.alignment_for_assignment" + value="80" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header" + value="true" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration" + value="80" /> + <setting + id="org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration" + value="0" /> + <setting + id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression" + value="16" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line" + value="false" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration" + value="end_of_line" /> + <setting + id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case" + value="end_of_line" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.comment.format_header" + value="true" /> + <setting + id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression" + value="16" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while" + value="insert" /> + <setting + id="org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode" + value="enabled" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.alignment_for_method_declaration" + value="0" /> + <setting + id="org.eclipse.jdt.core.formatter.join_wrapped_lines" value="false" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.wrap_before_conditional_operator" + value="true" /> + <setting + id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases" + value="true" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines" + value="2147483647" /> + <setting + id="org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries" + value="true" /> + <setting + id="org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration" + value="end_of_line" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.alignment_for_resources_in_try" + value="80" /> + <setting + id="org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations" + value="false" /> + <setting + id="org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause" + value="common_lines" /> + <setting + id="org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation" + value="16" /> + <setting + id="org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column" + value="false" /> + <setting id="org.eclipse.jdt.core.compiler.source" value="1.8" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws" + value="insert" /> + <setting id="org.eclipse.jdt.core.formatter.tabulation.size" + value="2" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.comment.format_source_code" + value="true" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.blank_lines_before_field" + value="0" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer" + value="2" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.blank_lines_before_method" + value="1" /> + <setting + id="org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration" + value="80" /> + <setting + id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration" + value="80" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.wrap_before_assignment_operator" + value="false" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.compiler.codegen.targetPlatform" value="1.8" /> + <setting + id="org.eclipse.jdt.core.formatter.brace_position_for_switch" + value="end_of_line" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.comment.format_html" value="false" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration" + value="common_lines" /> + <setting + id="org.eclipse.jdt.core.formatter.alignment_for_compact_if" + value="16" /> + <setting + id="org.eclipse.jdt.core.formatter.indent_empty_lines" value="false" /> + <setting + id="org.eclipse.jdt.core.formatter.alignment_for_type_arguments" + value="0" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_after_unary_operator" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation" + value="16" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line" + value="true" /> + <setting + id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch" + value="true" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk" + value="1" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_new_line_after_label" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header" + value="true" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.blank_lines_before_member_type" + value="1" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression" + value="16" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases" + value="true" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.comment.format_block_comments" + value="true" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line" + value="true" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration" + value="16" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_body" + value="true" /> + <setting + id="org.eclipse.jdt.core.formatter.alignment_for_multiple_fields" + value="16" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.brace_position_for_array_initializer" + value="end_of_line" /> + <setting + id="org.eclipse.jdt.core.formatter.wrap_before_binary_operator" + value="false" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch" + value="do not insert" /> + <setting id="org.eclipse.jdt.core.compiler.compliance" + value="1.8" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration" + value="common_lines" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested" + value="true" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.brace_position_for_enum_constant" + value="end_of_line" /> + <setting + id="org.eclipse.jdt.core.formatter.brace_position_for_type_declaration" + value="end_of_line" /> + <setting + id="org.eclipse.jdt.core.formatter.blank_lines_before_package" + value="0" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header" + value="0" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header" + value="true" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.join_lines_in_comments" + value="true" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional" + value="insert" /> + <setting + id="org.eclipse.jdt.core.formatter.comment.indent_parameter_description" + value="false" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement" + value="do not insert" /> + <setting id="org.eclipse.jdt.core.formatter.tabulation.char" + value="space" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.blank_lines_between_import_groups" + value="1" /> + <setting id="org.eclipse.jdt.core.formatter.lineSplit" + value="100" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation" + value="do not insert" /> + <setting + id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch" + value="insert" /> + </profile> +</profiles> diff --git a/src/lib/src/main/resources/rtsa-example.nc b/src/lib/src/main/resources/rtsa-example.nc new file mode 100644 index 0000000000000000000000000000000000000000..0b4e8d883e15107bd60ed7fc8bde3a9da0066427 Binary files /dev/null and b/src/lib/src/main/resources/rtsa-example.nc differ diff --git a/src/lib/src/main/resources/swagger/favicon.ico b/src/lib/src/main/resources/swagger/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..0c3e87c87b8ecc9900a3b6368598be574e9d0716 Binary files /dev/null and b/src/lib/src/main/resources/swagger/favicon.ico differ diff --git a/src/lib/src/main/resources/swagger/index.css b/src/lib/src/main/resources/swagger/index.css new file mode 100644 index 0000000000000000000000000000000000000000..65f90aca32b0c4145e7f2e7fa437cb2448e84b59 --- /dev/null +++ b/src/lib/src/main/resources/swagger/index.css @@ -0,0 +1,73 @@ +html, +body { + height: 100%; + overflow: hidden; +} + +body { + color: #333; + font-family: 'Roboto', 'Helvetica Neue', Helvetica, Arial, sans-serif; + margin: 0; + overflow: scroll; +} + +#swagger-ui { + padding-top: 1em; + padding-bottom: 50px; +} + +.nshmp-template-header, +.nshmp-template-footer { + background-color: #3d5e80; + box-shadow: 0 1px 8px rgba(0, 0, 0, 0.5); + height: 30px; + padding: 10px; + position: fixed; + width: 100vw; + z-index: 4; +} + +/* ---- Header ---- */ + +.nshmp-template-header { + top: 0; +} + +.nshmp-template-header .nshmp-template-header--logo { + height: 28px; + overflow: hidden; + +} + +.nshmp-template-header--logo .usgs-logo { + display: inline-block; + height: 100%; + position: relative; + +} + +.nshmp-template-header--logo .usgs-logo img { + border: none; + height: 140%; + max-width: 100%; +} + +/* ---- Footer ---- */ + +.nshmp-template-footer { + bottom: 0; + font-size: large; + text-align: center; +} + +.nshmp-template-footer a { + color: white; + cursor: pointer; + line-height: 30px; + padding: 0 1em; + text-decoration: none; +} + +.nshmp-template-footer a:visited { + color: white; +} diff --git a/src/lib/src/main/resources/swagger/index.html b/src/lib/src/main/resources/swagger/index.html new file mode 100644 index 0000000000000000000000000000000000000000..5bd722b5c63c977af1306b9b58e7b4d85308c8b3 --- /dev/null +++ b/src/lib/src/main/resources/swagger/index.html @@ -0,0 +1,54 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <title>NSHMP Static Data Services</title> + <meta charset="UTF-8" /> + <link + rel="icon" + type="image/x-icon" + href="favicon.ico" + /> + <script src="https://unpkg.com/swagger-ui-dist/swagger-ui-bundle.js"></script> + <script src="https://unpkg.com/swagger-ui-dist/swagger-ui-standalone-preset.js"></script> + <link + rel="stylesheet" + type="text/css" + href="https://unpkg.com/swagger-ui-dist/swagger-ui.css" + /> + <link + rel="stylesheet" + type="text/css" + href="https://unpkg.com/swagger-ui-themes@3.0.0/themes/3.x/theme-material.css" + /> + <link + rel="stylesheet" + type="text/css" + href="index.css" + /> + </head> + + <body> + <header class="nshmp-template-header"> + <div class="nshmp-template-header--logo"> + <a href="" class="usgs-logo"> + <img alt="USGS" src="usgs-logo.svg" /> + </a> + </div> + </header> + + <div id="swagger-ui"></div> + + <footer class="nshmp-template-footer"> + <a href="https://code.usgs.gov/ghsc/nshmp/nshmp-ws-static/-/blob/main/LICENSE.md"> + License + </a> + + <a href="https://code.usgs.gov/ghsc/nshmp/nshmp-ws-static/-/blob/main/DISCLAIMER.md"> + Disclaimer + </a> + + </footer> + + <script src="index.js"></script> + </body> +</html> diff --git a/src/lib/src/main/resources/swagger/index.js b/src/lib/src/main/resources/swagger/index.js new file mode 100644 index 0000000000000000000000000000000000000000..06e5a1326e3df94485c3d6879f3d3d773b4dcecf --- /dev/null +++ b/src/lib/src/main/resources/swagger/index.js @@ -0,0 +1,38 @@ +window.onload = function() { + let contextPath = window.location.pathname; + contextPath = contextPath.endsWith('/') ? contextPath.slice(0, -1) : contextPath; + + const ui = SwaggerUIBundle({ + url: `./swagger`, + dom_id: '#swagger-ui', + tagsSorter: 'alpha', + presets: [SwaggerUIBundle.presets.apis, SwaggerUIStandalonePreset], + plugins: [SwaggerUIBundle.plugins.DownloadUrl, updateContextPath(contextPath)], + validatorUrl: null, + deepLinking: true + }); + + window.ui = ui; +}; + +function updateContextPath(contextPath) { + return { + statePlugins: { + spec: { + wrapActions: { + updateJsonSpec: (oriAction) => (...args) => { + const [spec] = args; + if (spec && spec.paths) { + const newPaths = {}; + Object.entries(spec.paths).forEach( + ([path, value]) => (newPaths[contextPath + path] = value) + ); + spec.paths = newPaths; + } + oriAction(...args); + }, + }, + }, + }, + }; +} diff --git a/src/lib/src/main/resources/swagger/usgs-logo.svg b/src/lib/src/main/resources/swagger/usgs-logo.svg new file mode 100644 index 0000000000000000000000000000000000000000..d33f18c4c10451bc3a3540afabb67f420775b8cf --- /dev/null +++ b/src/lib/src/main/resources/swagger/usgs-logo.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="2353" height="869" viewBox="40.2 28.7 2353.3 869.2"><style>.a{fill:#FFF;}</style><path d="M1135.8 38.7v425.7c0 89.8-50.7 184.6-203.7 184.6 -138 0-204.6-71.5-204.6-184.6V38.7h125.6v417.4c0 74 31.6 103.1 77.3 103.1 54.9 0 79.8-36.6 79.8-103.1V38.7H1135.8z" class="a"/><path d="M1339.9 649c-155.5 0-184.6-91.5-177.9-195.4h125.6c0 57.4 2.5 105.6 71.5 105.6 42.4 0 63.2-27.4 63.2-68.2 0-108.1-252.8-114.7-252.8-293.5 0-94 44.9-168.8 197.9-168.8 122.2 0 182.9 54.9 174.6 180.4h-122.2c0-44.9-7.5-90.6-58.2-90.6 -40.7 0-64.8 22.5-64.8 64 0 113.9 252.8 103.9 252.8 292.7C1549.5 630.7 1435.6 649 1339.9 649z" class="a"/><path d="M2184 649c-155.5 0-184.6-91.5-177.9-195.4h125.6c0 57.4 2.5 105.6 71.5 105.6 42.4 0 63.2-27.4 63.2-68.2 0-108.1-252.8-114.7-252.8-293.5 0-94 44.9-168.8 197.9-168.8 122.2 0 182.9 54.9 174.6 180.4h-122.2c0-44.9-7.5-90.6-58.2-90.6 -40.7 0-64.9 22.5-64.9 64 0 113.9 252.8 103.9 252.8 292.7C2393.6 630.7 2279.6 649 2184 649z" class="a"/><path d="M1784 415.3h73.9v132.5l-6.1 2.3c-19.1 6.7-41.6 11.6-62.4 11.6 -71.5 0-89.8-33.3-89.8-221.2 0-116.4 0-222 78.2-222 60.8 0 73.6 41 74.8 90.6h125.1c1-116.5-74-180.4-192.3-180.4 -205.4 0-212.9 153.8-212.9 305.2 0 227.8 24.7 316.2 235.9 316.2 49 0 127-11.1 163-20.9 2.2-0.6 6.1-3 6.1-6.1 0-16.4 0-298.4 0-298.4h-193.3V415.3L1784 415.3z" class="a"/><path d="M71.3 823.1c-1.2 4.8-2 9.5-1.2 12.8 1 3.4 3.8 5 9.6 5s11.7-3.8 13.2-10.9c4.8-22.5-48.3-17.4-41.2-51.2 4.9-22.9 29-29.8 48.1-29.8 20.1 0 36.3 9.7 29.8 32.5h-29c1.6-7.3 1.7-11.7 0-13.6 -1.5-1.9-3.9-2.3-7.1-2.3 -6.5 0-11 4.2-12.5 11.3 -3.6 16.8 48.7 15.9 41.4 49.9 -3.9 18.5-22 32.3-46.5 32.3 -25.8 0-41.6-6.5-33.7-36.1H71.3L71.3 823.1z" class="a"/><path d="M197.9 789c3.3-15.7 0.5-21-8.8-21 -12.6 0-16 11.1-20.7 33.2 -6.9 32.3-5.6 39.2 5.3 39.2 9.2 0 15.4-8.4 18.4-22.2h29.6c-6.1 28.7-24.3 41.1-52 41.1 -38.2 0-38.3-23.3-31.2-56.4 6.2-28.9 15.6-53.7 54.6-53.7 27.3 0 40.2 12.2 34.3 39.9H197.9z" class="a"/><path d="M258.7 857.1h-29.6l22.5-106h29.6L258.7 857.1zM289.9 710.4l-5 23.3H255.4l5-23.3H289.9z" class="a"/><path d="M1643.2 857.1h-29.6l22.5-106h29.6L1643.2 857.1zM1674.4 710.4l-5 23.3h-29.6l4.9-23.3H1674.4z" class="a"/><path d="M315.8 808.9c-2.7 12.6-6.3 31.5 6.7 31.5 10.5 0 14.7-10.1 16.6-18.9h30c-2.9 11.5-8.7 21-17.2 27.5 -8.3 6.5-19.6 10.3-33.5 10.3 -38.2 0-38.3-23.3-31.2-56.4 6.2-28.9 15.6-53.7 54.6-53.7 39.9 0 38.8 25.8 30.5 59.8H315.8zM346.4 792.3c2.2-10.3 5.7-25-8.3-25 -13.6 0-16.8 15.9-18.7 25H346.4z" class="a"/><path d="M428.3 761.9h0.4c7.9-9.4 16.6-12.8 27.7-12.8 14.1 0 24.7 8.4 21.5 23.1l-18.1 85h-29.6l15.5-73c2-9.4 1.9-16.8-7.6-16.8 -9.4 0-12.7 7.3-14.7 16.8l-15.5 73H378.4l22.5-106h29.6L428.3 761.9z" class="a"/><path d="M545.7 789c3.3-15.7 0.5-21-8.8-21 -12.6 0-16 11.1-20.7 33.2 -6.9 32.3-5.6 39.2 5.3 39.2 9.2 0 15.4-8.4 18.4-22.2h29.6c-6.1 28.7-24.3 41.1-52 41.1 -38.2 0-38.3-23.3-31.2-56.4 6.2-28.9 15.6-53.7 54.6-53.7 27.3 0 40.2 12.2 34.3 39.9H545.7z" class="a"/><path d="M613.3 808.9c-2.7 12.6-6.3 31.5 6.7 31.5 10.5 0 14.7-10.1 16.6-18.9h30c-2.9 11.5-8.7 21-17.2 27.5 -8.3 6.5-19.6 10.3-33.5 10.3 -38.2 0-38.3-23.3-31.2-56.4 6.2-28.9 15.6-53.7 54.6-53.7 39.9 0 38.8 25.8 30.5 59.8H613.3zM643.9 792.3c2.2-10.3 5.7-25-8.3-25 -13.6 0-16.8 15.9-18.7 25H643.9z" class="a"/><path d="M794.1 729.3c-11.8-0.8-15.3 3.8-17.6 14.5l-2.1 7.4h13.8l-3.9 18.3h-13.8l-18.6 87.7h-29.6l18.6-87.7h-13.2l3.9-18.3h13.4c5.9-26.5 11.3-41.2 42.6-41.2 3.6 0 6.9 0.2 10.4 0.4L794.1 729.3z" class="a"/><path d="M784.8 802.8c6.2-28.9 15.6-53.7 54.6-53.7 39 0 38 24.8 31.8 53.7 -7 33.2-17 56.4-55.2 56.4C777.8 859.2 777.7 836 784.8 802.8zM842 801.1c4.7-22 6-33.2-6.6-33.2 -12.6 0-16 11.1-20.7 33.2 -6.9 32.3-5.6 39.2 5.3 39.2C830.9 840.4 835.1 833.4 842 801.1z" class="a"/><path d="M924.3 751.2l-2.9 13.6h0.4c8-12.2 18.9-15.7 30.8-15.7l-5.6 26.4c-25.7-1.7-29.3 13.4-31.5 23.9l-12.3 57.7h-29.6l22.5-106h28.1V751.2z" class="a"/><path d="M1065.3 837.4c-1.4 6.5-2 13.2-2.7 19.7h-27.5l1.7-14.1h-0.4c-8.6 10.9-18.3 16.2-31.1 16.2 -20.6 0-24.9-15.3-20.9-33.8 7.5-35 34.8-36.5 62.2-36.1l1.7-8.2c1.9-9 2-15.5-8.7-15.5 -10.3 0-12.8 7.8-14.6 16.2h-29c2.7-12.8 8.4-21 16.4-25.8 7.8-5 17.8-6.9 29.2-6.9 37.6 0 39 16.2 34.8 35.5L1065.3 837.4zM1013.5 824.2c-1.6 7.6-2.3 16.8 7.3 16.8 17.4 0 19.7-23.5 22.1-35C1028.2 806.6 1017.5 805.3 1013.5 824.2z" class="a"/><path d="M1182.4 789c3.3-15.7 0.5-21-8.8-21 -12.6 0-16 11.1-20.7 33.2 -6.9 32.3-5.6 39.2 5.3 39.2 9.2 0 15.4-8.4 18.4-22.2h29.6c-6.1 28.7-24.3 41.1-52 41.1 -38.2 0-38.3-23.3-31.2-56.4 6.2-28.9 15.6-53.7 54.6-53.7 27.3 0 40.2 12.2 34.3 39.9H1182.4z" class="a"/><path d="M1396.7 837.4c-1.4 6.5-2 13.2-2.7 19.7h-27.5l1.7-14.1h-0.4c-8.6 10.9-18.3 16.2-31.1 16.2 -20.6 0-24.9-15.3-20.9-33.8 7.5-35 34.8-36.5 62.2-36.1l1.7-8.2c1.9-9 2-15.5-8.7-15.5 -10.3 0-12.8 7.8-14.6 16.2h-29c2.7-12.8 8.5-21 16.4-25.8 7.8-5 17.8-6.9 29.2-6.9 37.6 0 38.9 16.2 34.8 35.5L1396.7 837.4zM1344.9 824.2c-1.6 7.6-2.3 16.8 7.3 16.8 17.4 0 19.7-23.5 22.1-35C1359.6 806.6 1348.9 805.3 1344.9 824.2z" class="a"/><path d="M1461.6 761.9h0.4c7.9-9.4 16.6-12.8 27.7-12.8 14.1 0 24.7 8.4 21.5 23.1l-18.1 85h-29.6l15.5-73c2-9.4 1.9-16.8-7.6-16.8 -9.4 0-12.7 7.3-14.7 16.8l-15.5 73h-29.6l22.5-106h29.6L1461.6 761.9z" class="a"/><path d="M1614.9 751.2l-23.5 110.4c-1.6 7.3-7.3 36.3-48 36.3 -22 0-39.7-5.7-34.9-31.5h29c-0.9 4.4-1.1 8.2 0.2 10.7 1.3 2.7 4.4 4.2 9 4.2 7.3 0 12.4-6.9 14.7-17.6l4.3-20.4h-0.4c-6.1 8.2-15.4 12.4-25.1 12.4 -32.5 0-24.7-29.8-19.6-53.7 5-23.3 11.7-52.9 42.5-52.9 10.5 0 18.5 4.6 20.6 14.5h0.4l2.6-12.4H1614.9zM1554.9 837.4c10.7 0 14.5-11.1 19.3-33.6 4.9-23.3 6.7-36.5-4.2-36.5 -11.1 0-14.7 7.8-21.5 40.1C1546.3 817.3 1540.6 837.4 1554.9 837.4z" class="a"/><path d="M1714 761.9h0.4c7.9-9.4 16.6-12.8 27.7-12.8 14.1 0 24.7 8.4 21.5 23.1l-18.1 85h-29.6l15.5-73c2-9.4 1.9-16.8-7.6-16.8 -9.4 0-12.7 7.3-14.7 16.8l-15.5 73h-29.6l22.5-106h29.6L1714 761.9z" class="a"/><path d="M1867.3 751.2l-23.5 110.4c-1.6 7.3-7.3 36.3-48 36.3 -22 0-39.7-5.7-34.8-31.5h29c-0.9 4.4-1.1 8.2 0.2 10.7 1.3 2.7 4.4 4.2 9 4.2 7.3 0 12.4-6.9 14.7-17.6l4.3-20.4h-0.4c-6.1 8.2-15.4 12.4-25.1 12.4 -32.5 0-24.7-29.8-19.6-53.7 4.9-23.3 11.7-52.9 42.5-52.9 10.5 0 18.5 4.6 20.6 14.5h0.4l2.6-12.4H1867.3zM1807.2 837.4c10.7 0 14.5-11.1 19.3-33.6 5-23.3 6.7-36.5-4.2-36.5 -11.1 0-14.7 7.8-21.5 40.1C1798.7 817.3 1793 837.4 1807.2 837.4z" class="a"/><path d="M1913.5 751.2h29.4l-2.4 79.7h0.4l35.3-79.7h31.4l0.4 79.7h0.4l32.2-79.7h28.4l-50.3 106h-31l-3-70.3h-0.4l-35.5 70.3h-31.4L1913.5 751.2z" class="a"/><path d="M2063 802.8c6.2-28.9 15.6-53.7 54.6-53.7 39 0 38 24.8 31.8 53.7 -7 33.2-17 56.4-55.2 56.4C2056.1 859.2 2056 836 2063 802.8zM2120.2 801.1c4.7-22 6-33.2-6.6-33.2 -12.6 0-16 11.1-20.7 33.2 -6.9 32.3-5.6 39.2 5.3 39.2C2109.2 840.4 2113.4 833.4 2120.2 801.1z" class="a"/><path d="M2204.2 751.2l-2.9 13.6h0.4c8-12.2 18.9-15.7 30.8-15.7l-5.6 26.4c-25.7-1.7-29.3 13.4-31.5 23.9l-12.3 57.7h-29.6l22.5-106h28.1V751.2z" class="a"/><path d="M1291 749.1c-11.1 0-19.8 3.4-27.7 12.8h-0.4l10.9-51.5h-29.6l-31.2 146.8h29.6l15.5-73c2-9.4 5.2-16.8 14.7-16.8 9.4 0 9.6 7.3 7.6 16.8l-15.5 73h29.6l18.1-85C1315.6 757.5 1305 749.1 1291 749.1z" class="a"/><polygon points="2253.5 710.4 2222.3 857.1 2251.9 857.1 2283.1 710.4 " class="a"/><path d="M2352.4 710.4l-10.8 50.9h-0.4c-4.2-9-10.8-12.2-21.6-12.2 -29.8 0-36 32.9-40.5 54.3 -4.6 21.8-12.9 55.8 17.7 55.8 11.3 0 20.3-3.6 27.9-13.9h0.4l-2.5 11.8h28.1l31.2-146.8H2352.4L2352.4 710.4zM2332.6 803.2c-5.7 26.6-9.9 37.8-20 37.8 -10.7 0-10.2-11.1-4.6-37.8 4.5-21.2 7.4-35.9 20.2-35.9C2340.5 767.3 2337.2 782 2332.6 803.2z" class="a"/><path d="M203.5 239.7l2.1 2c58.8 49.3 122.3 44.5 170.7 12.3 30.5-20.3 168.4-112 246.3-163.8V38.5H41.7v136.7C77.1 169.1 134.2 175.1 203.5 239.7z" class="a"/><path d="M422 467.2l-68.6-65.8c-9.6-8.8-17.9-15.2-19.7-16.6 -56.1-39.4-108.4-27.4-130.9-19 -6.8 2.7-13.3 6.5-18 9.4L41.7 470.9v173.5h580.9V519.5C609.8 527.6 531.1 570.2 422 467.2z" class="a"/><path d="M198.3 255.2c-3.1-2.9-6.5-6-9.6-8.5 -68.6-53.1-133.4-27.1-147.1-20.6v59.7l33.6-22.6c0 0 51.8-38.4 132.4 1L198.3 255.2z" class="a"/><path d="M278.6 332.4c-3-2.7-6.1-5.4-9.1-8.3 -60.9-51.5-119.7-38.4-144.1-29.4 -6.9 2.8-13.5 6.5-18.2 9.4l-6.6 4.4h0l-58.9 39.4v61.5l109.6-73.8c0 0 51.2-38 131 0.3L278.6 332.4z" class="a"/><path d="M622.7 396.8c-22.8 15.4-46.1 31.1-55.3 37.2 -20.7 13.8-68.5 48.1-148.1 10.1l9.4 9c3.5 3.2 7.8 6.8 12.4 10.4 57.2 42.7 118.2 36.6 164 6.2 6.3-4.2 12.1-8.1 17.6-11.7V396.8z" class="a"/><path d="M622.7 273.6c-50.2 33.7-117.9 79.3-130.6 87.8 -20.7 13.8-69.2 48.6-147.1 11.4l9 8.7c1 0.9 2 1.9 3.1 2.8l-0.1 0.1 0 0 0.1-0.1c60.5 51.2 127 43.3 172.7 12.8 25.8-17.2 62.4-42 92.9-62.6L622.7 273.6 622.7 273.6z" class="a"/><path d="M622.7 151c-72.3 48.5-191 128-205.4 137.6 -20.8 14-70 49.2-146.9 12.5l9.3 9c5.6 5 13 11.3 21 16.5 53.2 34 108.9 28 154.3-2.3 32.6-21.8 112.8-75.1 167.7-111.5L622.7 151 622.7 151z" class="a"/></svg> \ No newline at end of file diff --git a/src/lib/src/test/java/gov/usgs/earthquake/nshmp/netcdf/SiteClassTests.java b/src/lib/src/test/java/gov/usgs/earthquake/nshmp/netcdf/SiteClassTests.java new file mode 100644 index 0000000000000000000000000000000000000000..67f4f1cb2c9e53d212763590bad0b9c58f1875bf --- /dev/null +++ b/src/lib/src/test/java/gov/usgs/earthquake/nshmp/netcdf/SiteClassTests.java @@ -0,0 +1,41 @@ +package gov.usgs.earthquake.nshmp.netcdf; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.Test; + +class SiteClassTests { + + @Test + final void testVs30() { + assertEquals(2000, SiteClass.A.vs30()); + assertEquals(1500, SiteClass.AB.vs30()); + assertEquals(1080, SiteClass.B.vs30()); + assertEquals(760, SiteClass.BC.vs30()); + assertEquals(530, SiteClass.C.vs30()); + assertEquals(365, SiteClass.CD.vs30()); + assertEquals(260, SiteClass.D.vs30()); + assertEquals(185, SiteClass.DE.vs30()); + assertEquals(150, SiteClass.E.vs30()); + } + + @Test + final void testOfValue() { + assertEquals(SiteClass.A, SiteClass.ofValue(2000)); + assertEquals(SiteClass.AB, SiteClass.ofValue(1500)); + assertEquals(SiteClass.B, SiteClass.ofValue(1080)); + assertEquals(SiteClass.BC, SiteClass.ofValue(760)); + assertEquals(SiteClass.C, SiteClass.ofValue(530)); + assertEquals(SiteClass.CD, SiteClass.ofValue(365)); + assertEquals(SiteClass.D, SiteClass.ofValue(260)); + assertEquals(SiteClass.DE, SiteClass.ofValue(185)); + assertEquals(SiteClass.E, SiteClass.ofValue(150)); + + assertThrows(IllegalArgumentException.class, + () -> { + SiteClass.ofValue(0); + }); + } + +} diff --git a/src/lib/src/test/resources/invalid-netcdf-file.nc b/src/lib/src/test/resources/invalid-netcdf-file.nc new file mode 100644 index 0000000000000000000000000000000000000000..24d309ee84916c2518cfd90f8acbb2741cc34795 --- /dev/null +++ b/src/lib/src/test/resources/invalid-netcdf-file.nc @@ -0,0 +1 @@ +invalid netcdf file diff --git a/src/lib/src/test/resources/map-netcdf-test-0p05.geojson b/src/lib/src/test/resources/map-netcdf-test-0p05.geojson new file mode 100644 index 0000000000000000000000000000000000000000..819addfaddbb0da515d7f47c0bf94e657394d4c7 --- /dev/null +++ b/src/lib/src/test/resources/map-netcdf-test-0p05.geojson @@ -0,0 +1,50 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "id": "Extents", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [-105.31, 39.15], + [-105.31, 39.31], + [-105.10, 39.31], + [-105.10, 39.15], + [-105.31, 39.15] + ] + ] + }, + "properties": { + "fill": "#AA0078", + "stroke": "#AA0078", + "title": "Conterminous US Map Extents" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [-105.31, 39.15], + [-105.25, 39.25], + [-105.30, 39.25], + [-105.30, 39.31], + [-105.22, 39.30], + [-105.15, 39.30], + [-105.15, 39.25], + [-105.10, 39.25], + [-105.13, 39.15], + [-105.31, 39.15] + ] + ] + }, + "properties": { + "spacing": 0.05, + "title": "Conterminous US netCDF Test Region" + } + } + ] +} diff --git a/src/lib/src/test/resources/nshmp-conus-test-fv.0.3.nc b/src/lib/src/test/resources/nshmp-conus-test-fv.0.3.nc new file mode 100644 index 0000000000000000000000000000000000000000..1cff28e4aabc1888e673b28fe86f0a8c4444e7af Binary files /dev/null and b/src/lib/src/test/resources/nshmp-conus-test-fv.0.3.nc differ diff --git a/src/lib/src/test/resources/nshmp-conus-test-fv.0.4.nc b/src/lib/src/test/resources/nshmp-conus-test-fv.0.4.nc new file mode 100644 index 0000000000000000000000000000000000000000..3d1966c875908dba6b6c2a5d83e06a8456600750 Binary files /dev/null and b/src/lib/src/test/resources/nshmp-conus-test-fv.0.4.nc differ diff --git a/src/lib/src/test/resources/nshmp-conus-test-fv.1.0.nc b/src/lib/src/test/resources/nshmp-conus-test-fv.1.0.nc new file mode 100644 index 0000000000000000000000000000000000000000..ac2e5d506110070fbba0ac34edb9748d38df4c15 Binary files /dev/null and b/src/lib/src/test/resources/nshmp-conus-test-fv.1.0.nc differ