Search in sources :

Example 1 with SubSensor

use of org.n52.sos.netcdf.data.subsensor.SubSensor in project SOS by 52North.

the class AbstractNetcdfEncoder method populateHeightDepthArray.

private Double populateHeightDepthArray(AbstractSensorDataset sensorDataset, Array heightDephtArray, Variable v) throws EncodingException {
    Index index = heightDephtArray.getIndex();
    int indexCounter = 0;
    Double consistentBinHeight = null;
    for (SubSensor subSensor : sensorDataset.getSubSensors()) {
        if (subSensor instanceof ProfileSubSensor) {
            index.setDim(0, indexCounter++);
            heightDephtArray.setDouble(index, checkValue(v, ((ProfileSubSensor) subSensor).getHeight()));
            // check for consistent bin size
            if (subSensor instanceof BinProfileSubSensor) {
                double binHeight = checkValue(v, ((BinProfileSubSensor) subSensor).getBinHeight());
                if (consistentBinHeight == null) {
                    consistentBinHeight = binHeight;
                } else if (consistentBinHeight != getNetcdfHelper().getFillValue() && consistentBinHeight != binHeight) {
                    // mark bin height as inconsistent
                    consistentBinHeight = getNetcdfHelper().getFillValue();
                }
            }
        } else {
            throw new EncodingException("Non-profile subsensors not supported.");
        }
    }
    return consistentBinHeight;
}
Also used : BinProfileSubSensor(org.n52.sos.netcdf.data.subsensor.BinProfileSubSensor) EncodingException(org.n52.svalbard.encode.exception.EncodingException) Index(ucar.ma2.Index) ProfileSubSensor(org.n52.sos.netcdf.data.subsensor.ProfileSubSensor) SubSensor(org.n52.sos.netcdf.data.subsensor.SubSensor) BinProfileSubSensor(org.n52.sos.netcdf.data.subsensor.BinProfileSubSensor) ArrayDouble(ucar.ma2.ArrayDouble) ProfileSubSensor(org.n52.sos.netcdf.data.subsensor.ProfileSubSensor) BinProfileSubSensor(org.n52.sos.netcdf.data.subsensor.BinProfileSubSensor)

Example 2 with SubSensor

use of org.n52.sos.netcdf.data.subsensor.SubSensor in project SOS by 52North.

the class AbstractNetcdfEncoder method encodeSensorDataToNetcdf.

