use of org.n52.sos.netcdf.data.dataset.StaticLocationDataset in project SOS by 52North.
the class AbstractNetcdfEncoder method getLatitudeArray.
protected Array getLatitudeArray(AbstractSensorDataset sensorDataset) throws EncodingException {
if (sensorDataset instanceof StaticLocationDataset) {
StaticLocationDataset locationDataset = (StaticLocationDataset) sensorDataset;
if (locationDataset.getLat() != null) {
Array array = getArray();
initArrayWithFillValue(array, getNetcdfHelper().getFillValue());
Index index = array.getIndex();
index.set(0);
array.setDouble(index, locationDataset.getLat());
}
} else {
// TODO support varying lat
throw new EncodingException("Varying lat are not yet supported.");
}
return null;
}
use of org.n52.sos.netcdf.data.dataset.StaticLocationDataset in project SOS by 52North.
the class AbstractNetcdfEncoder method getLongitudeArray.
protected Array getLongitudeArray(AbstractSensorDataset sensorDataset) throws EncodingException {
if (sensorDataset instanceof StaticLocationDataset) {
StaticLocationDataset locationDataset = (StaticLocationDataset) sensorDataset;
if (locationDataset.getLat() != null) {
Array array = getArray();
initArrayWithFillValue(array, getNetcdfHelper().getFillValue());
Index index = array.getIndex();
index.set(0);
array.setDouble(index, locationDataset.getLat());
}
} else {
// TODO support varying lat
throw new EncodingException("Varying longs are not yet supported.");
}
return null;
}
use of org.n52.sos.netcdf.data.dataset.StaticLocationDataset in project SOS by 52North.
the class AbstractNetcdfEncoder method addGeospatialAttributes.
protected void addGeospatialAttributes(NetcdfFileWriter writer, AbstractSensorDataset sensorDataset) throws EncodingException {
// AbstractSensorDataset during construction
if (sensorDataset instanceof StaticLocationDataset) {
StaticLocationDataset LocationDataset = (StaticLocationDataset) sensorDataset;
writer.addGroupAttribute(null, new Attribute(ACDDConstants.GEOSPATIAL_LAT_MIN, LocationDataset.getLat()));
writer.addGroupAttribute(null, new Attribute(ACDDConstants.GEOSPATIAL_LAT_MAX, LocationDataset.getLat()));
writer.addGroupAttribute(null, new Attribute(ACDDConstants.GEOSPATIAL_LAT_UNITS, CFConstants.UNITS_DEGREES_NORTH));
writer.addGroupAttribute(null, new Attribute(ACDDConstants.GEOSPATIAL_LON_MIN, LocationDataset.getLng()));
writer.addGroupAttribute(null, new Attribute(ACDDConstants.GEOSPATIAL_LON_MAX, LocationDataset.getLng()));
writer.addGroupAttribute(null, new Attribute(ACDDConstants.GEOSPATIAL_LON_UNITS, CFConstants.UNITS_DEGREES_EAST));
} else {
throw new EncodingException("Trajectory encoding is not supported (bbox)");
}
}
use of org.n52.sos.netcdf.data.dataset.StaticLocationDataset 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();
}
Aggregations