Exemple #1
0
 /**
  * Returns the default value for elevation dimension.
  *
  * @param resourceInfo
  * @return
  */
 public Double getDefaultElevation(ResourceInfo resourceInfo) {
   DimensionInfo elevation =
       resourceInfo.getMetadata().get(ResourceInfo.ELEVATION, DimensionInfo.class);
   if (elevation == null || !elevation.isEnabled()) {
     throw new ServiceException(
         "Layer " + resourceInfo.prefixedName() + " does not have elevation support enabled");
   }
   DimensionDefaultValueSelectionStrategy strategy =
       this.getDefaultValueStrategy(resourceInfo, ResourceInfo.ELEVATION, elevation);
   return strategy.getDefaultValue(resourceInfo, ResourceInfo.ELEVATION, elevation, Double.class);
 }
Exemple #2
0
 /**
  * Returns the default value for time dimension.
  *
  * @param resourceInfo
  * @return
  */
 public Date getDefaultTime(ResourceInfo resourceInfo) {
   // check the time metadata
   DimensionInfo time = resourceInfo.getMetadata().get(ResourceInfo.TIME, DimensionInfo.class);
   if (time == null || !time.isEnabled()) {
     throw new ServiceException(
         "Layer " + resourceInfo.prefixedName() + " does not have time support enabled");
   }
   DimensionDefaultValueSelectionStrategy strategy =
       this.getDefaultValueStrategy(resourceInfo, ResourceInfo.TIME, time);
   return strategy.getDefaultValue(resourceInfo, ResourceInfo.TIME, time, Date.class);
 }
    /** @param referencedEnvelope */
    private void handleEnvelope(
        ReferencedEnvelope referencedEnvelope,
        DimensionInfo timeInfo,
        ReaderDimensionsAccessor dimensions) {
      AttributesImpl attributes = new AttributesImpl();

      attributes.addAttribute(
          "", "srsName", "srsName", "", /* "WGS84(DD)" */ "urn:ogc:def:crs:OGC:1.3:CRS84");
      start("wcs:lonLatEnvelope", attributes);
      final StringBuffer minCP =
          new StringBuffer(Double.toString(referencedEnvelope.getMinX()))
              .append(" ")
              .append(referencedEnvelope.getMinY());
      final StringBuffer maxCP =
          new StringBuffer(Double.toString(referencedEnvelope.getMaxX()))
              .append(" ")
              .append(referencedEnvelope.getMaxY());

      element("gml:pos", minCP.toString());
      element("gml:pos", maxCP.toString());

      // are we going to report time?
      if (timeInfo != null && timeInfo.isEnabled()) {
        SimpleDateFormat timeFormat = dimensions.getTimeFormat();
        element("gml:timePosition", timeFormat.format(dimensions.getMinTime()));
        element("gml:timePosition", timeFormat.format(dimensions.getMaxTime()));
      }

      end("wcs:lonLatEnvelope");
    }
Exemple #4
0
 /**
  * Returns the default value for the given custom dimension.
  *
  * @param <T>
  * @param dimensionName
  * @param resourceInfo
  * @param clz
  * @return
  */
 public <T> T getDefaultCustomDimensionValue(
     String dimensionName, ResourceInfo resourceInfo, Class<T> clz) {
   DimensionInfo customDim =
       resourceInfo
           .getMetadata()
           .get(ResourceInfo.CUSTOM_DIMENSION_PREFIX + dimensionName, DimensionInfo.class);
   if (customDim == null || !customDim.isEnabled()) {
     throw new ServiceException(
         "Layer "
             + resourceInfo.prefixedName()
             + " does not have support enabled for dimension "
             + dimensionName);
   }
   DimensionDefaultValueSelectionStrategy strategy =
       this.getDefaultValueStrategy(
           resourceInfo, ResourceInfo.CUSTOM_DIMENSION_PREFIX + dimensionName, customDim);
   return strategy.getDefaultValue(
       resourceInfo, ResourceInfo.CUSTOM_DIMENSION_PREFIX + dimensionName, customDim, clz);
 }
    /**
     * 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);
      }
    }
Exemple #7
0
  /**
   * Returns the list of elevation values for the specified typeInfo based on the dimension
   * representation: all values for {@link DimensionPresentation#LIST}, otherwise min and max
   *
   * @param typeInfo
   * @return
   * @throws IOException
   */
  public TreeSet<Double> getFeatureTypeElevations(FeatureTypeInfo typeInfo) throws IOException {
    // grab the time metadata
    DimensionInfo elevation =
        typeInfo.getMetadata().get(ResourceInfo.ELEVATION, DimensionInfo.class);
    if (elevation == null || !elevation.isEnabled()) {
      throw new ServiceException(
          "Layer " + typeInfo.getPrefixedName() + " does not have elevation support enabled");
    }

    FeatureCollection collection = getDimensionCollection(typeInfo, elevation);

    TreeSet<Double> result = new TreeSet<Double>();
    if (elevation.getPresentation() == DimensionPresentation.LIST
        || (elevation.getPresentation() == DimensionPresentation.DISCRETE_INTERVAL
            && elevation.getResolution() == null)) {
      final UniqueVisitor visitor = new UniqueVisitor(elevation.getAttribute());
      collection.accepts(visitor, null);

      @SuppressWarnings("unchecked")
      Set<Object> values = visitor.getUnique();
      if (values.size() <= 0) {
        result = null;
      } else {
        for (Object value : values) {
          result.add(((Number) value).doubleValue());
        }
      }
    } else {
      final MinVisitor min = new MinVisitor(elevation.getAttribute());
      collection.accepts(min, null);
      // check calcresult first to avoid potential IllegalStateException if no features are in
      // collection
      CalcResult calcResult = min.getResult();
      if (calcResult != CalcResult.NULL_RESULT) {
        result.add(((Number) min.getMin()).doubleValue());
        final MaxVisitor max = new MaxVisitor(elevation.getAttribute());
        collection.accepts(max, null);
        result.add(((Number) max.getMax()).doubleValue());
      }
    }

    return result;
  }