protected void encodeSensorDataToNetcdf(File netcdfFile, AbstractSensorDataset sensorDataset, Version version) throws EncodingException, IOException {
    String sensor = sensorDataset.getSensorIdentifier();
    sensorDataset.getSensor().setSensorDescription(getProcedureDescription(sensor, sensorDataset.getProcedureDescription()));
    NetcdfFileWriter writer = getNetcdfFileWriter(netcdfFile, version);
    // set fill on, doesn't seem to have any effect though
    writer.setFill(true);
    Map<Variable, Array> variableArrayMap = Maps.newHashMap();
    int numTimes = sensorDataset.getTimes().size();
    // FIXME shouldn't assume that all subsensors are heights (or rename
    // subsensors if they are)
    int numHeightDepth = sensorDataset.getSubSensors().size() > 0 ? sensorDataset.getSubSensors().size() : 1;
    // global attributes
    addGlobaleAttributes(writer, sensorDataset);
    // add appropriate dims for feature type
    List<Dimension> timeDims = Lists.newArrayList();
    List<Dimension> latLngDims = Lists.newArrayList();
    List<Dimension> latDims = Lists.newArrayList();
    List<Dimension> lngDims = Lists.newArrayList();
    List<Dimension> zDims = Lists.newArrayList();
    List<Dimension> obsPropDims = Lists.newArrayList();
    // REQUIRED for NetCDF-3
    // add Dimensions
    // dTime = writer.addDimension(null, CFStandardNames.TIME.getName(),
    // numTimes);
    Dimension dTime = writer.addUnlimitedDimension(getVariableDimensionCaseName(CFStandardNames.TIME.getName()));
    dTime.setLength(numTimes);
    timeDims.add(dTime);
    if (!(sensorDataset instanceof StaticLocationDataset)) {
        zDims.add(dTime);
    }
    obsPropDims.add(dTime);
    // set up lat/lng dimensions
    // FIXME do not set time dimension for static location dataset
    // if ((sensorDataset instanceof StaticLocationDataset)) {
    // latLngDims.add(dTime);
    // }
    // set up z dimensions
    String dimensionName;
    if (useHeight()) {
        dimensionName = getVariableDimensionCaseName(CFStandardNames.HEIGHT.getName());
    } else {
        dimensionName = getVariableDimensionCaseName(CFStandardNames.DEPTH.getName());
    }
    // profile/timeSeriesProfile
    Dimension dZ = writer.addDimension(null, dimensionName, numHeightDepth);
    if (!(sensorDataset instanceof StaticLocationDataset)) {
        // trajectory
        zDims.add(dTime);
    }
    zDims.add(dZ);
    obsPropDims.add(dZ);
    variableArrayMap.putAll(getNetcdfProfileSpecificVariablesArrays(writer, sensorDataset));
    // time var
    Variable vTime = addVariableTime(writer, timeDims);
    if (numTimes > 1 && writer.getVersion().isNetdf4format()) {
        vTime.addAttribute(new Attribute(CDM.CHUNK_SIZES, getNetcdfHelper().getChunkSizeTime()));
    }
    ArrayDouble timeArray = new ArrayDouble(getDimShapes(timeDims));
    initArrayWithFillValue(timeArray, getNetcdfHelper().getFillValue());
    Array latArray = getLatitudeArray(sensorDataset);
    Array lonArray = getLongitudeArray(sensorDataset);
    // add lat/long dimensions
    long latSize = 1;
    if (latArray != null) {
        latSize = latArray.getSize();
    }
    Dimension dLat = writer.addDimension(null, getVariableDimensionCaseName(CFStandardNames.LATITUDE.getName()), (int) latSize);
    latDims.add(dLat);
    long lonSize = 1;
    if (lonArray != null) {
        lonSize = lonArray.getSize();
    }
    Dimension dLon = writer.addDimension(null, getVariableDimensionCaseName(CFStandardNames.LONGITUDE.getName()), (int) lonSize);
    lngDims.add(dLon);
    // lat/lon var
    Variable vLat;
    Variable vLon;
    if (latLngDims.size() > 0) {
        vLat = addVariableLatitude(writer, latLngDims);
        vLon = addVariableLongitude(writer, latLngDims);
    } else {
        vLat = addVariableLatitude(writer, latDims);
        vLon = addVariableLongitude(writer, lngDims);
    }
    // height/depth var
    Variable vHeightDepth;
    if (useHeight()) {
        vHeightDepth = addVariableHeight(writer, zDims);
    } else {
        vHeightDepth = addVariableDepth(writer, zDims);
    }
    String coordinateString = Joiner.on(' ').join(Lists.newArrayList(vTime.getFullName(), vLat.getFullName(), vLon.getFullName(), vHeightDepth.getFullName()));
    Map<OmObservableProperty, Variable> obsPropVarMap = Maps.newHashMap();
    Map<Variable, Array> varDataArrayMap = Maps.newHashMap();
    for (OmObservableProperty obsProp : sensorDataset.getPhenomena()) {
        // obs prop var
        Variable vObsProp = addVariableForObservedProperty(writer, obsProp, obsPropDims, coordinateString);
        obsPropVarMap.put(obsProp, vObsProp);
        // init obs prop data array
        Array obsPropArray = getArray(obsPropDims);
        initArrayWithFillValue(obsPropArray, getNetcdfHelper().getFillValue());
        varDataArrayMap.put(vObsProp, obsPropArray);
    }
    // populate heights array for profile
    Array heightDephtArray = null;
    if (zDims.size() == 1 && hasDimension(zDims, dZ) && !sensorDataset.getSubSensors().isEmpty()) {
        heightDephtArray = initHeightDephtArray(zDims);
        Double consistentBinHeight = populateHeightDepthArray(sensorDataset, heightDephtArray, vHeightDepth);
        String verticalResolution = null;
        if (consistentBinHeight == null) {
            verticalResolution = ACDDConstants.POINT;
        } else if (consistentBinHeight != getNetcdfHelper().getFillValue()) {
            verticalResolution = consistentBinHeight + " " + CFConstants.UNITS_METERS + " " + ACDDConstants.BINNED;
        }
        if (verticalResolution != null) {
            writer.addGroupAttribute(null, new Attribute(ACDDConstants.GEOSPATIAL_VERTICAL_RESOLUTION, verticalResolution));
        }
    }
    // iterate through sensorDataset, set values
    int timeCounter = 0;
    for (Time time : sensorDataset.getTimes()) {
        // set time value
        Index timeIndex = timeArray.getIndex();
        int timeIndexCounter = 0;
        // }
        if (hasDimension(timeDims, dTime)) {
            timeIndex.setDim(timeIndexCounter++, timeCounter++);
        }
        timeArray.set(timeIndex, getTimeValue(time));
        // data values
        Map<OmObservableProperty, Map<SubSensor, Value<?>>> obsPropMap = sensorDataset.getDataValues().get(time);
        for (Entry<OmObservableProperty, Map<SubSensor, Value<?>>> entry : obsPropMap.entrySet()) {
            OmObservableProperty obsProp = entry.getKey();
            Variable variable = obsPropVarMap.get(obsProp);
            Array array = varDataArrayMap.get(variable);
            for (Entry<SubSensor, Value<?>> subSensorEntry : obsPropMap.get(obsProp).entrySet()) {
                SubSensor subSensor = subSensorEntry.getKey();
                Value<?> value = subSensorEntry.getValue();
                Object valObj = value.getValue();
                if (!(valObj instanceof Number)) {
                    throw new EncodingException("Value class %s not supported", valObj.getClass().getCanonicalName());
                }
                Index index = array.getIndex();
                int obsPropDimCounter = 0;
                for (Dimension dim : obsPropDims) {
                    // } else if (dim.equals(dTime)){
                    if (dim.equals(dTime)) {
                        // time index dim
                        index.setDim(obsPropDimCounter++, timeCounter - 1);
                    } else if (dim.equals(dZ) && dim.getLength() > 1) {
                        // height/depth index dim
                        index.setDim(obsPropDimCounter++, sensorDataset.getSubSensors().indexOf(subSensor));
                    }
                }
                if (array instanceof ArrayFloat) {
                    ((ArrayFloat) array).set(index, ((Number) valObj).floatValue());
                } else {
                    ((ArrayDouble) array).set(index, ((Number) valObj).doubleValue());
                }
            }
        }
    }
    // create the empty netCDF with dims/vars/attributes defined
    variableArrayMap.put(vTime, timeArray);
    if (latArray != null) {
        variableArrayMap.put(vLat, latArray);
    }
    if (lonArray != null) {
        variableArrayMap.put(vLon, lonArray);
    }
    if (heightDephtArray != null) {
        variableArrayMap.put(vHeightDepth, heightDephtArray);
    }
    variableArrayMap.putAll(varDataArrayMap);
    // create the empty netCDF with dims/vars/attributes defined
    writeToFile(writer, variableArrayMap);
    writer.close();
}
Also used : Variable(ucar.nc2.Variable) Attribute(ucar.nc2.Attribute) EncodingException(org.n52.svalbard.encode.exception.EncodingException) Time(org.n52.shetland.ogc.gml.time.Time) DateTime(org.joda.time.DateTime) Index(ucar.ma2.Index) ArrayFloat(ucar.ma2.ArrayFloat) ArrayDouble(ucar.ma2.ArrayDouble) ProfileSubSensor(org.n52.sos.netcdf.data.subsensor.ProfileSubSensor) SubSensor(org.n52.sos.netcdf.data.subsensor.SubSensor) BinProfileSubSensor(org.n52.sos.netcdf.data.subsensor.BinProfileSubSensor) OmObservableProperty(org.n52.shetland.ogc.om.OmObservableProperty) Dimension(ucar.nc2.Dimension) ArrayDouble(ucar.ma2.ArrayDouble) NetcdfFileWriter(ucar.nc2.NetcdfFileWriter) Array(ucar.ma2.Array) StaticLocationDataset(org.n52.sos.netcdf.data.dataset.StaticLocationDataset) Value(org.n52.shetland.ogc.om.values.Value) Map(java.util.Map)

