/* * Geotoolkit - An Open Source Java GIS Toolkit * http://www.geotoolkit.org * * (C) 2014, Geomatys * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ package org.geotoolkit.sos.netcdf; import java.sql.Timestamp; import java.util.ArrayList; import java.util.Date; import java.util.List; import org.geotoolkit.gml.xml.AbstractGeometry; import org.geotoolkit.gml.xml.Envelope; import org.geotoolkit.gml.xml.v321.AbstractGeometryType; import org.geotoolkit.sos.xml.SOSXmlFactory; import org.opengis.temporal.TemporalGeometricPrimitive; /** * * @author guilhem */ public class GeoSpatialBound { public Date dateStart; public Date dateEnd; public Double minx; public Double maxx; public Double miny; public Double maxy; private final List<AbstractGeometry> geometries = new ArrayList<>(); public void addDate(final long millis) { final Date d = new Date(millis); addDate(d); } public void addDate(final Date date) { if (date == null) return; if (dateStart == null) { dateStart = date; } if (dateEnd == null) { dateEnd = date; } if (dateStart.getTime() > date.getTime()) { dateStart = date; } if (dateEnd.getTime() < date.getTime()) { dateEnd = date; } } public void addXYCoordinate(final Double x, final Double y) { addXCoordinate(x); addYCoordinate(y); } public void addXCoordinate(final Double x) { if (x == null) return; if (minx == null) { minx = x; } if (maxx == null) { maxx = x; } if (minx > x) { minx = x; } if (maxx < x) { maxx = x; } } public void addYCoordinate(final Double y) { if (y == null) return; if (miny == null) { miny = y; } if (maxy == null) { maxy = y; } if (miny > y) { miny = y; } if (maxy < y) { maxy = y; } } /** * TODO int from a CRS */ public void initBoundary() { minx = -180.0; maxx = 180.0; miny = -90.0; maxy = 90.0; } public void addGeometry(final AbstractGeometry geometry) { if (!geometries.contains(geometry)) { geometries.add(geometry); } } public boolean hasFullSpatialCoordinates() { return maxx != null && minx != null && maxy != null && miny != null; } public void merge(final GeoSpatialBound other) { addDate(other.dateStart); addDate(other.dateEnd); addXCoordinate(other.minx); addXCoordinate(other.maxx); addYCoordinate(other.miny); addYCoordinate(other.maxy); for (AbstractGeometry geom : other.geometries) { if (!this.geometries.contains(geom)) { this.geometries.add(geom); } } } public TemporalGeometricPrimitive getTimeObject(final String version) { if (dateStart != null && dateEnd != null) { if (dateStart.getTime() == dateEnd.getTime()) { return SOSXmlFactory.buildTimeInstant(version, new Timestamp(dateStart.getTime())); } else { return SOSXmlFactory.buildTimePeriod(version, new Timestamp(dateStart.getTime()), new Timestamp(dateEnd.getTime())); } } return null; } public Envelope getSpatialBounds(final String version) { if (!hasFullSpatialCoordinates()) { return null; } if ("1.0.0".equals(version)) { final org.geotoolkit.gml.xml.v311.DirectPositionType lower = new org.geotoolkit.gml.xml.v311.DirectPositionType(minx, miny); final org.geotoolkit.gml.xml.v311.DirectPositionType upper = new org.geotoolkit.gml.xml.v311.DirectPositionType(maxx, maxy); return new org.geotoolkit.gml.xml.v311.EnvelopeType(null, lower, upper, null); } else if ("2.0.0".equals(version)) { final org.geotoolkit.gml.xml.v321.DirectPositionType lower = new org.geotoolkit.gml.xml.v321.DirectPositionType(minx, miny); final org.geotoolkit.gml.xml.v321.DirectPositionType upper = new org.geotoolkit.gml.xml.v321.DirectPositionType(maxx, maxy); return new org.geotoolkit.gml.xml.v321.EnvelopeType(lower, upper, null); } else { throw new IllegalArgumentException("unexpected version:" + version); } } public AbstractGeometry getPolyGonBounds(final String version) { if (!hasFullSpatialCoordinates()) { return null; } final List<Double> positions = new ArrayList<>(); positions.add(miny); positions.add(minx); positions.add(miny); positions.add(maxx); positions.add(maxy); positions.add(maxx); positions.add(maxy); positions.add(minx); positions.add(miny); positions.add(minx); if ("1.0.0".equals(version)) { final org.geotoolkit.gml.xml.v311.DirectPositionListType posList = new org.geotoolkit.gml.xml.v311.DirectPositionListType(positions); final org.geotoolkit.gml.xml.v311.AbstractRingType exterior = new org.geotoolkit.gml.xml.v311.LinearRingType("EPSG:4326", posList); return new org.geotoolkit.gml.xml.v311.PolygonType(exterior, null); } else if ("2.0.0".equals(version)) { final org.geotoolkit.gml.xml.v321.DirectPositionListType posList = new org.geotoolkit.gml.xml.v321.DirectPositionListType(positions); final org.geotoolkit.gml.xml.v321.AbstractRingType exterior = new org.geotoolkit.gml.xml.v321.LinearRingType("EPSG:4326", posList); return new org.geotoolkit.gml.xml.v321.PolygonType(exterior, null); } else { throw new IllegalArgumentException("unexpected version:" + version); } } public AbstractGeometry getGeometry(final String version) { if (geometries.isEmpty()) { return null; } else if (geometries.size() == 1) { return geometries.get(0); } else { final List<org.geotoolkit.gml.xml.v321.GeometryPropertyType> members = new ArrayList<>(); for (AbstractGeometry geom : geometries) { members.add(new org.geotoolkit.gml.xml.v321.GeometryPropertyType((AbstractGeometryType) geom)); } final org.geotoolkit.gml.xml.v321.MultiGeometryType geom = new org.geotoolkit.gml.xml.v321.MultiGeometryType(members); return geom; } } }