Exemple #8
0
  /**
   * Returns the collection of all values of the dimension attribute, eventually sorted if the
   * native capabilities allow for it
   *
   * @param typeInfo
   * @param dimension
   * @return
   * @throws IOException
   */
  FeatureCollection getDimensionCollection(FeatureTypeInfo typeInfo, DimensionInfo dimension)
      throws IOException {
    // grab the feature source
    FeatureSource source = null;
    try {
      source = typeInfo.getFeatureSource(null, GeoTools.getDefaultHints());
    } catch (IOException e) {
      throw new ServiceException(
          "Could not get the feauture source to list time info for layer "
              + typeInfo.getPrefixedName(),
          e);
    }

    // build query to grab the dimension values
    final Query dimQuery = new Query(source.getSchema().getName().getLocalPart());
    dimQuery.setPropertyNames(Arrays.asList(dimension.getAttribute()));
    return source.getFeatures(dimQuery);
  }
Exemple #9
0
  /**
   * Builds a filter for the current time and elevation, should the layer support them. Only one
   * among time and elevation can be multi-valued
   *
   * @param layerFilter
   * @param currentTime
   * @param currentElevation
   * @param mapLayerInfo
   * @return
   */
  public Filter getTimeElevationToFilter(
      List<Object> times, List<Object> elevations, FeatureTypeInfo typeInfo) throws IOException {
    DimensionInfo timeInfo = typeInfo.getMetadata().get(ResourceInfo.TIME, DimensionInfo.class);
    DimensionInfo elevationInfo =
        typeInfo.getMetadata().get(ResourceInfo.ELEVATION, DimensionInfo.class);

    DimensionFilterBuilder builder = new DimensionFilterBuilder(ff);

    // handle time support
    if (timeInfo != null && timeInfo.isEnabled() && times != null) {
      List<Object> defaultedTimes = new ArrayList<Object>(times.size());
      for (Object datetime : times) {
        if (datetime == null) {
          // this is "default"
          datetime = getDefaultTime(typeInfo);
        }
        defaultedTimes.add(datetime);
      }

      builder.appendFilters(timeInfo.getAttribute(), timeInfo.getEndAttribute(), defaultedTimes);
    }

    // handle elevation support
    if (elevationInfo != null && elevationInfo.isEnabled() && elevations != null) {
      List<Object> defaultedElevations = new ArrayList<Object>(elevations.size());
      for (Object elevation : elevations) {
        if (elevation == null) {
          // this is "default"
          elevation = getDefaultElevation(typeInfo);
        }
        defaultedElevations.add(elevation);
      }
      builder.appendFilters(
          elevationInfo.getAttribute(), elevationInfo.getEndAttribute(), defaultedElevations);
    }

    Filter result = builder.getFilter();
    return result;
  }
 /**
  * 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 + "\"") : "");
 }
Exemple #11
0
  /**
   * Returns the list of time values for the specified typeInfo based on the dimension
   * representation: all values for {@link DimensionPresentation#LIST}, otherwise min and max
   *
   * @param typeInfo
   * @return
   * @throws IOException
   */
  public TreeSet<Date> getFeatureTypeTimes(FeatureTypeInfo typeInfo) throws IOException {
    // grab the time metadata
    DimensionInfo time = typeInfo.getMetadata().get(ResourceInfo.TIME, DimensionInfo.class);
    if (time == null || !time.isEnabled()) {
      throw new ServiceException(
          "Layer " + typeInfo.getPrefixedName() + " does not have time support enabled");
    }

    FeatureCollection collection = getDimensionCollection(typeInfo, time);

    TreeSet<Date> result = new TreeSet<Date>();
    if (time.getPresentation() == DimensionPresentation.LIST) {
      final UniqueVisitor visitor = new UniqueVisitor(time.getAttribute());
      collection.accepts(visitor, null);

      @SuppressWarnings("unchecked")
      Set<Date> values = visitor.getUnique();
      if (values.size() <= 0) {
        result = null;
      } else {
        // we might get null values out of the visitor, strip them
        values.remove(null);
        result.addAll(values);
      }
    } else {
      final MinVisitor min = new MinVisitor(time.getAttribute());
      collection.accepts(min, null);
      CalcResult minResult = min.getResult();
      // check calcresult first to avoid potential IllegalStateException if no features are in
      // collection
      if (minResult != CalcResult.NULL_RESULT) {
        result.add((Date) min.getMin());
        final MaxVisitor max = new MaxVisitor(time.getAttribute());
        collection.accepts(max, null);
        result.add((Date) max.getMax());
      }
    }

    return result;
  }
