/** * Set additional dimension metadata to the DescribeCoverage element * * @param name the custom dimension name * @param dimension the custom dimension related {@link DimensionInfo} instance * @param helper the {@link WCSDimensionsHelper} instance to be used to parse domains * @throws IOException */ private void setAdditionalDimensionMetadata( final String name, final DimensionInfo dimension, WCSDimensionsHelper helper) throws IOException { Utilities.ensureNonNull("helper", helper); final String startTag = initStartMetadataTag(TAG.ADDITIONAL_DIMENSION, name, dimension, helper); start(startTag); // Custom dimension only supports List presentation final List<String> domain = helper.getDomain(name); // TODO: check if we are in the list of instants case, or in the list of periods case // list case int i = 0; for (String item : domain) { Date date = WCSDimensionsValueParser.parseAsDate(item); if (date != null) { final String dimensionId = helper.getCoverageId() + "_dd_" + i; encodeDate(date, helper, dimensionId); continue; } Double number = WCSDimensionsValueParser.parseAsDouble(item); if (number != null) { element(TAG.SINGLE_VALUE, item.toString()); continue; } NumberRange<Double> range = WCSDimensionsValueParser.parseAsDoubleRange(item); if (range != null) { encodeInterval( range.getMinValue().toString(), range.getMaxValue().toString(), null, null); continue; } // TODO: Add support for date Ranges if (item instanceof String) { element(TAG.SINGLE_VALUE, item.toString()); } // else if (item instanceof DateRange) { // final String dimensionId = helper.getCoverageId() + "_dd_" + i; // encodeDateRange((DateRange) item, helper, dimensionId); // } // TODO: Add more cases i++; } end(TAG.ADDITIONAL_DIMENSION); }
/** * Encode a Date item as a GML TimeInstant * * @param item * @param helper * @param id */ private void encodeDate(final Date item, final WCSDimensionsHelper helper, final String id) { final AttributesImpl atts = new AttributesImpl(); atts.addAttribute("", "gml:id", "gml:id", "", id); start("gml:TimeInstant", atts); element("gml:timePosition", helper.format(item)); end("gml:TimeInstant"); }
/** * Initialize the metadata start tag for a custom dimension, setting dimension name, checking * for UOM, defaultValue, ... * * @param dimensionTag the TAG referring to type of dimension (Time, Elevation, Additional ,...) * @param name the name of the custom dimension * @param dimension the custom dimension {@link DimensionInfo} instance * @param helper the {@link WCSDimensionsHelper} instance used to parse default values * @return * @throws IOException */ private String initStartMetadataTag( final String dimensionTag, final String name, final DimensionInfo dimension, final WCSDimensionsHelper helper) throws IOException { final String uom = dimension.getUnitSymbol(); String defaultValue = null; String prolog = null; if (dimensionTag.equals(TAG.ADDITIONAL_DIMENSION)) { prolog = TAG.ADDITIONAL_DIMENSION + " name = \"" + name + "\""; defaultValue = helper.getDefaultValue(name); } else if (dimensionTag.equals(TAG.ELEVATION_DOMAIN)) { prolog = TAG.ELEVATION_DOMAIN; defaultValue = helper.getBeginElevation(); } else if (dimensionTag.equals(TAG.TIME_DOMAIN)) { prolog = TAG.TIME_DOMAIN; defaultValue = helper.getEndTime(); } return prolog + (uom != null ? (" uom=\"" + uom + "\"") : "") + (defaultValue != null ? (" default=\"" + defaultValue + "\"") : ""); }
/** * Look for additional dimensions in the dimensionsHelper and put additional domains to the * metadata * * @param helper * @throws IOException */ private void handleAdditionalDimensionMetadata(final WCSDimensionsHelper helper) throws IOException { Utilities.ensureNonNull("helper", helper); final Map<String, DimensionInfo> additionalDimensions = helper.getAdditionalDimensions(); final Set<String> dimensionsName = additionalDimensions.keySet(); final Iterator<String> dimensionsIterator = dimensionsName.iterator(); while (dimensionsIterator.hasNext()) { final String dimensionName = dimensionsIterator.next(); final DimensionInfo customDimension = additionalDimensions.get(dimensionName); if (customDimension != null) { setAdditionalDimensionMetadata(dimensionName, customDimension, helper); } } }
/** * Set the timeDomain metadata in case the dimensionsHelper instance has a timeDimension * * @param helper * @throws IOException */ private void handleTimeMetadata(WCSDimensionsHelper helper) throws IOException { Utilities.ensureNonNull("helper", helper); final DimensionInfo timeDimension = helper.getTimeDimension(); if (timeDimension != null) { start(initStartMetadataTag(TAG.TIME_DOMAIN, null, timeDimension, helper)); final DimensionPresentation presentation = timeDimension.getPresentation(); final String id = helper.getCoverageId(); switch (presentation) { case CONTINUOUS_INTERVAL: encodeTimePeriod(helper.getBeginTime(), helper.getEndTime(), id + "_tp_0", null, null); break; case DISCRETE_INTERVAL: encodeTimePeriod( helper.getBeginTime(), helper.getEndTime(), id + "_tp_0", helper.getTimeResolutionUnit(), helper.getTimeResolutionValue()); break; default: // TODO: check if we are in the list of instants case, or in the list of periods case // list case final TreeSet<Object> domain = helper.getTimeDomain(); int i = 0; for (Object item : domain) { // gml:id is mandatory for time instant... if (item instanceof Date) { encodeDate((Date) item, helper, id + "_td_" + i); } else if (item instanceof DateRange) { encodeDateRange((DateRange) item, helper, id + "_td_" + i); } i++; } break; } end(TAG.TIME_DOMAIN); } }
/** * Set the elevationDomain metadata in case the dimensionsHelper instance has an * elevationDimension * * @param helper * @throws IOException */ private void handleElevationMetadata(WCSDimensionsHelper helper) throws IOException { // Null check has been performed in advance final DimensionInfo elevationDimension = helper.getElevationDimension(); if (elevationDimension != null) { start(initStartMetadataTag(TAG.ELEVATION_DOMAIN, null, elevationDimension, helper)); final DimensionPresentation presentation = elevationDimension.getPresentation(); switch (presentation) { // Where _er_ means elevation range case CONTINUOUS_INTERVAL: encodeInterval(helper.getBeginElevation(), helper.getEndElevation(), null, null); break; case DISCRETE_INTERVAL: encodeInterval( helper.getBeginElevation(), helper.getEndElevation(), helper.getElevationResolutionUnit(), helper.getElevationResolutionValue()); break; default: // TODO: check if we are in the list of instants case, or in the list of periods case // list case final TreeSet<Object> domain = helper.getElevationDomain(); for (Object item : domain) { if (item instanceof Number) { element(TAG.SINGLE_VALUE, item.toString()); } else if (item instanceof NumberRange) { NumberRange range = (NumberRange) item; encodeInterval( range.getMinValue().toString(), range.getMaxValue().toString(), null, null); } } break; } end(TAG.ELEVATION_DOMAIN); } }
/** * Encodes the boundedBy element * * <p>e.g.: * * <pre>{@code * <gml:boundedBy> * <gml:Envelope srsName="http://www.opengis.net/def/crs/EPSG/0/4326" axisLabels="Lat Long" uomLabels="deg deg" srsDimension="2"> * <gml:lowerCorner>1 1</gml:lowerCorner> * <gml:upperCorner>5 3</gml:upperCorner> * </gml:Envelope> * </gml:boundedBy> * }</pre> * * @param ci * @param gc2d * @param ePSGCode * @param axisSwap * @param srsName * @param axesNames * @param axisLabels * @throws IOException */ public void handleBoundedBy( final GeneralEnvelope envelope, boolean axisSwap, String srsName, String axisLabels, WCSDimensionsHelper dimensionHelper) throws IOException { final CoordinateReferenceSystem crs = envelope.getCoordinateReferenceSystem(); final CoordinateSystem cs = crs.getCoordinateSystem(); // TODO time String uomLabels = extractUoM(crs, cs.getAxis(axisSwap ? 1 : 0).getUnit()) + " " + extractUoM(crs, cs.getAxis(axisSwap ? 0 : 1).getUnit()); // time and elevation dimensions management boolean hasElevation = false; boolean hasTime = false; if (dimensionHelper != null) { if (dimensionHelper.getElevationDimension() != null) { uomLabels = uomLabels + " m"; // TODO: Check elevation uom hasElevation = true; } if (dimensionHelper.getTimeDimension() != null) { uomLabels = uomLabels + " s"; hasTime = true; } } final int srsDimension = cs.getDimension() + (hasElevation ? 1 : 0); // Setting up envelope bounds (including elevation) final String lower = new StringBuilder() .append(envelope.getLowerCorner().getOrdinate(axisSwap ? 1 : 0)) .append(" ") .append(envelope.getLowerCorner().getOrdinate(axisSwap ? 0 : 1)) .append(hasElevation ? " " + dimensionHelper.getBeginElevation() : "") .toString(); final String upper = new StringBuilder() .append(envelope.getUpperCorner().getOrdinate(axisSwap ? 1 : 0)) .append(" ") .append(envelope.getUpperCorner().getOrdinate(axisSwap ? 0 : 1)) .append(hasElevation ? " " + dimensionHelper.getEndElevation() : "") .toString(); // build the fragment final AttributesImpl envelopeAttrs = new AttributesImpl(); envelopeAttrs.addAttribute("", "srsName", "srsName", "", srsName); envelopeAttrs.addAttribute("", "axisLabels", "axisLabels", "", axisLabels); envelopeAttrs.addAttribute("", "uomLabels", "uomLabels", "", uomLabels); envelopeAttrs.addAttribute( "", "srsDimension", "srsDimension", "", String.valueOf(srsDimension)); start("gml:boundedBy"); String envelopeName; if (dimensionHelper != null && (hasTime || hasElevation)) { envelopeName = "gml:EnvelopeWithTimePeriod"; } else { envelopeName = "gml:Envelope"; } start(envelopeName, envelopeAttrs); element("gml:lowerCorner", lower); element("gml:upperCorner", upper); if (dimensionHelper != null && hasTime) { element("gml:beginPosition", dimensionHelper.getBeginTime()); element("gml:endPosition", dimensionHelper.getEndTime()); } end(envelopeName); end("gml:boundedBy"); }
/** * Encode a DateRange item as a GML TimePeriod * * @param range * @param helper * @param id */ private void encodeDateRange( final DateRange range, final WCSDimensionsHelper helper, final String id) { encodeTimePeriod( helper.format(range.getMinValue()), helper.format(range.getMaxValue()), id, null, null); }