/** * Copyright (C) 2012-2017 52°North Initiative for Geospatial Open Source * Software GmbH * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published * by the Free Software Foundation. * * If the program is linked with libraries which are licensed under one of * the following licenses, the combination of the program with the linked * library is not considered a "derivative work" of the program: * * - Apache License, version 2.0 * - Apache Software License, version 1.0 * - GNU Lesser General Public License, version 3 * - Mozilla Public License, versions 1.0, 1.1 and 2.0 * - Common Development and Distribution License (CDDL), version 1.0 * * Therefore the distribution of the program linked with libraries licensed * under the aforementioned licenses, is permitted by the copyright holders * if the distribution is compliant with both the GNU General Public * License version 2 and the aforementioned licenses. * * This program 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 General * Public License for more details. */ package org.n52.sos.ds.hibernate.util.observation; import java.util.List; import java.util.Set; import org.n52.sos.aqd.AqdConstants; import org.n52.sos.aqd.AqdConstants.PrimaryObservation; import org.n52.sos.aqd.AqdUomRepository; import org.n52.sos.aqd.AqdUomRepository.Uom; import org.n52.sos.aqd.ElementType; import org.n52.sos.ds.hibernate.entities.AbstractObservationTime; import org.n52.sos.ds.hibernate.entities.ereporting.HiberanteEReportingRelations.EReportingQualityData; import org.n52.sos.ds.hibernate.entities.ereporting.HiberanteEReportingRelations.EReportingValues; import org.n52.sos.ds.hibernate.entities.ereporting.values.EReportingValue; import org.n52.sos.iso.gmd.GmdDomainConsistency; import org.n52.sos.ogc.gml.GmlConstants; import org.n52.sos.ogc.gml.time.Time; import org.n52.sos.ogc.gml.time.TimeInstant; import org.n52.sos.ogc.gml.time.TimePeriod; import org.n52.sos.ogc.om.ObservationValue; import org.n52.sos.ogc.om.OmObservation; import org.n52.sos.ogc.om.SingleObservationValue; import org.n52.sos.ogc.om.quality.OmResultQuality; import org.n52.sos.ogc.om.values.SweDataArrayValue; import org.n52.sos.ogc.swe.SweAbstractDataComponent; import org.n52.sos.ogc.swe.SweDataArray; import org.n52.sos.ogc.swe.SweDataRecord; import org.n52.sos.ogc.swe.SweField; import org.n52.sos.ogc.swe.encoding.SweAbstractEncoding; import org.n52.sos.ogc.swe.simpleType.SweCategory; import org.n52.sos.ogc.swe.simpleType.SweCount; import org.n52.sos.ogc.swe.simpleType.SweQuantity; import org.n52.sos.ogc.swe.simpleType.SweTime; import org.n52.sos.util.Constants; import org.n52.sos.util.DateTimeHelper; import org.n52.sos.util.JavaHelper; import org.n52.sos.util.SweHelper; import com.google.common.collect.Lists; import com.google.common.collect.Sets; /** * Helper class for eReporting. * * @author Carsten Hollmann <c.hollmann@52north.org> * @since 4.3.0 * */ public class EReportingHelper { /** * private constructor */ private EReportingHelper() { } /** * Creates an {@link ObservationValue} from the {@link EReportingValue} * * @param omObservation * Corresponding {@link OmObservation} * @param observation * {@link EReportingValue} to create {@link ObservationValue} * from * @return Created {@link ObservationValue}. */ @SuppressWarnings({ "rawtypes", "unchecked" }) public static SingleObservationValue<?> createSweDataArrayValue(OmObservation omObservation, EReportingValues observation) { SweDataArrayValue sweDataArrayValue = new SweDataArrayValue(); sweDataArrayValue.setValue(createSweDataArray(omObservation, observation)); SingleObservationValue observationValue = new SingleObservationValue(sweDataArrayValue); observationValue.setPhenomenonTime(getPhenomenonTime(omObservation, ((AbstractObservationTime) observation).createPhenomenonTime())); addQuality(observation, observationValue); return observationValue; } /** * Creates an {@link SweDataArray} object from the {@link EReportingValue} * * @param omObservation * Corresponding {@link OmObservation} * @param observation * {@link EReportingValue} to create {@link SweDataArray} from * @return Created {@link SweDataArray} */ public static SweDataArray createSweDataArray(OmObservation omObservation, EReportingValues observation) { SweDataArray sweDataArray = new SweDataArray(); sweDataArray.setElementCount(createElementCount(omObservation)); PrimaryObservation primaryObservation = PrimaryObservation.from(observation.getPrimaryObservation()); sweDataArray.setElementType(createElementType(primaryObservation, getUnit(omObservation, observation))); sweDataArray.setEncoding(createEncoding(omObservation)); sweDataArray.setValues(createValue(omObservation, observation, primaryObservation)); return sweDataArray; } /** * Merge {@link SweDataArray}s to a single {@link SweDataArray} * * @param combinedValue * {@link SweDataArray} which the data is to be added * @param value * {@link SweDataArray} to be added to the other * @return Merged {@link SweDataArray} */ public static SweDataArray mergeValues(SweDataArray combinedValue, SweDataArray value) { if (value.isSetValues()) { combinedValue.addAll(value.getValues()); } return combinedValue; } private static String getUnit(OmObservation omObservation, EReportingValues observation) { if (omObservation.isSetValue() && omObservation.getValue().getValue().isSetUnit()) { return omObservation.getValue().getValue().getUnit(); } else if (observation.isSetUnit()) { return observation.getUnit().getUnit(); } return null; } private static SweCount createElementCount(OmObservation omObservation) { if (omObservation.isSetValue() && omObservation.getValue().getValue() instanceof SweDataArrayValue) { SweDataArray value = (SweDataArray) omObservation.getValue().getValue().getValue(); SweCount elementCount = value.getElementCount(); elementCount.increaseCount(); } return new SweCount().setValue(1); } private static SweAbstractDataComponent createElementType(PrimaryObservation primaryObservation, String unit) { SweDataRecord dataRecord = new SweDataRecord(); dataRecord.setDefinition(AqdConstants.NAME_FIXED_OBSERVATIONS); dataRecord.addField(createField(ElementType.START_TIME, createSweTimeSamplingTime(ElementType.START_TIME))); dataRecord.addField(createField(ElementType.END_TIME, createSweTimeSamplingTime(ElementType.END_TIME))); dataRecord.addField(createField(ElementType.VERIFICATION, createSweCatagory(ElementType.VERIFICATION))); dataRecord.addField(createField(ElementType.VALIDITY, createSweCatagory(ElementType.VALIDITY))); ElementType value = ElementType.getValueElementType(primaryObservation, unit); dataRecord.addField(createField(value, createSweQuantity(value, unit))); if (primaryObservation.isMultyDayPrimaryObservation()) { dataRecord.addField(createField(ElementType.DATA_CAPTURE, createSweQuantity(ElementType.DATA_CAPTURE))); } return dataRecord; } private static SweField createField(ElementType elementType, SweAbstractDataComponent content) { return new SweField(elementType.getName(), content); } private static SweAbstractDataComponent createSweTimeSamplingTime(ElementType elementType) { SweTime time = new SweTime(); time.setDefinition(elementType.getDefinition()); if (elementType.isSetUOM()) { time.setUom(elementType.getUOM()); } return time; } private static SweAbstractDataComponent createSweCatagory(ElementType elementType) { return new SweCategory().setDefinition(elementType.getDefinition()); } private static SweAbstractDataComponent createSweQuantity(ElementType elementType) { return createSweQuantity(elementType, elementType.getUOM()); } private static SweAbstractDataComponent createSweQuantity(ElementType elementType, String unit) { SweQuantity quantity = new SweQuantity(); quantity.setDefinition(elementType.getDefinition()); Uom aqdUom = AqdUomRepository.getAqdUom(unit); if (aqdUom != null) { quantity.setUom(aqdUom.getConceptURI()); } else { quantity.setUom(unit); } return quantity; } private static SweAbstractEncoding createEncoding(OmObservation omObservation) { return SweHelper.createTextEncoding(omObservation); } private static void addDoubleValue(List<String> list, Double value) { if (value != null) { list.add(Double.toString(value)); } else { list.add(Constants.EMPTY_STRING); } } private static void addIntegerValue(List<String> list, Integer value) { if (value != null) { list.add(Integer.toString(value)); } else { list.add(Constants.EMPTY_STRING); } } private static void addValue(List<String> value, OmObservation omObservation) { if (omObservation.getValue() instanceof SingleObservationValue<?>) { value.add(JavaHelper.asString(omObservation.getValue().getValue().getValue())); } else { value.add(Constants.EMPTY_STRING); } } private static void addValue(List<String> value, EReportingValues observation, OmObservation omObservation) { if (observation.isSetValue()) { // TODO check if this is the best solution if (omObservation.isSetDecimalSeparator() && omObservation.getDecimalSeparator() != ".") { value.add(observation.getValueAsString().replace(".", omObservation.getDecimalSeparator())); } else { value.add(observation.getValueAsString()); } } else { value.add(Constants.EMPTY_STRING); } } private static List<List<String>> createValue(OmObservation omObservation, EReportingValues observation, PrimaryObservation primaryObservation) { List<String> value = Lists.newArrayListWithCapacity(5); addTimes(value, ((AbstractObservationTime) observation).createPhenomenonTime()); addIntegerValue(value, observation.getVerification()); addIntegerValue(value, observation.getValidation()); addValue(value, observation, omObservation); if (primaryObservation.isMultyDayPrimaryObservation()) { addDoubleValue(value, observation.getDataCapture()); } List<List<String>> list = Lists.newArrayList(); list.add(value); return list; } private static void addTimes(List<String> value, Time time) { if (time instanceof TimeInstant) { value.add(DateTimeHelper.formatDateTime2IsoString(((TimeInstant) time).getValue())); value.add(DateTimeHelper.formatDateTime2IsoString(((TimeInstant) time).getValue())); } else if (time instanceof TimePeriod) { value.add(DateTimeHelper.formatDateTime2IsoString(((TimePeriod) time).getStart())); value.add(DateTimeHelper.formatDateTime2IsoString(((TimePeriod) time).getEnd())); } else { value.add(Constants.EMPTY_STRING); value.add(Constants.EMPTY_STRING); } } private static Time getPhenomenonTime(OmObservation omObservation, Time time) { if (omObservation.isSetValue() && omObservation.getPhenomenonTime() != null) { if (omObservation.getPhenomenonTime() instanceof TimePeriod) { TimePeriod timePeriod = (TimePeriod) omObservation.getPhenomenonTime(); timePeriod.extendToContain(time); return timePeriod; } else { TimePeriod timePeriod = new TimePeriod(); timePeriod.extendToContain(omObservation.getPhenomenonTime()); timePeriod.extendToContain(time); return timePeriod; } } return time; } private static void addQuality(EReportingValues eReportingObservation, SingleObservationValue<?> value) { value.addQualityList(getGmdDomainConsistency(eReportingObservation, false)); } public static Set<OmResultQuality> getGmdDomainConsistency(EReportingQualityData eReportingObservation, boolean force) { Set<OmResultQuality> set = Sets.newHashSet(); if (eReportingObservation.isSetDataCaptureFlag()) { set.add(GmdDomainConsistency.dataCapture(eReportingObservation.getDataCaptureFlag())); } else if (force) { set.add(GmdDomainConsistency.dataCapture(GmlConstants.NilReason.unknown)); } if (eReportingObservation.isSetTimeCoverageFlag()) { set.add(GmdDomainConsistency.timeCoverage(eReportingObservation.getTimeCoverageFlag())); } else if (force) { set.add(GmdDomainConsistency.timeCoverage(GmlConstants.NilReason.unknown)); } if (eReportingObservation.isSetUncertaintyEstimation()) { set.add(GmdDomainConsistency.uncertaintyEstimation(eReportingObservation.getUncertaintyEstimation())); } else if (force) { set.add(GmdDomainConsistency.uncertaintyEstimation(GmlConstants.NilReason.unknown)); } return set; } }