Exemple #12
0
  /**
   * Returns the read parameters for the specified layer, merging some well known request parameters
   * into the read parameters if possible
   *
   * @param request
   * @param mapLayerInfo
   * @param layerFilter
   * @param reader
   * @return
   */
  public GeneralParameterValue[] getWMSReadParameters(
      final GetMapRequest request,
      final MapLayerInfo mapLayerInfo,
      final Filter layerFilter,
      final List<Object> times,
      final List<Object> elevations,
      final GridCoverage2DReader reader,
      boolean readGeom)
      throws IOException {
    // setup the scene
    final ParameterValueGroup readParametersDescriptor = reader.getFormat().getReadParameters();
    CoverageInfo coverage = mapLayerInfo.getCoverage();
    MetadataMap metadata = coverage.getMetadata();
    GeneralParameterValue[] readParameters =
        CoverageUtils.getParameters(readParametersDescriptor, coverage.getParameters(), readGeom);
    ReaderDimensionsAccessor dimensions = new ReaderDimensionsAccessor(reader);
    // pass down time
    final DimensionInfo timeInfo = metadata.get(ResourceInfo.TIME, DimensionInfo.class);
    // add the descriptors for custom dimensions
    final List<GeneralParameterDescriptor> parameterDescriptors =
        new ArrayList<GeneralParameterDescriptor>(
            readParametersDescriptor.getDescriptor().descriptors());
    Set<ParameterDescriptor<List>> dynamicParameters = reader.getDynamicParameters();
    parameterDescriptors.addAll(dynamicParameters);
    if (timeInfo != null && timeInfo.isEnabled()) {
      // handle "default"
      List<Object> fixedTimes = new ArrayList<Object>(times);
      for (int i = 0; i < fixedTimes.size(); i++) {
        if (fixedTimes.get(i) == null) {
          fixedTimes.set(i, getDefaultTime(coverage));
        }
      }
      // pass down the parameters
      readParameters =
          CoverageUtils.mergeParameter(
              parameterDescriptors, readParameters, fixedTimes, "TIME", "Time");
    }

    // pass down elevation
    final DimensionInfo elevationInfo = metadata.get(ResourceInfo.ELEVATION, DimensionInfo.class);
    if (elevationInfo != null && elevationInfo.isEnabled()) {
      // handle "default"
      List<Object> fixedElevations = new ArrayList<Object>(elevations);
      for (int i = 0; i < fixedElevations.size(); i++) {
        if (fixedElevations.get(i) == null) {
          fixedElevations.set(i, getDefaultElevation(coverage));
        }
      }
      readParameters =
          CoverageUtils.mergeParameter(
              parameterDescriptors, readParameters, fixedElevations, "ELEVATION", "Elevation");
    }

    if (layerFilter != null && readParameters != null) {
      // test for default [empty is replaced with INCLUDE filter] ]filter
      for (int i = 0; i < readParameters.length; i++) {

        GeneralParameterValue param = readParameters[i];
        GeneralParameterDescriptor pd = param.getDescriptor();

        if (pd.getName().getCode().equalsIgnoreCase("FILTER")) {
          final ParameterValue pv = (ParameterValue) pd.createValue();
          // if something different from the default INCLUDE filter is specified
          if (layerFilter != Filter.INCLUDE) {
            // override the default filter
            pv.setValue(layerFilter);
            readParameters[i] = pv;
          }
          break;
        }
      }
    }

    // custom dimensions

    List<String> customDomains = new ArrayList(dimensions.getCustomDomains());
    for (String domain : new ArrayList<String>(customDomains)) {
      List<String> values = request.getCustomDimension(domain);
      if (values != null) {
        readParameters =
            CoverageUtils.mergeParameter(parameterDescriptors, readParameters, values, domain);
        customDomains.remove(domain);
      }
    }

    // see if we have any custom domain for which we have to set the default value
    if (!customDomains.isEmpty()) {
      for (String name : customDomains) {
        final DimensionInfo customInfo =
            metadata.get(ResourceInfo.CUSTOM_DIMENSION_PREFIX + name, DimensionInfo.class);
        if (customInfo != null && customInfo.isEnabled()) {
          final ArrayList<String> val = new ArrayList<String>(1);
          val.add(getDefaultCustomDimensionValue(name, coverage, String.class));
          readParameters =
              CoverageUtils.mergeParameter(parameterDescriptors, readParameters, val, name);
        }
      }
    }

    return readParameters;
  }