On Fri, Feb 17, 2012 at 12:19 AM, Mike Benowitz <michael.benowitz@anonymised.com> wrote:
Andrea,
Thanks for your reply. Regarding the three concerns you expressed:
- I think distinguishing dimension metadata from other random metadata can
be handled without changing the API or relying on a naming convention. From
what I can tell, dimension entries in the coverage.xml file are
distinguished by the dimensionInfo element, which gets translated to a
DimensionInfo (or more specifically,
org.geoserver.catalog.impl.DimensionInfoImpl) value in the corresponding
entry in the MetadataMap received by DimensionHelper. The modified
DimensionHelper should be able to scan the MetadataMap for all entries whose
values are assignable to type DimensionInfo, and process only those entries
as dimensions.
- It’s true that the core logic would not be able to assume the data type
for non-standard dimensions, but this does not seem particularly
problematic. We could include processing to recognize whether strings are
numeric and if so convert them to Double, or whether they are in a
recognizable date/time format and if so convert them to Date. In any case,
it seems reasonable that values that are not in a recognized format would
just be treated as strings, and the interpretation left to the custom
plugin/client.
That works once things are configured, but how does a user configure
dimensions from the GUI or from REST config, which mind, are the
only supported configuration mechanisms? (you directly writing the files
is not a supported way, the on disk file format can and will change without
warning).
GUI wise, when you are configuring the custom dimensions, how do you
provide a list of valid values to the end user?
If you look at the DimensionEditor class you’ll see there is a check like the
following that enables/disables the possibility to configure dimensions;
GridCoverageReader reader = ((CoverageInfo) resource).getGridCoverageReader(null, null);
if(Number.class.isAssignableFrom(type)) {
String elev = reader.getMetadataValue(AbstractGridCoverage2DReader.HAS_ELEVATION_DOMAIN);
if(!Boolean.parseBoolean(elev)) {
disableDimension(type, configs, noAttributeMessage);
}
} else if(Date.class.isAssignableFrom(type)) {
String time = reader.getMetadataValue(AbstractGridCoverage2DReader.HAS_TIME_DOMAIN);
if(!Boolean.parseBoolean(time)) {
disableDimension(type, configs, noAttributeMessage);
}
}
The GUI must have a way to list the available dimensions, out of the canonical
ones, and allow the user to enable them.
An acceptable approach is to mimick the existing metadata keys:
/**
- The time domain (comma separated list of values)
*/
public static final String TIME_DOMAIN = “TIME_DOMAIN”;
/**
- Time domain resolution (when using min/max/resolution)
*/
public static final String TIME_DOMAIN_RESOLUTION = “TIME_DOMAIN_RESOLUTION”;
/**
- If the time domain is available (or if a min/max/resolution approach has been chosen)
*/
public static final String HAS_TIME_DOMAIN = “HAS_TIME_DOMAIN”;
/**
- The time domain max value
*/
public static final String TIME_DOMAIN_MAXIMUM = “TIME_DOMAIN_MAXIMUM”;
/**
- The time domain min value
*/
public static final String TIME_DOMAIN_MINIMUM = “TIME_DOMAIN_MINIMUM”;
For a custom dimensions we could have the following keys:
CUSTOM_DIMENSIONS (a comma separated list of the dimensions)
_TYPE (Date,Number,String?)
HAS__DOMAIN
_DOMAIN (the only solution for string dimensions)
_RESOLUTION (makes sense only for numeric/time)
_MINIMUM (makes sense only for numeric/time)
_MAXIMUM (makes sense only for numeric/time)
Around the above it should be possible to build all the configuration machinery and
also make meaningful choices when working against the requests coming down
(e.g., you give me a range request with resolution against a dimension with
string values and we can throw back a meaningful service exception)
Mind, whilst there is basically nothing left in core that does not have
a GUI I’m not saying that you have to build the GUI yourself, I’m saying
that whatever solution is chosen it has to allow the construction of a meaningful
GUI.
Speaking of requirements, the changes you are proposing are core ones,
they must be compounded with unit/integration
tests checking that the code is doing the right thing also with the custom
dimensions. See all the Dimensions*Test test classes here:
http://svn.codehaus.org/geoserver/trunk/src/wms/src/test/java/org/geoserver/wms/wms_1_1_1/
http://svn.codehaus.org/geoserver/trunk/src/wms/src/test/java/org/geoserver/wms/wms_1_3/
I don’t mean you have to build that many tests, but there must be some covering
custom dimensions handling. Which also means there must be a reader (even
a mocked up one) in the classpath that reports such dimensions.
If it sounds like a lot of work, consider that if you try to contribute
to the core code you also have to play by the same rules as a core developer.
- I believe the modified DefaultWebCoverageService100.getCoverage method
can handle custom dimensions regardless of whether they are numeric. As it
is now, the axis subset list items (created from the axisSubset elements in
the request document) that are processed by this method are of type
TypedLiteralType, which specifies all values as strings. The ELEVATION
processing assumes that the values can be parsed to numbers, but I don’t see
anything requiring the custom dimension processing to make such an
assumption.
Read the WCS 1.0 spec quickly, the spec only cites numeric cases for
custom dimensions, but yeah, I don’t see it negating the possibility
for non numeric axes.
Cheers
Andrea
–
Ing. Andrea Aime
GeoSolutions S.A.S.
Tech lead
Via Poggio alle Viti 1187
55054 Massarosa (LU)
Italy
phone: +39 0584 962313
fax: +39 0584 962313
mob: +39 339 8844549
http://www.geo-solutions.it
http://geo-solutions.blogspot.com/
http://www.youtube.com/user/GeoSolutionsIT
http://www.linkedin.com/in/andreaaime
http://twitter.com/geowolf