/* * Geotoolkit - An Open Source Java GIS Toolkit * http://www.geotoolkit.org * * (C) 2015, 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; * version 2.1 of the License. * * 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.observation; import java.net.URI; import java.sql.Timestamp; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Date; import java.util.List; import java.util.logging.Logger; import org.apache.sis.util.logging.Logging; import org.geotoolkit.gml.xml.AbstractFeature; import org.geotoolkit.gml.xml.AbstractGeometry; import org.geotoolkit.gml.xml.BoundingShape; import org.geotoolkit.gml.xml.Envelope; import static org.geotoolkit.ows.xml.OWSExceptionCode.INVALID_PARAMETER_VALUE; import static org.geotoolkit.ows.xml.OWSExceptionCode.MISSING_PARAMETER_VALUE; import org.geotoolkit.sml.xml.AbstractDerivableComponent; import org.geotoolkit.sml.xml.AbstractIdentification; import org.geotoolkit.sml.xml.AbstractIdentifier; import org.geotoolkit.sml.xml.AbstractProcess; import org.geotoolkit.sml.xml.AbstractSensorML; import org.geotoolkit.sos.xml.SOSXmlFactory; import org.geotoolkit.temporal.object.ISODateParser; import org.opengis.observation.Observation; /** * Utility methods for SOS / Sensor. * * @author Guilhem Legal (Geomatys) */ public class Utils { private static final Logger LOGGER = Logging.getLogger("org.geotoolkit.observation"); /** * Return the physical ID of a sensor. * This ID is found into a "Identifier" mark with the name 'supervisorCode' * * @param sensor * @return */ public static String getPhysicalID(final AbstractSensorML sensor) { if (sensor != null && sensor.getMember().size() > 0) { final AbstractProcess process = sensor.getMember().get(0).getRealProcess(); final List<? extends AbstractIdentification> idents = process.getIdentification(); for(AbstractIdentification ident : idents) { if (ident.getIdentifierList() != null) { for (AbstractIdentifier identifier: ident.getIdentifierList().getIdentifier()) { if ("supervisorCode".equals(identifier.getName()) && identifier.getTerm() != null) { return identifier.getTerm().getValue(); } } } } } return null; } /** * Return the position of a sensor. * * @param sensor * @return */ public static AbstractGeometry getSensorPosition(final AbstractSensorML sensor) { if (sensor.getMember().size() == 1) { if (sensor.getMember().get(0).getRealProcess() instanceof AbstractDerivableComponent) { final AbstractDerivableComponent component = (AbstractDerivableComponent) sensor.getMember().get(0).getRealProcess(); if (component.getSMLLocation() != null && component.getSMLLocation().getGeometry()!= null) { return component.getSMLLocation().getGeometry(); } else if (component.getPosition() != null && component.getPosition().getPosition() != null && component.getPosition().getPosition().getLocation() != null && component.getPosition().getPosition().getLocation().getVector() != null) { final URI crs = component.getPosition().getPosition().getReferenceFrame(); return component.getPosition().getPosition().getLocation().getVector().getGeometry(crs); } } } LOGGER.warning("there is no sensor position in the specified sensorML"); return null; } /** * return a SQL formatted timestamp * * @param time a GML time position object. * @return * @throws org.geotoolkit.observation.ObservationStoreException */ public static String getTimeValue(final Date time) throws ObservationStoreException { if (time != null) { try { DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SS"); final String value = df.format(time); //here t is not used but it allow to verify the syntax of the timestamp final ISODateParser parser = new ISODateParser(); final Date d = parser.parseToDate(value); final Timestamp t = new Timestamp(d.getTime()); return t.toString(); } catch(IllegalArgumentException e) { throw new ObservationStoreException("Unable to parse the value: " + time.toString() + '\n' + "Bad format of timestamp:\n" + e.getMessage(), INVALID_PARAMETER_VALUE, "eventTime"); } } else { String locator; if (time == null) { locator = "Timeposition"; } else { locator = "TimePosition value"; } throw new ObservationStoreException("bad format of time, " + locator + " mustn't be null", MISSING_PARAMETER_VALUE, "eventTime"); } } /** * Return an envelope containing all the Observation member of the collection. * * @param version * @param observations * @param srsName * @return */ public static Envelope getCollectionBound(final String version, final List<Observation> observations, final String srsName) { double minx = Double.MAX_VALUE; double miny = Double.MAX_VALUE; double maxx = -Double.MAX_VALUE; double maxy = -Double.MAX_VALUE; for (Observation observation: observations) { final AbstractFeature feature = (AbstractFeature) observation.getFeatureOfInterest(); if (feature != null) { if (feature.getBoundedBy() != null) { final BoundingShape bound = feature.getBoundedBy(); if (bound.getEnvelope() != null) { if (bound.getEnvelope().getLowerCorner() != null && bound.getEnvelope().getLowerCorner().getCoordinate() != null && bound.getEnvelope().getLowerCorner().getCoordinate().length == 2 ) { final double[] lower = bound.getEnvelope().getLowerCorner().getCoordinate(); if (lower[0] < minx) { minx = lower[0]; } if (lower[1] < miny) { miny = lower[1]; } } if (bound.getEnvelope().getUpperCorner() != null && bound.getEnvelope().getUpperCorner().getCoordinate() != null && bound.getEnvelope().getUpperCorner().getCoordinate().length == 2 ) { final double[] upper = bound.getEnvelope().getUpperCorner().getCoordinate(); if (upper[0] > maxx) { maxx = upper[0]; } if (upper[1] > maxy) { maxy = upper[1]; } } } } } } if (minx == Double.MAX_VALUE) { minx = -180.0; } if (miny == Double.MAX_VALUE) { miny = -90.0; } if (maxx == (-Double.MAX_VALUE)) { maxx = 180.0; } if (maxy == (-Double.MAX_VALUE)) { maxy = 90.0; } final Envelope env = SOSXmlFactory.buildEnvelope(version, null, minx, miny, maxx, maxy, srsName); env.setSrsDimension(2); env.setAxisLabels(Arrays.asList("Y X")); return env; } }