GeoservePlacesService.java

  1. package gov.usgs.earthquake.geoserve;

  2. import java.io.IOException;
  3. import java.io.InputStream;
  4. import java.math.BigDecimal;
  5. import java.net.MalformedURLException;
  6. import java.net.URL;
  7. import java.net.URLEncoder;
  8. import java.nio.charset.StandardCharsets;

  9. import javax.json.Json;
  10. import javax.json.JsonArray;
  11. import javax.json.JsonObject;
  12. import javax.json.JsonReader;

  13. import gov.usgs.util.StreamUtils;

  14. /**
  15.  * Access places from the Geoserve Places service.
  16.  */
  17. public class GeoservePlacesService {
  18.   /** Default URL for GeoServe Places service. */
  19.   public static final String DEFAULT_ENDPOINT_URL = "https://earthquake.usgs.gov/ws/geoserve/places.json";
  20.   /** Default connection timeout */
  21.   public static final int DEFAULT_CONNECT_TIMEOUT = 300; // ms
  22.   /** Default read timeout */
  23.   public static final int DEFAULT_READ_TIMEOUT = 1700; // ms

  24.   /** Configured URL for GeoServe Places service. */
  25.   private String endpointUrl;
  26.   private int connectTimeout;
  27.   private int readTimeout;

  28.   /** Default constructor */
  29.   public GeoservePlacesService() {
  30.     this(DEFAULT_ENDPOINT_URL, DEFAULT_CONNECT_TIMEOUT, DEFAULT_READ_TIMEOUT);
  31.   }

  32.   /**
  33.    * Constructor taking in endpointURL
  34.    * @param endpointUrl for places service
  35.    */
  36.   public GeoservePlacesService(final String endpointUrl) {
  37.     this(endpointUrl, DEFAULT_CONNECT_TIMEOUT, DEFAULT_READ_TIMEOUT);
  38.   }

  39.   /**
  40.    * Constructor taking in timeouts and using default endpoint URL
  41.    * @param connectTimeout in ms
  42.    * @param readTimeout in ms
  43.    */
  44.   public GeoservePlacesService(final int connectTimeout, final int readTimeout) {
  45.     this(DEFAULT_ENDPOINT_URL, connectTimeout, readTimeout);
  46.   }

  47.   /**
  48.    * Custom constructor
  49.    * @param endpointUrl for Places service
  50.    * @param connectTimeout in ms
  51.    * @param readTimeout in ms
  52.    */
  53.   public GeoservePlacesService(final String endpointUrl, final int connectTimeout, final int readTimeout) {
  54.     this.setEndpointURL(endpointUrl);
  55.     this.setConnectTimeout(connectTimeout);
  56.     this.setReadTimeout(readTimeout);
  57.   }

  58.   /** @return connectTimemout */
  59.   public int getConnectTimeout() {
  60.     return this.connectTimeout;
  61.   }

  62.   /** @return endpointURL */
  63.   public String getEndpointURL() {
  64.     return this.endpointUrl;
  65.   }

  66.   /**
  67.    * Find an event in the Places service via a latitude and longitude
  68.    * @param latitude of event
  69.    * @param longitude of event
  70.    * @return JSONObject of event
  71.    * @throws IOException on IO error
  72.    * @throws MalformedURLException or URL error
  73.    */
  74.   public JsonObject getEventPlaces(BigDecimal latitude, BigDecimal longitude)
  75.       throws IOException, MalformedURLException {
  76.     final URL url = new URL(this.endpointUrl +
  77.         "?type=event" +
  78.         "&latitude=" + URLEncoder.encode(latitude.toString(), StandardCharsets.UTF_8.toString()) +
  79.         "&longitude=" + URLEncoder.encode(longitude.toString(), StandardCharsets.UTF_8.toString())
  80.     );

  81.     try (InputStream in = StreamUtils.getURLInputStream(url, this.connectTimeout, this.readTimeout)) {
  82.       JsonReader reader = Json.createReader(in);
  83.       JsonObject json = reader.readObject();
  84.       reader.close();
  85.       return json.getJsonObject("event");
  86.     }
  87.   }


  88.   /**
  89.    * Get nearest place to a latitude and longitude
  90.    * @param latitude of place
  91.    * @param longitude of place
  92.    * @return JSONObject of place
  93.    * @throws IndexOutOfBoundsException on no places returned
  94.    * @throws IOException on IO error
  95.    * @throws MalformedURLException on URL error
  96.    * @deprecated
  97.    */
  98.   public JsonObject getNearestPlace(BigDecimal latitude, BigDecimal longitude)
  99.       throws IndexOutOfBoundsException, IOException, MalformedURLException {
  100.     return this.getNearestPlace(latitude, longitude, 300);
  101.   }

  102.   /**
  103.    * Get nearest place to a latitude and longitude
  104.    * @param latitude of place
  105.    * @param longitude of place
  106.    * @param maxradiuskm around place
  107.    * @return JSONObject of place
  108.    * @throws IOException on IO error
  109.    * @throws MalformedURLException on URL error
  110.    */
  111.   public JsonObject getNearestPlace(BigDecimal latitude, BigDecimal longitude,
  112.       int maxradiuskm) throws IOException, MalformedURLException {
  113.     final URL url = new URL(this.endpointUrl +
  114.        "?type=geonames" +
  115.        "&latitude=" + URLEncoder.encode(latitude.toString(), StandardCharsets.UTF_8.toString()) +
  116.        "&longitude=" + URLEncoder.encode(longitude.toString(), StandardCharsets.UTF_8.toString()) +
  117.        "&maxradiuskm=" + URLEncoder.encode(String.valueOf(maxradiuskm), StandardCharsets.UTF_8.toString()) +
  118.        "&limit=1"
  119.     );

  120.     try (
  121.       InputStream in = StreamUtils.getURLInputStream(url, this.connectTimeout, this.readTimeout);
  122.       JsonReader reader = Json.createReader(in)
  123.     ) {
  124.       JsonObject json = reader.readObject();
  125.       JsonObject places = json.getJsonObject("geonames");
  126.       JsonArray features = places.getJsonArray("features");

  127.       if (features.size() > 0) {
  128.         return features.getJsonObject(0);
  129.       } else {
  130.         return null;
  131.       }
  132.     }
  133.   }

  134.   /** @return readTimeout */
  135.   public int getReadTimeout() {
  136.     return this.readTimeout;
  137.   }

  138.   /** @param connectTimeout int to set */
  139.   public void setConnectTimeout(final int connectTimeout) {
  140.     this.connectTimeout = connectTimeout;
  141.   }

  142.   /** @param endpointUrl string to set */
  143.   public void setEndpointURL(final String endpointUrl) {
  144.     this.endpointUrl = endpointUrl;
  145.   }

  146.   /** @param readTimeout int to set */
  147.   public void setReadTimeout(final int readTimeout) {
  148.     this.readTimeout = readTimeout;
  149.   }

  150.   // as needed, implement full GeoServe places API options
  151. }