added possiblity to alter the Coverage Band Details of layers & WCS EO tag

This commit is contained in:
rotz_he 2014-01-31 12:04:45 +01:00
parent b5bf46a189
commit 1c60c1d94a
7 changed files with 736 additions and 116 deletions

View File

@ -26,13 +26,13 @@
package it.geosolutions.geoserver.rest.decoder;
import it.geosolutions.geoserver.rest.decoder.utils.JDOMBuilder;
import it.geosolutions.geoserver.rest.encoder.dimensions.GSCoverageDimensionEncoder;
import it.geosolutions.geoserver.rest.encoder.feature.FeatureTypeAttribute;
import it.geosolutions.geoserver.rest.encoder.feature.GSAttributeEncoder;
import it.geosolutions.geoserver.rest.encoder.metadatalink.GSMetadataLinkInfoEncoder;
import it.geosolutions.geoserver.rest.encoder.metadatalink.ResourceMetadataLinkInfo;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -183,4 +183,50 @@ public class RESTResource {
return metaLinksList;
}
/**
* Decodes the list of GSCoverageDimensionEncoder from the GeoServer Resource
*
* @author Henry Rotzoll
*
* @return the list of GSCoverageDimensionEncoder
*/
public List<GSCoverageDimensionEncoder> getEncodedDimensionsInfoList()
{
List<GSCoverageDimensionEncoder> dimensionList = null;
final Element dimensionsRoot = rootElem.getChild("dimensions");
if(dimensionsRoot!=null)
{
final List<Element> dimensions = dimensionsRoot.getChildren();
if (dimensions != null)
{
dimensionList = new ArrayList<GSCoverageDimensionEncoder>(dimensions.size());
for (Element coverageDimension : dimensions)
{
final String name = coverageDimension.getChildText("name");
final String description = coverageDimension.getChildText("description");
String rangeMin = null;
String rangeMax = null;
final Element rangeElement = coverageDimension.getChild("range");
if(rangeElement != null)
{
rangeMin = rangeElement.getChildText("min");
rangeMax = rangeElement.getChildText("max");
}
final String unit = coverageDimension.getChildText("unit");
String dimensionTypeName = null;
final Element dimensionTypeElement = coverageDimension.getChild("dimensionType");
if(dimensionTypeElement != null)
{
dimensionTypeName = dimensionTypeElement.getChildText("name");
}
final GSCoverageDimensionEncoder coverageDimensionEncoder = new GSCoverageDimensionEncoder(name, description, rangeMin, rangeMax, unit, dimensionTypeName);
dimensionList.add(coverageDimensionEncoder);
}
}
}
return dimensionList;
}
}

View File

