RegionsXML.java

package gov.usgs.earthquake.geoserve;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.TreeSet;

import gov.usgs.earthquake.qdm.Point;
import gov.usgs.earthquake.qdm.Region;
import gov.usgs.earthquake.qdm.Regions;
import gov.usgs.earthquake.qdm.RegionsHandler;
import gov.usgs.util.XmlUtils;

/**
 * Legacy Regions XML formatting for gov.usgs.earthquake.qdm.Regions.
 *
 */
public class RegionsXML {

  /**
   * Output ANSS Authoritative Regions in the legacy Regions XML format.
   *
   * @param regions ANSS Authoritative regions
   * @return String on regions in an XML format
   */
  public String formatXML(final Regions regions) {
    StringBuffer xml = new StringBuffer(String.join("\n", "<?xml version=\"1.0\" encoding=\"UTF-8\"?>", "<regions>",
        "  <file name=\"regions.xml\">", "  <update date=\"" + XmlUtils.formatDate(new Date()) + "\"/>",
        "  <format version=\"0.2\"/>", "\n<!--", "# ANSS Authoritative Regions",
        "# DEFAULT indicates no polygon - matches any event.", "# A network may have more than 1 region list,",
        "# but each region may be associated with only ONE network.", "# There may only be 1 DEFAULT region.",
        "-->\n"));

    // group regions by netid
    final HashMap<String, ArrayList<Region>> networks = new HashMap<>();
    for (final Region region : regions.regions) {
      String netid = region.netid;
      ArrayList<Region> netRegions = networks.get(netid);
      if (netRegions == null) {
        netRegions = new ArrayList<Region>();
        networks.put(netid, netRegions);
      }
      netRegions.add(region);
    }

    // output networks
    for (String netid : new TreeSet<>(networks.keySet())) {
      xml.append("\n<net").append(" code=\"").append(netid).append("\"")
          // name is "DEFAULT" or not, use netid since it's unique
          .append(" name=\"").append(netid).append("\"").append(">\n");
      // output network regions
      for (Region region : networks.get(netid)) {
        xml.append("  <region code=\"").append(region.regionid).append("\">\n");
        for (Point point : region.points) {
          xml.append("    <coordinate").append(" latitude=\"").append(point.y).append("\"").append(" longitude=\"")
              .append(point.x).append("\"").append("/>\n");
        }
        xml.append("  </region>\n");
      }
      xml.append("</net>\n");
    }

    // add NEIC as default region
    xml.append(String.join("\n", "", "<net code=\"US\" name=\"DEFAULT\">", "  <region code=\"US\"/>", "</net>", ""));

    xml.append("</regions>");

    return xml.toString();
  }

  /**
   * Parse regions from an XML input stream.
   *
   * @param in input stream
   * @throws Exception if error occurs
   * @return Regions
   */
  public static Regions getRegions(final InputStream in) throws Exception {
    RegionsHandler regionsHandler = new RegionsHandler();
    Exception error = regionsHandler.parse(in);
    if (error != null) {
      throw error;
    }
    return regionsHandler.regions;
  }

  /**
   * Download ANSS Authoritative regions from Geoserve, and print to the screen in
   * Regions XML format.
   *
   * @param args console arguments
   * @throws Exception if error occurs
   */
  public static void main(final String[] args) throws Exception {
    Regions regions = ANSSRegionsFactory.getFactory().getRegions();
    String xml = new RegionsXML().formatXML(regions);
    System.out.println(xml);
  }

}