Example 3 with SubSensor

use of org.n52.sos.netcdf.data.subsensor.SubSensor in project SOS by 52North.

the class NetCDFUtil method processObservation.

default void processObservation(OmObservation sosObs, SetMultimap<String, OmObservableProperty> sensorPhens, Map<String, AbstractFeature> sensorProcedure, SetMultimap<String, Double> sensorLngs, SetMultimap<String, Double> sensorLats, SetMultimap<String, Double> sensorHeights, Map<String, Map<Time, Map<OmObservableProperty, Map<SubSensor, Value<?>>>>> obsValuesMap) throws EncodingException {
    OmObservationConstellation obsConst = sosObs.getObservationConstellation();
    // first, resolve the procId to an asset type
    String sensor = obsConst.getProcedure().getIdentifier();
    if (!sensorProcedure.containsKey(sensor)) {
        sensorProcedure.put(sensor, obsConst.getProcedure());
    }
    AbstractPhenomenon absPhen = obsConst.getObservableProperty();
    Map<String, OmObservableProperty> phenomenaMap = new HashMap<>();
    if (absPhen instanceof OmCompositePhenomenon) {
        for (OmObservableProperty phen : ((OmCompositePhenomenon) absPhen).getPhenomenonComponents()) {
            // TODO should the unit be set like this? seems sketchy
            if (phen.getUnit() == null && sosObs.getValue() != null && sosObs.getValue().getValue() != null && sosObs.getValue().getValue().getUnit() != null) {
                phen.setUnit(sosObs.getValue().getValue().getUnit());
            }
            phenomenaMap.put(phen.getIdentifier(), phen);
        }
    } else {
        OmObservableProperty phen = (OmObservableProperty) absPhen;
        // TODO should the unit be set like this? seems sketchy
        if (phen.getUnit() == null && sosObs.getValue() != null && sosObs.getValue().getValue() != null && sosObs.getValue().getValue().getUnit() != null) {
            phen.setUnit(sosObs.getValue().getValue().getUnit());
        }
        phenomenaMap.put(phen.getIdentifier(), phen);
    }
    List<OmObservableProperty> phenomena = new ArrayList<>(phenomenaMap.values());
    sensorPhens.putAll(sensor, phenomena);
    // get foi
    AbstractFeature aFoi = obsConst.getFeatureOfInterest();
    if (!(aFoi instanceof AbstractSamplingFeature)) {
        throw new EncodingException("Encountered a feature which isn't a SamplingFeature");
    }
    AbstractSamplingFeature foi = (AbstractSamplingFeature) aFoi;
    for (Point point : FeatureUtil.getFeaturePoints(foi)) {
        try {
            // TODO is this correct?
            Point p = (Point) getGeometryHandler().switchCoordinateAxisFromToDatasourceIfNeeded(point);
            sensorLngs.put(sensor, p.getX());
            sensorLats.put(sensor, p.getY());
        } catch (OwsExceptionReport e) {
            throw new EncodingException("Exception while normalizing feature coordinate axis order.", e);
        }
    }
    Set<Double> featureHeights = FeatureUtil.getFeatureHeights(foi);
    sensorHeights.putAll(sensor, featureHeights);
    String phenId = obsConst.getObservableProperty().getIdentifier();
    ObservationValue<?> iObsValue = sosObs.getValue();
    if (!(iObsValue instanceof SingleObservationValue)) {
        throw new EncodingException("Only SingleObservationValues are supported.");
    }
    SingleObservationValue<?> singleObsValue = (SingleObservationValue<?>) iObsValue;
    Time obsTime = singleObsValue.getPhenomenonTime();
    // TODO Quality
    Value<?> obsValue = singleObsValue.getValue();
    if (!(obsValue instanceof QuantityValue)) {
        throw new EncodingException("Only QuantityValues are supported.");
    }
    QuantityValue quantityValue = (QuantityValue) obsValue;
    // axes shouldn't be composite phenomena
    if (phenomena.size() == 1) {
        OmObservableProperty phenomenon = phenomena.get(0);
        // add dimensional values to procedure dimension tracking maps
        if (isLng(phenomenon.getIdentifier())) {
            sensorLngs.get(sensor).add(quantityValue.getValue().doubleValue());
        }
        if (isLat(phenomenon.getIdentifier())) {
            sensorLats.get(sensor).add(quantityValue.getValue().doubleValue());
        }
        if (isZ(phenomenon.getIdentifier())) {
            Double zValue = quantityValue.getValue().doubleValue();
            sensorHeights.get(sensor).add(zValue);
        }
    }
    // check for samplingGeometry in observation
    if (sosObs.isSetParameter()) {
        if (sosObs.isSetHeightDepthParameter()) {
            if (sosObs.isSetHeightParameter()) {
                sensorHeights.get(sensor).add(sosObs.getHeightParameter().getValue().getValue().doubleValue());
            } else if (sosObs.isSetDepthParameter()) {
                sensorHeights.get(sensor).add(sosObs.getDepthParameter().getValue().getValue().doubleValue());
            }
        }
        if (hasSamplingGeometry(sosObs)) {
            Geometry geometry = getSamplingGeometryGeometry(sosObs);
            Set<Point> points = FeatureUtil.getPoints(geometry);
            for (Point point : points) {
                try {
                    Point p = (Point) getGeometryHandler().switchCoordinateAxisFromToDatasourceIfNeeded(point);
                    sensorLngs.put(sensor, p.getX());
                    sensorLats.put(sensor, p.getY());
                } catch (OwsExceptionReport e) {
                    throw new EncodingException("Exception while normalizing sampling geometry coordinate axis order.");
                }
            }
            sensorHeights.putAll(sensor, FeatureUtil.getHeights(points));
        }
    }
    // get the sensor's data map
    Map<Time, Map<OmObservableProperty, Map<SubSensor, Value<?>>>> sensorObsMap = obsValuesMap.get(sensor);
    if (sensorObsMap == null) {
        sensorObsMap = new HashMap<>();
        obsValuesMap.put(sensor, sensorObsMap);
    }
    // get the map of the asset's phenomena by time
    Map<OmObservableProperty, Map<SubSensor, Value<?>>> obsPropMap = sensorObsMap.get(obsTime);
    if (obsPropMap == null) {
        obsPropMap = new HashMap<>();
        sensorObsMap.put(obsTime, obsPropMap);
    }
    OmObservableProperty phen = phenomenaMap.get(phenId);
    Map<SubSensor, Value<?>> subSensorMap = obsPropMap.get(phen);
    if (subSensorMap == null) {
        subSensorMap = new HashMap<>();
        obsPropMap.put(phen, subSensorMap);
    }
    // add obs value to subsensor map (null subsensors are ok)
    if (sosObs.isSetParameter() && hasSamplingGeometry(sosObs)) {
        subSensorMap.put(createSubSensor(sensor, getSamplingGeometryGeometry(sosObs)), obsValue);
    } else {
        subSensorMap.put(createSubSensor(sensor, foi), obsValue);
    }
}
Also used : AbstractSamplingFeature(org.n52.shetland.ogc.om.features.samplingFeatures.AbstractSamplingFeature) HashMap(java.util.HashMap) EncodingException(org.n52.svalbard.encode.exception.EncodingException) ArrayList(java.util.ArrayList) Time(org.n52.shetland.ogc.gml.time.Time) LineString(org.locationtech.jts.geom.LineString) SingleObservationValue(org.n52.shetland.ogc.om.SingleObservationValue) PointProfileSubSensor(org.n52.sos.netcdf.data.subsensor.PointProfileSubSensor) BinProfileSubSensor(org.n52.sos.netcdf.data.subsensor.BinProfileSubSensor) SubSensor(org.n52.sos.netcdf.data.subsensor.SubSensor) OmObservableProperty(org.n52.shetland.ogc.om.OmObservableProperty) OmCompositePhenomenon(org.n52.shetland.ogc.om.OmCompositePhenomenon) AbstractFeature(org.n52.shetland.ogc.gml.AbstractFeature) Point(org.locationtech.jts.geom.Point) OmObservationConstellation(org.n52.shetland.ogc.om.OmObservationConstellation) Geometry(org.locationtech.jts.geom.Geometry) AbstractPhenomenon(org.n52.shetland.ogc.om.AbstractPhenomenon) QuantityValue(org.n52.shetland.ogc.om.values.QuantityValue) SingleObservationValue(org.n52.shetland.ogc.om.SingleObservationValue) StreamingValue(org.n52.shetland.ogc.om.StreamingValue) QuantityValue(org.n52.shetland.ogc.om.values.QuantityValue) ObservationValue(org.n52.shetland.ogc.om.ObservationValue) GeometryValue(org.n52.shetland.ogc.om.values.GeometryValue) NamedValue(org.n52.shetland.ogc.om.NamedValue) Value(org.n52.shetland.ogc.om.values.Value) OwsExceptionReport(org.n52.shetland.ogc.ows.exception.OwsExceptionReport) HashMap(java.util.HashMap) Map(java.util.Map)