@ -26,6 +26,7 @@
package it.geosolutions.geoserver.rest.encoder;
import it.geosolutions.geoserver.rest.encoder.coverage.GSCoverageEncoder;
import it.geosolutions.geoserver.rest.encoder.dimensions.GSCoverageDimensionEncoder;
import it.geosolutions.geoserver.rest.encoder.feature.GSFeatureTypeEncoder;
import it.geosolutions.geoserver.rest.encoder.metadata.GSDimensionInfoEncoder;
import it.geosolutions.geoserver.rest.encoder.metadata.GSFeatureDimensionInfoEncoder;
@ -57,10 +58,12 @@ public abstract class GSResourceEncoder
public final static String METADATA="metadata";
public final static String KEYWORDS="keywords";
public final static String METADATALINKS="metadataLinks";
public final static String DIMENSIONS="dimensions";
final private GSMetadataEncoder metadata = new GSMetadataEncoder();
final private Element keywordsListEncoder = new Element(KEYWORDS);
final private Element metadataLinksListEncoder = new Element(METADATALINKS);
final private Element dimensionsEncoder = new Element(DIMENSIONS);
private class GSMetadataEncoder extends NestedElementEncoder{
public GSMetadataEncoder() {
@ -133,6 +136,10 @@ public abstract class GSResourceEncoder
setMetadataDimension(key, dimensionInfo, false);
}
public void setMetadataString(String key, String value) {
metadata.set(key, value);
}
/**
* Set the metadata for a custom dimension.
*
@ -227,6 +234,52 @@ public abstract class GSResourceEncoder
: true;
}
/**
* Adds a CoverageDimensionInfo to the GeoServer Resource
*
* @param coverageDimensionInfo
*
* @author Henry Rotzoll
*/
public void addCoverageDimensionInfo (GSCoverageDimensionEncoder coverageDimensionInfo) {
if(ElementUtils.contains(getRoot(), DIMENSIONS) == null)addContent(dimensionsEncoder);
dimensionsEncoder.addContent(coverageDimensionInfo.getRoot());
}
/**
* Adds quickly a CoverageDimensionInfo to the GeoServer Resource
*
* @author Henry Rotzoll
*
* @param name
* @param description
* @param rangeMin
* @param rangeMax
* @param unit
* @param dimensionType
*/
public void addCoverageDimensionInfo(String name, String description, String rangeMin, String rangeMax, String unit, String dimensionType) {
final GSCoverageDimensionEncoder coverageDimensionEncoder = new GSCoverageDimensionEncoder(
name, description, rangeMin, rangeMax, unit, dimensionType);
addCoverageDimensionInfo(coverageDimensionEncoder);
}
/**
* Deletes a CoverageDimensionInfo from the list using the CoverageDimension Name
* (CoverageDimensionInfo content)
*
* @author Henry Rotzoll
*
* @param coverageDimensionName
* @return true if something is removed, false otherwise
*/
public boolean delCoverageDimensionInfo(final String coverageDimensionName) {
return (dimensionsEncoder
.removeContent(GSCoverageDimensionEncoder
.getFilterByContent(coverageDimensionName))).size() == 0 ? false
: true;
}
/**
* Reprojection policy for a published layer. One of:

View File

@ -0,0 +1,394 @@
/*
* GeoServer-Manager - Simple Manager Library for GeoServer
*
* Copyright (C) 2007,2011 GeoSolutions S.A.S.
* http://www.geo-solutions.it
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package it.geosolutions.geoserver.rest.encoder.dimensions;
import it.geosolutions.geoserver.rest.encoder.utils.ElementUtils;
import it.geosolutions.geoserver.rest.encoder.utils.XmlElement;
import org.jdom.Element;
import org.jdom.filter.Filter;
/**
* GSCoverageDimension - encodes a CoverageDimension for a given GeoServer Resource
* (feature type /coverage), as follows:
* <pre>
* {@code
* final GSCoverageDimensionEncoder gsCoverageDimensionEncoder = new GSCoverageDimensionEncoder("GRAY_INDEX", "GridSampleDimension[-2.147483648E9,-2.147483648E9]", String.valueOf(Integer.MIN_VALUE), String.valueOf(Integer.MAX_VALUE), "dobson units³", "REAL_32BITS");
* coverageEncoder.addCoverageDimensionInfo(gsCoverageDimensionEncoder);
* }
* </pre>
* For this example, the XML output is:
* <pre>
* {@code
*<coverageDimension>
* <name>GRAY_INDEX</name>
* <description>GridSampleDimension[-2.147483648E9,2.147483648E9]</description>
* <range>
* <min>-2.147483648E9</min>
* <max>2.147483647E9</max>
* </range>
* <unit>dobson units³</unit>
* <dimensionType>
* <name>REAL_32BITS</name>
* </dimensionType>
*</coverageDimension>
* }
* </pre>
*
* @author Henry Rotzoll (henry.rotzoll@dlr.de)
*
*/
public class GSCoverageDimensionEncoder extends XmlElement {
/** A class to filter the GSCoverageDimension by content
*
*
*/
private static class filterByContent implements Filter {
final private String key;
public filterByContent(String content) {
this.key = content;
}
private static final long serialVersionUID = 1L;
public boolean matches(Object obj) {
Element el = ((Element) obj)
.getChild("name");
if (el != null && el.getTextTrim().equals(key)) {
return true;
}
return false;
}
}
/**
* Get a Filter using the GSCoverageDimensionEncoder content (GSCoverageDimensionEncoder name)
*
* @param content
* @return the filter
*/
public static Filter getFilterByContent(String content) {
return new filterByContent(content);
}
/**
* Constructs a new GSCoverageDimensionEncoder
*
*/
public GSCoverageDimensionEncoder() {
super("coverageDimension");
}
/**
* Constructs quickly a GSCoverageDimensionEncoder info
*
* @param name
* @param description
* @param rangeMin
* @param rangeMax
* @param unit
* @param dimensionTypeName
*/
public GSCoverageDimensionEncoder(String name, String description, String rangeMin, String rangeMax, String unit, String dimensionTypeName) {
super("coverageDimension");
this.setup(name, description, rangeMin, rangeMax, unit, dimensionTypeName);
}
/**
* Set-up quickly a GSCoverageDimensionEncoder info
*
* @param name
* @param description
* @param rangeMin
* @param rangeMax
* @param unit
* @param dimensionTypeName
*/
protected void setup(String name, String description, String rangeMin, String rangeMax, String unit, String dimensionTypeName)
{
//name
setName(name);
//description
setDescription(description);
//range
setRange(rangeMin, rangeMax);
//unit
setUnit(unit);
//dimension Type
setDimensionType(dimensionTypeName);
}
/**
* Get the value of the GSCoverageDimensionEncoder member
*
* @param memberName
* @return the value of the GSCoverageDimensionEncoder member
*/
protected String getMember(String memberName) {
Element el = this.getRoot().getChild(memberName.toString());
if (el != null)
return el.getTextTrim();
else
return null;
}
/**
* Deletes a GSCoverageDimensionEncoder member
*
* @param memberName
* @return true if the GSCoverageDimensionEncoder member is removed
*/
protected boolean delMemberIfExists(String memberName) {
if(ElementUtils.contains(getRoot(), memberName) != null)
{
return ElementUtils.remove(this.getRoot(), this.getRoot().getChild(memberName.toString()));
}
return false;
}
/**
* Set a GSCoverageDimensionEncoder member
*
* @param memberName
* @param memberValue
*/
protected void setMember(String memberName, String memberValue) {
if(memberName != null && !memberName.isEmpty() && memberValue != null && !memberValue.isEmpty())
{
delMemberIfExists(memberName); //delete the element if it already exists
addMember(memberName.toString(), memberValue);
}
}
/**
* adds a GSCoverageDimensionEncoder member
*
* @param memberName
* @param memberValue
*/
protected void addMember(String memberName, String memberValue) {
if(memberName != null && !memberName.isEmpty() && memberValue != null && ! memberValue.isEmpty())
{
set(memberName.toString(), memberValue);
}
}
/**
* Set the name
*
* @param name
*/
public void setName(String name){
setMember("name", name);
}
/**
* Deletes the name
*
* @param name
* @return true if removed
*/
public boolean delName(){
return this.delMemberIfExists("name");
}
/**
* Get the description
*
* @return description
*/
public String getName(){
return this.getMember("name");
}
/**
* Set the description
*
* @param description
*/
public void setDescription(String description){
setMember("description", description);
}
/**
* Deletes the description
*
* @param description
* @return true if removed
*/
public boolean delDescription(){
return this.delMemberIfExists("description");
}
/**
* Get the description
*
* @return description
*/
public String getDescription(){
return this.getMember("description");
}
/**
* Set the range
*
* @param range
*/
public void setRange(String rangeMin, String rangeMax){
if(rangeMin != null && !rangeMin.isEmpty() && rangeMax != null && !rangeMax.isEmpty())
{
remove("range");
final Element rangeElement = new Element("range");
final Element rangeMinElement = new Element("min");
rangeMinElement.setText(rangeMin);
final Element rangeMaxElement = new Element("max");
rangeMaxElement.setText(rangeMax);
rangeElement.addContent(rangeMinElement);
rangeElement.addContent(rangeMaxElement);
addContent(rangeElement);
}
}
/**
* Deletes the range
*
* @param range
* @return true if removed
*/
public boolean delRange(){
return this.delMemberIfExists("range");
}
/**
* Get the range min
*
* @return range min
*/
public String getRangeMin(){
final Element range = this.getRoot().getChild("range");
if(range != null)
{
return range.getChildText("min");
}
return null;
}
/**
* Get the range max
*
* @return range max
*/
public String getRangeMax(){
final Element range = this.getRoot().getChild("range");
if(range != null)
{
return range.getChildText("max");
}
return null;
}
/**
* Set the unit
*
* @param unit
*/
public void setUnit(String unit){
setMember("unit", unit);
}
/**
* Deletes the type
*
* @param type
* @return true if removed
*/
public boolean delUnit(){
return this.delMemberIfExists("unit");
}
/**
* Get the unit
*
* @return unit
*/
public String getUnit(){
return this.getMember("unit");
}
/**
* Set the dimensionType
*
* @param dimensionType
*/
public void setDimensionType(String dimensionTypeName){
if(dimensionTypeName != null && !dimensionTypeName.isEmpty())
{
remove("dimensionType");
final Element dimensionTypeElement = new Element("dimensionType");
final Element dimensionNameElement = new Element("name");
dimensionNameElement.setText(dimensionTypeName);
dimensionTypeElement.addContent(dimensionNameElement);
addContent(dimensionTypeElement);
}
}
/**
* Deletes the dimensionType
*
* @param dimensionType
* @return true if removed
*/
public boolean delDimensionType(){
return this.delMemberIfExists("dimensionType");
}
/**
* Get the dimensionType name
*
* @return dimensionType name
*/
public String getDimensionTypeName(){
final Element dimensionType = this.getRoot().getChild("dimensionType");
if(dimensionType != null)
{
return dimensionType.getChildText("name");
}
return null;
}
}

View File

@ -1,7 +1,7 @@
package it.geosolutions.geoserver.decoder;
import it.geosolutions.geoserver.rest.decoder.RESTCoverage;
import it.geosolutions.geoserver.rest.encoder.feature.GSAttributeEncoder;
import it.geosolutions.geoserver.rest.encoder.dimensions.GSCoverageDimensionEncoder;
import it.geosolutions.geoserver.rest.encoder.metadatalink.GSMetadataLinkInfoEncoder;
import java.io.File;
@ -18,6 +18,7 @@ import org.springframework.core.io.ClassPathResource;
* ResourceDecoderTest
*
* @author eblondel
* @author Henry Rotzoll (henry.rotzoll@dlr.de)
*
*/
public class ResourceDecoderTest {
@ -111,5 +112,19 @@ public class ResourceDecoderTest {
}
@Test
public void testCoverageDimension() throws IOException{
List<GSCoverageDimensionEncoder> list = coverage.getEncodedDimensionsInfoList();
GSCoverageDimensionEncoder coverageDimension1 = list.get(0);
Assert.assertEquals("GRAY_INDEX", coverageDimension1.getName());
Assert.assertEquals("GridSampleDimension[-Infinity,Infinity]", coverageDimension1.getDescription());
Assert.assertEquals("-inf", coverageDimension1.getRangeMin());
Assert.assertEquals("inf", coverageDimension1.getRangeMax());
Assert.assertEquals("dobson units³", coverageDimension1.getUnit());
Assert.assertEquals("REAL_32BITS", coverageDimension1.getDimensionTypeName());
}
}

View File

@ -0,0 +1,70 @@
/*
* Copyright (C) 2007 - 2011 GeoSolutions S.A.S.
* http://www.geo-solutions.it
*
* GPLv3 + Classpath exception
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package it.geosolutions.geoserver.rest.encoder.dimensions;
import junit.framework.Assert;
import org.junit.Test;
/**
*
* @author Henry Rotzoll (henry.rotzoll@dlr.de)
*
*/
public class GSCoverageDimensionEncoderTest {
@Test
public void coverageDimensionTest(){
GSCoverageDimensionEncoder encoder = new GSCoverageDimensionEncoder("GRAY_INDEX", "GridSampleDimension[-Infinity,Infinity]", "-inf", "inf", "dobson units³", "REAL_32BITS");
Assert.assertEquals("GRAY_INDEX", encoder.getName());
Assert.assertEquals("GridSampleDimension[-Infinity,Infinity]", encoder.getDescription());
Assert.assertEquals("-inf", encoder.getRangeMin());
Assert.assertEquals("inf", encoder.getRangeMax());
Assert.assertEquals("dobson units³", encoder.getUnit());
Assert.assertEquals("REAL_32BITS", encoder.getDimensionTypeName());
Assert.assertTrue(encoder.delName());
Assert.assertTrue(encoder.delDescription());
Assert.assertTrue(encoder.delRange());
Assert.assertTrue(encoder.delUnit());
Assert.assertTrue(encoder.delDimensionType());
Assert.assertNull( encoder.getName());
Assert.assertNull(encoder.getDescription());
Assert.assertNull(encoder.getRangeMin());
Assert.assertNull(encoder.getRangeMax());
Assert.assertNull(encoder.getUnit());
Assert.assertNull(encoder.getDimensionTypeName());
encoder.setName("GRAY_INDEX");
encoder.setDescription("GridSampleDimension[-Infinity,Infinity]");
encoder.setRange("-inf", "inf");
encoder.setUnit("dobson units³");
encoder.setDimensionType("REAL_32BITS");
Assert.assertEquals("GRAY_INDEX", encoder.getName());
Assert.assertEquals("GridSampleDimension[-Infinity,Infinity]", encoder.getDescription());
Assert.assertEquals("-inf", encoder.getRangeMin());
Assert.assertEquals("inf", encoder.getRangeMax());
Assert.assertEquals("dobson units³", encoder.getUnit());
Assert.assertEquals("REAL_32BITS", encoder.getDimensionTypeName());
}
}

View File

@ -28,6 +28,7 @@ import it.geosolutions.geoserver.rest.encoder.GSLayerEncoder;
import it.geosolutions.geoserver.rest.encoder.GSLayerEncoder21;
import it.geosolutions.geoserver.rest.encoder.GSResourceEncoder;
import it.geosolutions.geoserver.rest.encoder.authorityurl.GSAuthorityURLInfoEncoder;
import it.geosolutions.geoserver.rest.encoder.dimensions.GSCoverageDimensionEncoder;
import it.geosolutions.geoserver.rest.encoder.identifier.GSIdentifierInfoEncoder;
import it.geosolutions.geoserver.rest.encoder.metadata.GSDimensionInfoEncoder;
import it.geosolutions.geoserver.rest.encoder.metadata.GSDimensionInfoEncoder.Presentation;
@ -60,6 +61,7 @@ import org.springframework.core.io.ClassPathResource;
* @author Carlo Cancellieri - carlo.cancellieri@geo-solutions.it
* @author Emmanuel Blondel - emmanuel.blondel1@gmail.com |
* emmanuel.blondel@fao.org
* @author Henry Rotzoll (henry.rotzoll@dlr.de)
*/
public class GSFeatureEncoderTest extends GeoserverRESTTest {
protected final static Logger LOGGER = LoggerFactory.getLogger(GSFeatureEncoderTest.class);
@ -91,6 +93,9 @@ public class GSFeatureEncoderTest extends GeoserverRESTTest {
"http://www.organization.org/metadata1");
fte.addMetadataLinkInfo(metadatalink);
GSCoverageDimensionEncoder gsCoverageDimensionEncoder = new GSCoverageDimensionEncoder("GRAY_INDEX", "GridSampleDimension[-Infinity,Infinity]", "-inf", "inf", "dobson units³", "REAL_32BITS");
fte.addCoverageDimensionInfo(gsCoverageDimensionEncoder);
GSLayerEncoder layerEncoder = null;
if (!GSVersionDecoder.VERSION.getVersion(VERSION).equals(
GSVersionDecoder.VERSION.UNRECOGNIZED)) {
@ -148,6 +153,24 @@ public class GSFeatureEncoderTest extends GeoserverRESTTest {
}
@Test
public void testCoverageDimension() throws IOException {
GSFeatureTypeEncoder fte = new GSFeatureTypeEncoder();
fte.setNativeName("testlayer");
fte.setName("testlayer" + "_NEW");
fte.setTitle("title");
fte.setNativeCRS("EPSG:4326");
fte.setDescription("desc");
fte.setEnabled(true);
assertFalse(fte.toString().contains("<dimensions><coverageDimension><name>GRAY_INDEX</name><description>GridSampleDimension[-Infinity,Infinity]</description><range><min>-inf</min><max>inf</max></range><unit>dobson units³</unit><dimensionType><name>REAL_32BITS</name></dimensionType></coverageDimension></dimensions>"));
GSCoverageDimensionEncoder gsCoverageDimensionEncoder = new GSCoverageDimensionEncoder("GRAY_INDEX", "GridSampleDimension[-Infinity,Infinity]", "-inf", "inf", "dobson units³", "REAL_32BITS");
fte.addCoverageDimensionInfo(gsCoverageDimensionEncoder);
LOGGER.debug("fte.toString() :" + fte.toString());
assertTrue(fte.toString().contains("<dimensions><coverageDimension><name>GRAY_INDEX</name><description>GridSampleDimension[-Infinity,Infinity]</description><range><min>-inf</min><max>inf</max></range><unit>dobson units³</unit><dimensionType><name>REAL_32BITS</name></dimensionType></coverageDimension></dimensions>"));
}
@Test
public void testFeatureTypeEncoder() {

View File

@ -1,115 +1,134 @@
<coverage>
<name>granuleTestMosaic</name>
<nativeName>granuleTestMosaic</nativeName>
<abstract>this is an abstract</abstract>
<namespace>
<name>topp</name>
<atom:link xmlns:atom="http://www.w3.org/2005/Atom" rel="alternate" href="http://localhost:8080/geoserver/rest/namespaces/topp.xml" type="application/xml"/>
</namespace>
<title>granuleTestMosaic</title>
<keywords>
<string>keyword1</string>
<string>keyword2</string>
<string>keyword3</string>
</keywords>
<metadataLinks>
<metadataLink>
<type>text/xml</type>
<metadataType>ISO19115:2003</metadataType>
<content>http://www.organization.org/metadata1</content>
</metadataLink>
<metadataLink>
<type>text/html</type>
<metadataType>ISO19115:2003</metadataType>
<content>http://www.organization.org/metadata2</content>
</metadataLink>
</metadataLinks>
<nativeCRS>GEOGCS[&quot;WGS 84&quot;, &#xd;
DATUM[&quot;World Geodetic System 1984&quot;, &#xd;
SPHEROID[&quot;WGS 84&quot;, 6378137.0, 298.257223563, AUTHORITY[&quot;EPSG&quot;,&quot;7030&quot;]], &#xd;
AUTHORITY[&quot;EPSG&quot;,&quot;6326&quot;]], &#xd;
PRIMEM[&quot;Greenwich&quot;, 0.0, AUTHORITY[&quot;EPSG&quot;,&quot;8901&quot;]], &#xd;
UNIT[&quot;degree&quot;, 0.017453292519943295], &#xd;
AXIS[&quot;Geodetic longitude&quot;, EAST], &#xd;
AXIS[&quot;Geodetic latitude&quot;, NORTH], &#xd;
AUTHORITY[&quot;EPSG&quot;,&quot;4326&quot;]]</nativeCRS>
<srs>EPSG:4326</srs>
<nativeBoundingBox>
<minx>-180.0</minx>
<maxx>180.0</maxx>
<miny>-90.0</miny>
<maxy>90.0</maxy>
<crs>EPSG:4326</crs>
</nativeBoundingBox>
<latLonBoundingBox>
<minx>-180.0</minx>
<maxx>180.0</maxx>
<miny>-90.0</miny>
<maxy>90.0</maxy>
<crs>EPSG:4326</crs>
</latLonBoundingBox>
<projectionPolicy>NONE</projectionPolicy>
<enabled>true</enabled>
<advertised>true</advertised>
<metadata>
<entry key="time">
<dimensionInfo>
<enabled>true</enabled>
<presentation>LIST</presentation>
</dimensionInfo>
</entry>
<entry key="elevation">
<dimensionInfo>
<enabled>true</enabled>
<presentation>DISCRETE_INTERVAL</presentation>
<resolution>2</resolution>
</dimensionInfo>
</entry>
</metadata>
<store class="coverageStore">
<name>granuleTestMosaic</name>
<atom:link xmlns:atom="http://www.w3.org/2005/Atom" rel="alternate" href="http://localhost:8080/geoserver/rest/workspaces/topp/coveragestores/granuleTestMosaic.xml" type="application/xml"/>
</store>
<grid dimension="2">
<range>
<low>0 0</low>
<high>540 270</high>
</range>
<transform>
<scaleX>0.6666666666666666</scaleX>
<scaleY>-0.6666666666666666</scaleY>
<shearX>0.0</shearX>
<shearY>0.0</shearY>
<translateX>-179.66666666666666</translateX>
<translateY>89.66666666666667</translateY>
</transform>
<crs>EPSG:4326</crs>
</grid>
<parameters>
<entry>
<string>AllowMultithreading</string>
<string>false</string>
</entry>
<entry>
<string>MaxAllowedTiles</string>
<string>2147483647</string>
</entry>
<entry>
<string>InputTransparentColor</string>
<string></string>
</entry>
<entry>
<string>SUGGESTED_TILE_SIZE</string>
<string>256,256</string>
</entry>
<entry>
<string>USE_JAI_IMAGEREAD</string>
<string>false</string>
</entry>
<entry>
<string>BackgroundValues</string>
<string>-1.0</string>
</entry>
</parameters>
<name>granuleTestMosaic</name>
<nativeName>granuleTestMosaic</nativeName>
<abstract>this is an abstract</abstract>
<namespace>
<name>topp</name>
<atom:link xmlns:atom="http://www.w3.org/2005/Atom" rel="alternate"
href="http://localhost:8080/geoserver/rest/namespaces/topp.xml" type="application/xml" />
</namespace>
<title>granuleTestMosaic</title>
<keywords>
<string>keyword1</string>
<string>keyword2</string>
<string>keyword3</string>
</keywords>
<metadataLinks>
<metadataLink>
<type>text/xml</type>
<metadataType>ISO19115:2003</metadataType>
<content>http://www.organization.org/metadata1</content>
</metadataLink>
<metadataLink>
<type>text/html</type>
<metadataType>ISO19115:2003</metadataType>
<content>http://www.organization.org/metadata2</content>
</metadataLink>
</metadataLinks>
<nativeCRS>GEOGCS[&quot;WGS 84&quot;, &#xd;
DATUM[&quot;World Geodetic System 1984&quot;, &#xd;
SPHEROID[&quot;WGS 84&quot;, 6378137.0, 298.257223563,
AUTHORITY[&quot;EPSG&quot;,&quot;7030&quot;]], &#xd;
AUTHORITY[&quot;EPSG&quot;,&quot;6326&quot;]], &#xd;
PRIMEM[&quot;Greenwich&quot;, 0.0,
AUTHORITY[&quot;EPSG&quot;,&quot;8901&quot;]], &#xd;
UNIT[&quot;degree&quot;, 0.017453292519943295], &#xd;
AXIS[&quot;Geodetic longitude&quot;, EAST], &#xd;
AXIS[&quot;Geodetic latitude&quot;, NORTH], &#xd;
AUTHORITY[&quot;EPSG&quot;,&quot;4326&quot;]]</nativeCRS>
<srs>EPSG:4326</srs>
<nativeBoundingBox>
<minx>-180.0</minx>
<maxx>180.0</maxx>
<miny>-90.0</miny>
<maxy>90.0</maxy>
<crs>EPSG:4326</crs>
</nativeBoundingBox>
<latLonBoundingBox>
<minx>-180.0</minx>
<maxx>180.0</maxx>
<miny>-90.0</miny>
<maxy>90.0</maxy>
<crs>EPSG:4326</crs>
</latLonBoundingBox>
<projectionPolicy>NONE</projectionPolicy>
<enabled>true</enabled>
<advertised>true</advertised>
<metadata>
<entry key="time">
<dimensionInfo>
<enabled>true</enabled>
<presentation>LIST</presentation>
</dimensionInfo>
</entry>
<entry key="elevation">
<dimensionInfo>
<enabled>true</enabled>
<presentation>DISCRETE_INTERVAL</presentation>
<resolution>2</resolution>
</dimensionInfo>
</entry>
</metadata>
<store class="coverageStore">
<name>granuleTestMosaic</name>
<atom:link xmlns:atom="http://www.w3.org/2005/Atom" rel="alternate"
href="http://localhost:8080/geoserver/rest/workspaces/topp/coveragestores/granuleTestMosaic.xml"
type="application/xml" />
</store>
<grid dimension="2">
<range>
<low>0 0</low>
<high>540 270</high>
</range>
<transform>
<scaleX>0.6666666666666666</scaleX>
<scaleY>-0.6666666666666666</scaleY>
<shearX>0.0</shearX>
<shearY>0.0</shearY>
<translateX>-179.66666666666666</translateX>
<translateY>89.66666666666667</translateY>
</transform>
<crs>EPSG:4326</crs>
</grid>
<dimensions>
<coverageDimension>
<name>GRAY_INDEX</name>
<description>GridSampleDimension[-Infinity,Infinity]</description>
<range>
<min>-inf</min>
<max>inf</max>
</range>
<unit>dobson units³</unit>
<dimensionType>
<name>REAL_32BITS</name>
</dimensionType>
</coverageDimension>
</dimensions>
<parameters>
<entry>
<string>AllowMultithreading</string>
<string>false</string>
</entry>
<entry>
<string>MaxAllowedTiles</string>
<string>2147483647</string>
</entry>
<entry>
<string>InputTransparentColor</string>
<string></string>
</entry>
<entry>
<string>SUGGESTED_TILE_SIZE</string>
<string>256,256</string>
</entry>
<entry>
<string>USE_JAI_IMAGEREAD</string>
<string>false</string>
</entry>
<entry>
<string>BackgroundValues</string>
<string>-1.0</string>
</entry>
</parameters>
</coverage>