Envelope.java

  1. package de.turnertech.ows.gml;

  2. import java.text.DecimalFormat;
  3. import java.text.DecimalFormatSymbols;
  4. import java.util.Locale;
  5. import java.util.Optional;

  6. import javax.xml.namespace.QName;
  7. import javax.xml.stream.XMLStreamWriter;

  8. import de.turnertech.ows.Logging;
  9. import de.turnertech.ows.common.OwsContext;
  10. import de.turnertech.ows.srs.SpatialReferenceSystem;
  11. import de.turnertech.ows.srs.SpatialReferenceSystemConverter;
  12. import de.turnertech.ows.srs.SpatialReferenceSystemRepresentation;

  13. public class Envelope implements GmlElement {

  14.     @Deprecated
  15.     public static final String GML_NAME = "boundedBy";

  16.     public static final QName QNAME = new QName(OwsContext.GML_URI, "Envelope");

  17.     protected DirectPosition upperCorner;

  18.     protected DirectPosition lowerCorner;

  19.     // Use with care! This is an inverted and unusable box!
  20.     public Envelope() {
  21.         this(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY);
  22.     }

  23.     public Envelope(double south, double west, double north, double east) {
  24.         this.lowerCorner = new DirectPosition(SpatialReferenceSystem.EPSG4326, west, south);
  25.         this.upperCorner = new DirectPosition(SpatialReferenceSystem.EPSG4326, east, north);
  26.     }

  27.     public Envelope(final DirectPosition lowerCorner, final DirectPosition upperCorner) {
  28.         this.lowerCorner = lowerCorner;
  29.         this.upperCorner = upperCorner;
  30.     }

  31.     public boolean contains(double latitude, double longitute) {
  32.         return !(latitude > upperCorner.getY() || latitude < lowerCorner.getY() || longitute > upperCorner.getX() || longitute < lowerCorner.getX());
  33.     }

  34.     public boolean intersects(Envelope other) {
  35.         if(this.getNorth() < other.getSouth()) return false;
  36.         if(this.getSouth() > other.getNorth()) return false;
  37.         if(this.getEast() < other.getWest()) return false;
  38.         if(this.getWest() > other.getEast()) return false;
  39.         return true;
  40.     }

  41.     public static Envelope from(Envelope other) {
  42.         return new Envelope(other.getSouth(), other.getWest(), other.getNorth(), other.getEast());
  43.     }

  44.     public static Envelope from(DirectPositionList posList) {
  45.         double maxSouth = Double.POSITIVE_INFINITY;
  46.         double maxWest = Double.POSITIVE_INFINITY;
  47.         double maxNorth = Double.NEGATIVE_INFINITY;
  48.         double maxEast = Double.NEGATIVE_INFINITY;

  49.         for(DirectPosition position : posList) {
  50.             if(position.getY() > maxNorth) maxNorth = position.getY();
  51.             if(position.getY() < maxSouth) maxSouth = position.getY();
  52.             if(position.getX() > maxEast) maxEast = position.getX();
  53.             if(position.getX() < maxWest) maxWest = position.getX();
  54.         }

  55.         // Catch BBOX with a size of 0 (causes errors in many clients, happens with only 1 point)
  56.         if(maxSouth == maxNorth) {
  57.             maxNorth += 0.00001;
  58.             maxSouth -= 0.00001;
  59.         }
  60.         if(maxEast == maxWest) {
  61.             maxEast += 0.00001;
  62.             maxWest -= 0.00001;
  63.         }

  64.         return new Envelope(maxSouth, maxWest, maxNorth, maxEast);
  65.     }

  66.     public void expandToFit(Envelope other) {
  67.         if(other == null) return;
  68.         if(other.getNorth() > getNorth()) upperCorner.setY(other.getNorth());
  69.         if(other.getSouth() < getSouth()) lowerCorner.setY(other.getSouth());
  70.         if(other.getEast() > getEast()) upperCorner.setX(other.getEast());
  71.         if(other.getWest() < getWest()) lowerCorner.setX(other.getWest());
  72.     }

  73.     /**
  74.      * @return the south
  75.      */
  76.     public double getSouth() {
  77.         return lowerCorner.getY();
  78.     }

  79.     /**
  80.      * @return the west
  81.      */
  82.     public double getWest() {
  83.         return lowerCorner.getX();
  84.     }

  85.     /**
  86.      * @return the north
  87.      */
  88.     public double getNorth() {
  89.         return upperCorner.getY();
  90.     }

  91.     /**
  92.      * @return the east
  93.      */
  94.     public double getEast() {
  95.         return upperCorner.getX();
  96.     }

  97.     @Override
  98.     public void writeGml(XMLStreamWriter out, String localName, String namespaceURI, SpatialReferenceSystemRepresentation srsRepresentation) {
  99.         DecimalFormat decimalFormat = new DecimalFormat("0.", DecimalFormatSymbols.getInstance(Locale.ENGLISH));
  100.         decimalFormat.setMaximumFractionDigits(8);

  101.         DirectPosition sw = new DirectPosition(getWest(), getSouth());
  102.         DirectPosition ne = new DirectPosition(getEast(), getNorth());

  103.         Optional<DirectPosition> transformedPos = SpatialReferenceSystemConverter.convertDirectPosition(sw, srsRepresentation.getSrs());
  104.         if (transformedPos.isPresent()) {
  105.             sw = transformedPos.get();
  106.         }

  107.         transformedPos = SpatialReferenceSystemConverter.convertDirectPosition(ne, srsRepresentation.getSrs());
  108.         if (transformedPos.isPresent()) {
  109.             ne = transformedPos.get();
  110.         }

  111.         try {
  112.             writeGmlStartElement(out, localName, namespaceURI);
  113.                 out.writeStartElement(GmlElement.NAMESPACE, "Envelope");
  114.                 out.writeAttribute(GmlElement.NAMESPACE, "srsName", srsRepresentation.toString());
  115.                     out.writeStartElement(GmlElement.NAMESPACE, "lowerCorner");
  116.                         out.writeCharacters(sw.toString());
  117.                     out.writeEndElement();
  118.                     out.writeStartElement(GmlElement.NAMESPACE, "upperCorner");
  119.                         out.writeCharacters(ne.toString());
  120.                     out.writeEndElement();
  121.                 out.writeEndElement();
  122.             out.writeEndElement();
  123.         } catch (Exception e) {
  124.             Logging.LOG.severe("Could not get GML for BoundingBox");
  125.         }
  126.     }

  127.     @Override
  128.     public String getGmlName() {
  129.         return GML_NAME;
  130.     }

  131. }