Example 4 with SubSensor

use of org.n52.sos.netcdf.data.subsensor.SubSensor in project SOS by 52North.

the class NetCDFUtil method createNetCDFSosObservations.

/**
 * Organizes OmObservation collection into a list of NetCDFObservation
 * blocks, each of which contain a single feature type
 *
 * @param omObservations
 *            The collection of observations to transform
 * @return List&lt;NetCDFObservation&gt; ready for encoding
 * @throws EncodingException
 *             if an error occurs
 */
default List<NetCDFObservation> createNetCDFSosObservations(ObservationStream omObservations) throws EncodingException, OwsExceptionReport {
    // the main map of observation value strings by asset, time, phenomenon,
    // and subsensor (height, profile bin, etc)
    Map<String, Map<Time, Map<OmObservableProperty, Map<SubSensor, Value<?>>>>> obsValuesMap = new HashMap<>();
    SetMultimap<String, OmObservableProperty> sensorPhens = HashMultimap.create();
    Map<String, AbstractFeature> sensorProcedure = Maps.newHashMap();
    // Map<StationAsset,TimePeriod> stationPeriodMap = new
    // HashMap<StationAsset,TimePeriod>();
    // maps to keep track of unique dimension values by sensor (these may or
    // may not vary, determining the feature type)
    SetMultimap<String, Double> sensorLngs = HashMultimap.create();
    SetMultimap<String, Double> sensorLats = HashMultimap.create();
    SetMultimap<String, Double> sensorHeights = HashMultimap.create();
    while (omObservations.hasNext()) {
        OmObservation sosObs = omObservations.next();
        if (sosObs.getValue() instanceof StreamingValue<?>) {
            StreamingValue<?> streaming = (StreamingValue<?>) sosObs.getValue();
            while (streaming.hasNext()) {
                processObservation(streaming.next(), sensorPhens, sensorProcedure, sensorLngs, sensorLats, sensorHeights, obsValuesMap);
            }
        } else {
            processObservation(sosObs, sensorPhens, sensorProcedure, sensorLngs, sensorLats, sensorHeights, obsValuesMap);
        }
    }
    // now we know about each station's dimensions, sort into CF feature
    // types
    // sampling time periods
    // TimePeriod pointSamplingTimePeriod = new TimePeriod();
    TimePeriod timeSeriesSamplingTimePeriod = new TimePeriod();
    // TimePeriod profileSamplingTimePeriod = new TimePeriod();
    TimePeriod timeSeriesProfileSamplingTimePeriod = new TimePeriod();
    TimePeriod trajectorySamplingTimePeriod = new TimePeriod();
    TimePeriod trajectoryProfileSamplingTimePeriod = new TimePeriod();
    // station datasets
    // Map<SensorAsset,PointSensorDataset> pointSensorDatasets =
    // new HashMap<SensorAsset,PointSensorDataset>();
    Map<String, TimeSeriesSensorDataset> timeSeriesSensorDatasets = new HashMap<>();
    // Map<SensorAsset,ProfileSensorDataset> profileSensorDatasets =
    // new HashMap<SensorAsset,ProfileSensorDataset>();
    Map<String, TimeSeriesProfileSensorDataset> timeSeriesProfileSensorDatasets = new HashMap<>();
    Map<String, TrajectorySensorDataset> trajectorySensorDatasets = new HashMap<>();
    Map<String, TrajectoryProfileSensorDataset> trajectoryProfileSensorDatasets = new HashMap<>();
    // phenomena
    // Set<OmObservableProperty> pointPhenomena = new
    // HashSet<OmObservableProperty>();
    Set<OmObservableProperty> timeSeriesPhenomena = new HashSet<>();
    // Set<OmObservableProperty> profilePhenomena = new
    // HashSet<OmObservableProperty>();
    Set<OmObservableProperty> timeSeriesProfilePhenomena = new HashSet<>();
    Set<OmObservableProperty> trajectoryPhenomena = new HashSet<>();
    Set<OmObservableProperty> trajectoryProfilePhenomena = new HashSet<>();
    // envelopes
    // Envelope pointEnvelope = new Envelope();
    Envelope timeSeriesEnvelope = new Envelope();
    // Envelope profileEnvelope = new Envelope();
    Envelope timeSeriesProfileEnvelope = new Envelope();
    Envelope trajectoryEnvelope = new Envelope();
    Envelope trajectoryProfileEnvelope = new Envelope();
    for (Map.Entry<String, Map<Time, Map<OmObservableProperty, Map<SubSensor, Value<?>>>>> obsValuesEntry : obsValuesMap.entrySet()) {
        IdentifierDatasetSensor datasetSensor = new IdentifierDatasetSensor(obsValuesEntry.getKey());
        String sensor = datasetSensor.getSensorIdentifier();
        Set<Time> sensorTimes = obsValuesEntry.getValue().keySet();
        int lngCount = sensorLngs.get(sensor).size();
        int latCount = sensorLats.get(sensor).size();
        int heightCount = sensorHeights.get(sensor).size();
        // int timeCount = sensorTimes.size();
        boolean locationVaries = lngCount > 0 && latCount > 0 && (lngCount > 1 || latCount > 1);
        boolean heightVaries = heightCount > 1;
        // boolean timeVaries = timeCount > 1;
        // set static dimension values where applicable
        Double staticLng = null;
        Double staticLat = null;
        Double staticHeight = null;
        // Time staticTime = null;
        if (!locationVaries) {
            if (!sensorLngs.get(sensor).isEmpty()) {
                staticLng = sensorLngs.get(sensor).iterator().next();
            }
            if (!sensorLats.get(sensor).isEmpty()) {
                staticLat = sensorLats.get(sensor).iterator().next();
            }
        }
        if (!heightVaries) {
            if (!sensorHeights.get(sensor).isEmpty()) {
                staticHeight = sensorHeights.get(sensor).iterator().next();
            }
        }
        // } else if( !locationVaries && !heightVaries && timeVaries){
        if (!locationVaries && !heightVaries) {
            // time series
            timeSeriesSamplingTimePeriod.extendToContain(sensorTimes);
            timeSeriesSensorDatasets.put(sensor, new TimeSeriesSensorDataset(datasetSensor, staticLng, staticLat, staticHeight, obsValuesEntry.getValue(), sensorProcedure.get(sensor)));
            timeSeriesPhenomena.addAll(sensorPhens.get(sensor));
            if (staticLng != null && staticLat != null) {
                timeSeriesEnvelope.expandToInclude(staticLng, staticLat);
            }
        } else if (!locationVaries && heightVaries) {
            // time series profile
            timeSeriesProfileSamplingTimePeriod.extendToContain(sensorTimes);
            timeSeriesProfileSensorDatasets.put(sensor, new TimeSeriesProfileSensorDataset(datasetSensor, staticLng, staticLat, obsValuesEntry.getValue(), sensorProcedure.get(sensor)));
            timeSeriesProfilePhenomena.addAll(sensorPhens.get(sensor));
            if (staticLng != null && staticLat != null) {
                timeSeriesProfileEnvelope.expandToInclude(staticLng, staticLat);
            }
        } else if (locationVaries && !heightVaries) {
            // trajectory
            trajectorySamplingTimePeriod.extendToContain(sensorTimes);
            trajectorySensorDatasets.put(sensor, new TrajectorySensorDataset(datasetSensor, staticHeight, obsValuesEntry.getValue(), sensorProcedure.get(sensor)));
            trajectoryPhenomena.addAll(sensorPhens.get(sensor));
            expandEnvelopeToInclude(trajectoryEnvelope, sensorLngs.get(sensor), sensorLats.get(sensor));
        } else if (locationVaries && heightVaries) {
            // trajectory profile
            trajectoryProfileSamplingTimePeriod.extendToContain(sensorTimes);
            trajectoryProfileSensorDatasets.put(sensor, new TrajectoryProfileSensorDataset(datasetSensor, obsValuesEntry.getValue(), sensorProcedure.get(sensor)));
            trajectoryProfilePhenomena.addAll(sensorPhens.get(sensor));
            expandEnvelopeToInclude(trajectoryProfileEnvelope, sensorLngs.get(sensor), sensorLats.get(sensor));
        }
    }
    // build NetCDFObservations
    List<NetCDFObservation> iSosObsList = new ArrayList<>(timeSeriesSensorDatasets.size() + timeSeriesProfileSensorDatasets.size() + trajectorySensorDatasets.size() + trajectoryProfileSensorDatasets.size());
    // timeSeries
    if (timeSeriesSensorDatasets.size() > 0) {
        iSosObsList.add(new NetCDFObservation(CF.FeatureType.timeSeries, timeSeriesSamplingTimePeriod, timeSeriesSensorDatasets, timeSeriesPhenomena, timeSeriesEnvelope));
    }
    // time series profile
    if (timeSeriesProfileSensorDatasets.size() > 0) {
        iSosObsList.add(new NetCDFObservation(CF.FeatureType.timeSeriesProfile, timeSeriesProfileSamplingTimePeriod, timeSeriesProfileSensorDatasets, timeSeriesProfilePhenomena, timeSeriesProfileEnvelope));
    }
    // trajectory
    if (trajectorySensorDatasets.size() > 0) {
        iSosObsList.add(new NetCDFObservation(CF.FeatureType.trajectory, trajectorySamplingTimePeriod, trajectorySensorDatasets, trajectoryPhenomena, trajectoryEnvelope));
    }
    // trajectoryProfile
    if (trajectoryProfileSensorDatasets.size() > 0) {
        iSosObsList.add(new NetCDFObservation(CF.FeatureType.trajectoryProfile, trajectoryProfileSamplingTimePeriod, trajectoryProfileSensorDatasets, trajectoryProfilePhenomena, trajectoryProfileEnvelope));
    }
    return iSosObsList;
}
Also used : TrajectorySensorDataset(org.n52.sos.netcdf.data.dataset.TrajectorySensorDataset) HashMap(java.util.HashMap) StreamingValue(org.n52.shetland.ogc.om.StreamingValue) OmObservation(org.n52.shetland.ogc.om.OmObservation) ArrayList(java.util.ArrayList) Time(org.n52.shetland.ogc.gml.time.Time) LineString(org.locationtech.jts.geom.LineString) Envelope(org.locationtech.jts.geom.Envelope) IdentifierDatasetSensor(org.n52.sos.netcdf.data.dataset.IdentifierDatasetSensor) OmObservableProperty(org.n52.shetland.ogc.om.OmObservableProperty) HashSet(java.util.HashSet) TimeSeriesProfileSensorDataset(org.n52.sos.netcdf.data.dataset.TimeSeriesProfileSensorDataset) TimePeriod(org.n52.shetland.ogc.gml.time.TimePeriod) AbstractFeature(org.n52.shetland.ogc.gml.AbstractFeature) Point(org.locationtech.jts.geom.Point) TimeSeriesSensorDataset(org.n52.sos.netcdf.data.dataset.TimeSeriesSensorDataset) TrajectoryProfileSensorDataset(org.n52.sos.netcdf.data.dataset.TrajectoryProfileSensorDataset) HashMap(java.util.HashMap) Map(java.util.Map) NetCDFObservation(org.n52.sos.netcdf.om.NetCDFObservation)

