From f68fd4cf0a9782de1644818fe28c99d471ae76be Mon Sep 17 00:00:00 2001 From: Peter Powers <pmpowers@usgs.gov> Date: Mon, 14 Mar 2016 15:04:27 -0600 Subject: [PATCH] code shuffling; renamed Export to NshmSiteFiles --- src/org/opensha2/calc/Site.java | 58 +------- src/org/opensha2/calc/Sites.java | 34 ++--- src/org/opensha2/util/GeoJson.java | 111 ++++++++++++++ .../util/{Export.java => NshmpSiteFiles.java} | 135 ++++-------------- 4 files changed, 157 insertions(+), 181 deletions(-) rename src/org/opensha2/util/{Export.java => NshmpSiteFiles.java} (72%) diff --git a/src/org/opensha2/calc/Site.java b/src/org/opensha2/calc/Site.java index 9baa45477..3ee212b87 100644 --- a/src/org/opensha2/calc/Site.java +++ b/src/org/opensha2/calc/Site.java @@ -139,8 +139,6 @@ public class Site implements Named { return name; } - // TODO do we need toCsv and to/fromJson?? - /** * Return a fresh {@link Builder}. */ @@ -158,7 +156,7 @@ public class Site implements Named { public static class Builder { private String name = NO_NAME; - private Location location = NehrpTestCity.LOS_ANGELES.location(); + private Location location; private double vs30 = DEFAULT_VS_30; private boolean vsInferred = true; private double z1p0 = Double.NaN; @@ -249,15 +247,11 @@ public class Site implements Named { Key.Z2P5); /* - * Custom (de)serializers that take care of several issues with sites. + * Custom deserializer that takes care of several issues with sites. * Specifically, JSON prohibits the use of NaN, which is the default value * for z1p0 and z2p5, and so these two fields may not be set. Users have * been notified that as long as no z1p0 or z2p5 value has been supplied in * any JSON, the default will be used. - * - * TODO check me: Also, a Location stores data internally in radians and so - * we ensure that user-friendly decimal degree values are used during - * (de)serialization. */ static class Deserializer implements JsonDeserializer<Site> { @@ -303,52 +297,4 @@ public class Site implements Named { } } - static class Serializer implements JsonSerializer<Site> { - - @Override - public JsonElement serialize( - Site site, - Type type, - JsonSerializationContext context) { - - JsonObject feature = new JsonObject(); - feature.addProperty(GeoJson.Key.TYPE, GeoJson.Value.FEATURE); - - JsonObject geometry = new JsonObject(); - geometry.addProperty(GeoJson.Key.TYPE, GeoJson.Value.POINT); - geometry.add(GeoJson.Key.COORDINATES, context.serialize( - new double[] { site.location.lon(), site.location.lat() })); - feature.add(GeoJson.Key.GEOMETRY, geometry); - - JsonObject properties = new JsonObject(); - properties.addProperty(GeoJson.Properties.Key.TITLE, site.name); - feature.add(GeoJson.Key.PROPERTIES, properties); - - return feature; - } - } - - static class SerializerWithSiteTerms extends Serializer { - - @Override - public JsonElement serialize( - Site site, - Type type, - JsonSerializationContext context) { - - JsonObject feature = (JsonObject) super.serialize(site, type, context); - JsonObject properties = feature.getAsJsonObject(GeoJson.Key.PROPERTIES); - - properties.addProperty(Site.Key.VS30, site.vs30); - properties.addProperty(Site.Key.VS_INF, site.vsInferred); - - if (Double.isNaN(site.z1p0) && Double.isNaN(site.z1p0)) return feature; - - properties.addProperty(Site.Key.Z1P0, site.z1p0); - properties.addProperty(Site.Key.Z2P5, site.z2p5); - - return feature; - } - } - } diff --git a/src/org/opensha2/calc/Sites.java b/src/org/opensha2/calc/Sites.java index 55cc99f19..07a1b9cf3 100644 --- a/src/org/opensha2/calc/Sites.java +++ b/src/org/opensha2/calc/Sites.java @@ -1,6 +1,8 @@ package org.opensha2.calc; import static com.google.common.base.Preconditions.checkState; +import static com.google.common.base.Strings.padEnd; +import static com.google.common.base.Strings.padStart; import static com.google.common.base.Strings.repeat; import static java.nio.charset.StandardCharsets.UTF_8; import static org.opensha2.geo.BorderType.MERCATOR_LINEAR; @@ -14,7 +16,9 @@ import java.lang.reflect.Type; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; +import java.text.DecimalFormat; import java.util.ArrayList; +import java.util.Collection; import java.util.Iterator; import java.util.List; @@ -30,6 +34,7 @@ import org.opensha2.util.Parsing; import org.opensha2.util.Parsing.Delimiter; import org.opensha2.util.TextUtils; +import com.google.common.base.Function; import com.google.common.base.Optional; import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; @@ -43,18 +48,16 @@ import com.google.gson.JsonElement; import com.google.gson.JsonObject; /** - * A {@code SiteSet} is an Iterable over a group of {@code Site}s. The supplied - * {@code Site}s may be defined internally by a region with common properties or - * a list of individual sites. Any {@code iterator} returned by this class is - * unmodifiable. + * {@code Site} factory class used primarily for creating iterables over groups + * of sites. * * @author Peter Powers */ public final class Sites { /** - * Create an {@code Iterable<Site>} from the comma-delimted site file - * designated by {@code path}. + * Create an unmodifiable {@code Iterable<Site>} from the comma-delimted + * site file designated by {@code path}. * * @param path to comma-delimited site data file * @throws IOException if a problem is encountered @@ -135,7 +138,7 @@ public final class Sites { .create(); /** - * Create an {@code Iterable<Site>} from the GeoJSON site file + * Create an unmodifiable {@code Iterable<Site>} from the GeoJSON site file * designated by {@code path}. * * @param path to GeoJson site data file @@ -148,9 +151,11 @@ public final class Sites { return iterable; } - /* Marker interface needed for deserialization */ + /* + * Parent class for deserialization of different GeoJSON site file formats + */ private abstract static class SiteIterable implements Iterable<Site> { - + static final int TO_STRING_LIMIT = 5; @Override @@ -188,7 +193,7 @@ public final class Sites { return delegate.iterator(); } } - + static final class RegionIterable extends SiteIterable { final GriddedRegion region; @@ -223,12 +228,6 @@ public final class Sites { } } - - static final String SITES = "sites"; - static final String REGION = "region"; - static final String BORDER = "border"; - static final String SPACING = "spacing"; - /* * Site GeoJSON is currently deserialized with the expectation that the * feature array will be strictly of type:Point or type:Polygon. Polygon @@ -269,7 +268,7 @@ public final class Sites { int calcPolyIndex = 0; if (features.size() == 2) { calcPolyIndex++; - + JsonObject extentsFeature = features.get(0).getAsJsonObject(); validateProperty(extentsFeature, GeoJson.Key.ID, GeoJson.Value.EXTENTS); @@ -373,4 +372,5 @@ public final class Sites { "Extents polygon does not define a lat-lon Mercator rectangle:%s", locs); return locs; } + } diff --git a/src/org/opensha2/util/GeoJson.java b/src/org/opensha2/util/GeoJson.java index 9cc573a16..da874bdec 100644 --- a/src/org/opensha2/util/GeoJson.java +++ b/src/org/opensha2/util/GeoJson.java @@ -1,14 +1,21 @@ package org.opensha2.util; import static com.google.common.base.Preconditions.checkState; +import static org.opensha2.util.MathUtils.round; +import java.util.List; import java.util.Objects; +import org.opensha2.calc.NamedLocation; +import org.opensha2.geo.Location; import org.opensha2.geo.LocationList; +import com.google.common.base.Optional; +import com.google.common.collect.ImmutableList; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; +import com.google.gson.annotations.SerializedName; /** * GeoJSON serialization keys, values, and utilities. @@ -87,4 +94,108 @@ public final class GeoJson { "Expected \"%s\" : \"%s\", but found \"$s\"", key, value, actual); } + + /* GeoJSON objectsfor stadard GSON serialization */ + + static class FeatureCollection { + String type = "FeatureCollection"; + List<Feature> features; + } + + static class Feature { + String type = "Feature"; + String id; + Geometry geometry = new Geometry(); + PropertiesObject properties; + } + + static Feature createPoint(NamedLocation loc) { + Feature f = new Feature(); + f.geometry.type = "Point"; + f.geometry.coordinates = toCoordinates(loc.location()); + f.properties = new PointProperties(); + f.properties.title = loc.toString(); + return f; + } + + private static final String EXTENTS_COLOR = "#4169E1"; + + static Feature createPolygon( + String name, + LocationList coords, + Optional<String> id, + Optional<Double> spacing) { + + Feature f = new Feature(); + + PolyProperties properties = new PolyProperties(); + properties.title = name; + if (spacing.isPresent()) { + properties.spacing = spacing.get(); + } + + if (id.isPresent()) { + f.id = id.get(); + coords = coords.bounds().toList(); + properties.strokeColor = EXTENTS_COLOR; + properties.fillColor = EXTENTS_COLOR; + } + + f.geometry.type = "Polygon"; + f.geometry.coordinates = ImmutableList.of(toCoordinates(coords)); + f.properties = properties; + return f; + } + + static class Geometry { + String type; + Object coordinates; + } + + static class PropertiesObject { + String title; + } + + static class PointProperties extends PropertiesObject { + @SerializedName("marker-size") + String markerSize = "small"; + } + + static class PolyProperties extends PropertiesObject { + Double spacing; + @SerializedName("fill") + String fillColor; + @SerializedName("marker-color") + String strokeColor; + } + + static double[] toCoordinates(Location loc) { + return new double[] { round(loc.lon(), 5), round(loc.lat(), 5) }; + } + + static double[][] toCoordinates(LocationList locs) { + double[][] coords = new double[locs.size()][2]; + for (int i = 0; i < locs.size(); i++) { + coords[i] = toCoordinates(locs.get(i)); + } + return coords; + } + + /* brute force compaction of coordinate array onto single line */ + static String cleanPoints(String s) { + return s.replace(": [\n ", ": [") + .replace(",\n ", ", ") + .replace("\n ]", "]") + "\n"; + } + + /* brute force compaction of coordinate array onto single line */ + static String cleanPoly(String s) { + return s + .replace("\n [", "[") + .replace("[\n ", "[ ") + .replace(",\n ", ", ") + .replace("\n ]", " ]") + .replace("\n ]", "]") + "\n"; + } + } diff --git a/src/org/opensha2/util/Export.java b/src/org/opensha2/util/NshmpSiteFiles.java similarity index 72% rename from src/org/opensha2/util/Export.java rename to src/org/opensha2/util/NshmpSiteFiles.java index 5667531f9..f7ba5259d 100644 --- a/src/org/opensha2/util/Export.java +++ b/src/org/opensha2/util/NshmpSiteFiles.java @@ -30,6 +30,8 @@ import java.util.Set; import org.opensha2.calc.NamedLocation; import org.opensha2.geo.Location; import org.opensha2.geo.LocationList; +import org.opensha2.util.GeoJson.Feature; +import org.opensha2.util.GeoJson.FeatureCollection; import com.google.common.base.Function; import com.google.common.base.Functions; @@ -42,11 +44,11 @@ import com.google.gson.GsonBuilder; import com.google.gson.annotations.SerializedName; /** - * Methods for exporting data as TXT, JSON, KML, CSV, etc. + * Methods for exporting nshmp site data as CSV and GeoJSON. * * @author Peter Powers */ -final class Export { +final class NshmpSiteFiles { private static final Gson GSON = new GsonBuilder() .setPrettyPrinting() @@ -55,6 +57,9 @@ final class Export { private static final Path EXPORT_DIR = Paths.get("etc", "nshm"); + /** + * Updates all site list and map files in etc/nshm. + */ public static void main(String[] args) throws IOException { writeNshmpSites(); writeNshmpPolys(); @@ -158,7 +163,7 @@ final class Export { List<Feature> features = new ArrayList<>(); int i = 0; for (LocationList coords : coordList) { - features.add(createPolygon( + features.add(GeoJson.createPolygon( nameList.get(i++), coords, Optional.<String> absent(), @@ -166,7 +171,7 @@ final class Export { } FeatureCollection fc = new FeatureCollection(); fc.features = features; - String json = cleanPoly(GSON.toJson(fc)); + String json = GeoJson.cleanPoly(GSON.toJson(fc)); Files.write(out, json.getBytes(StandardCharsets.UTF_8)); } @@ -179,20 +184,20 @@ final class Export { List<Feature> features = new ArrayList<>(); if (bounds != null) { - features.add(createPolygon( + features.add(GeoJson.createPolygon( name + " Map Extents", bounds, Optional.of(GeoJson.Value.EXTENTS), Optional.<Double> absent())); } - features.add(createPolygon( + features.add(GeoJson.createPolygon( name, coords, Optional.<String> absent(), Optional.of(spacing))); FeatureCollection fc = new FeatureCollection(); fc.features = features; - String json = cleanPoly(GSON.toJson(fc)); + String json = GeoJson.cleanPoly(GSON.toJson(fc)); Files.write(out, json.getBytes(StandardCharsets.UTF_8)); } @@ -244,115 +249,29 @@ final class Export { List<Feature> features = new ArrayList<>(sites.size()); for (NamedLocation loc : sites) { - features.add(createPoint(loc)); + features.add(GeoJson.createPoint(loc)); } FeatureCollection fc = new FeatureCollection(); fc.features = features; - String json = cleanPoints(GSON.toJson(fc)); + String json = GeoJson.cleanPoints(GSON.toJson(fc)); Files.write(out, json.getBytes(StandardCharsets.UTF_8)); } - - /* GeoJSON objects */ - - static class FeatureCollection { - String type = "FeatureCollection"; - List<Feature> features; - } - - static class Feature { - String type = "Feature"; - String id; - Geometry geometry = new Geometry(); - Properties properties; - } - - static Feature createPoint(NamedLocation loc) { - Feature f = new Feature(); - f.geometry.type = "Point"; - f.geometry.coordinates = toCoordinates(loc.location()); - f.properties = new PointProperties(); - f.properties.title = loc.toString(); - return f; - } - - private static final String EXTENTS_COLOR = "#4169E1"; - static Feature createPolygon( - String name, - LocationList coords, - Optional<String> id, - Optional<Double> spacing) { - - Feature f = new Feature(); - - PolyProperties properties = new PolyProperties(); - properties.title = name; - if (spacing.isPresent()) { - properties.spacing = spacing.get(); - } - - if (id.isPresent()) { - f.id = id.get(); - coords = coords.bounds().toList(); - properties.strokeColor = EXTENTS_COLOR; - properties.fillColor = EXTENTS_COLOR; - } - - f.geometry.type = "Polygon"; - f.geometry.coordinates = ImmutableList.of(toCoordinates(coords)); - f.properties = properties; - return f; - } +// private static void writeJsonSites(Path out, Collection<? extends NamedLocation> sites) +// throws IOException { +// +// List<Feature> features = new ArrayList<>(sites.size()); +// for (NamedLocation loc : sites) { +// features.add(createPoint(loc)); +// } +// FeatureCollection fc = new FeatureCollection(); +// fc.features = features; +// String json = cleanPoints(GSON.toJson(fc)); +// Files.write(out, json.getBytes(StandardCharsets.UTF_8)); +// } - static class Geometry { - String type; - Object coordinates; - } - - static class Properties { - String title; - } - - static class PointProperties extends Properties { - @SerializedName("marker-size") - String markerSize = "small"; - } - - static class PolyProperties extends Properties { - Double spacing; - @SerializedName("fill") - String fillColor; - @SerializedName("marker-color") - String strokeColor; - } - static double[] toCoordinates(Location loc) { - return new double[] { round(loc.lon(), 5), round(loc.lat(), 5) }; - } - - static double[][] toCoordinates(LocationList locs) { - double[][] coords = new double[locs.size()][2]; - for (int i = 0; i < locs.size(); i++) { - coords[i] = toCoordinates(locs.get(i)); - } - return coords; - } - - /* brute force compaction of coordinate array onto single line */ - static String cleanPoints(String s) { - return s.replace(": [\n ", ": [") - .replace(",\n ", ", ") - .replace("\n ]", "]") + "\n"; - } + /* GeoJSON objects */ - /* brute force compaction of coordinate array onto single line */ - static String cleanPoly(String s) { - return s - .replace("\n [", "[") - .replace("[\n ", "[ ") - .replace(",\n ", ", ") - .replace("\n ]", " ]") - .replace("\n ]", "]") + "\n"; - } } -- GitLab