Aggregations

Map (java.util.Map)3 Time (org.n52.shetland.ogc.gml.time.Time)3 OmObservableProperty (org.n52.shetland.ogc.om.OmObservableProperty)3 BinProfileSubSensor (org.n52.sos.netcdf.data.subsensor.BinProfileSubSensor)3 SubSensor (org.n52.sos.netcdf.data.subsensor.SubSensor)3 EncodingException (org.n52.svalbard.encode.exception.EncodingException)3 ArrayList (java.util.ArrayList)2 HashMap (java.util.HashMap)2 LineString (org.locationtech.jts.geom.LineString)2 Point (org.locationtech.jts.geom.Point)2 AbstractFeature (org.n52.shetland.ogc.gml.AbstractFeature)2 StreamingValue (org.n52.shetland.ogc.om.StreamingValue)2 Value (org.n52.shetland.ogc.om.values.Value)2 ProfileSubSensor (org.n52.sos.netcdf.data.subsensor.ProfileSubSensor)2 ArrayDouble (ucar.ma2.ArrayDouble)2 HashSet (java.util.HashSet)1 DateTime (org.joda.time.DateTime)1 Envelope (org.locationtech.jts.geom.Envelope)1 Geometry (org.locationtech.jts.geom.Geometry)1 TimePeriod (org.n52.shetland.ogc.gml.time.TimePeriod)1