/*
* GeoTools - The Open Source Java GIS Toolkit
* http://geotools.org
*
* (C) 2014, Open Source Geospatial Foundation (OSGeo)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License.
*
* This library 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
* Lesser General Public License for more details.
*/
package org.geotools.coverage.io;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import java.awt.Rectangle;
import java.awt.geom.AffineTransform;
import java.io.IOException;
import java.io.Serializable;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import org.geotools.coverage.grid.GridCoverage2D;
import org.geotools.coverage.grid.GridCoverageFactory;
import org.geotools.coverage.io.CoverageAccess.AccessType;
import org.geotools.coverage.io.CoverageResponse.Status;
import org.geotools.coverage.io.CoverageSource.AdditionalDomain;
import org.geotools.coverage.io.CoverageSource.DomainType;
import org.geotools.coverage.io.CoverageSource.VerticalDomain;
import org.geotools.coverage.io.Driver.DriverCapabilities;
import org.geotools.coverage.io.driver.TestDriver;
import org.geotools.coverage.io.impl.DefaultCoverageSource;
import org.geotools.coverage.io.impl.DefaultFileCoverageAccess;
import org.geotools.coverage.io.impl.DefaultFileDriver;
import org.geotools.coverage.io.metadata.MetadataAttribute;
import org.geotools.coverage.io.metadata.MetadataNode;
import org.geotools.coverage.io.util.DateRangeTreeSet;
import org.geotools.coverage.io.util.DoubleRangeTreeSet;
import org.geotools.data.DataSourceException;
import org.geotools.data.Parameter;
import org.geotools.factory.Hints;
import org.geotools.feature.NameImpl;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.geotools.referencing.operation.transform.AffineTransform2D;
import org.geotools.util.DateRange;
import org.geotools.util.NumberRange;
import org.junit.Test;
import org.opengis.coverage.Coverage;
import org.opengis.coverage.grid.GridCoverage;
import org.opengis.feature.type.Name;
import org.opengis.filter.Filter;
import org.opengis.geometry.MismatchedDimensionException;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.MathTransform2D;
import org.opengis.referencing.operation.TransformException;
import org.opengis.util.ProgressListener;
/**
*
* @author Nicola Lagomarsini Geosolutions
*
*/
public class CoverageTest {
private final static TestDriverNew driver = new TestDriverNew();
private static final Name TEST_NAME = new NameImpl("New Test Coverage");
public static final String TEST_URL = "file:/" + TEST_NAME.getLocalPart();
@Test
public void testDomains() throws IOException, MismatchedDimensionException, TransformException {
Map<String, Serializable> connectionParams = new HashMap<String, Serializable>();
connectionParams.put(DefaultFileDriver.URL.key, new URL(TEST_URL));
CoverageAccess access = driver.access(DriverCapabilities.CONNECT, connectionParams, null,
null);
assertSame(driver, access.getDriver());
// Checking proper coverage name
final List<Name> names = access.getNames(null);
final Name coverageName = names.get(0);
assertEquals(1, names.size());
assertEquals(TEST_NAME, coverageName);
final CoverageSource source = access.access(TEST_NAME, null, AccessType.READ_ONLY, null,
null);
assertEquals(TEST_NAME, source.getName(null));
// Test additional domains Setter and getter
assertTrue(!source.getAdditionalDomains().isEmpty());
assertNotNull(source.getVerticalDomain());
}
@Test
public void testAttributes() throws IOException, MismatchedDimensionException, TransformException {
Map<String, Serializable> connectionParams = new HashMap<String, Serializable>();
connectionParams.put(DefaultFileDriver.URL.key, new URL(TEST_URL));
CoverageAccess access = driver.access(DriverCapabilities.CONNECT, connectionParams, null,
null);
final CoverageSource source = access.access(TEST_NAME, null, AccessType.READ_ONLY, null,
null);
// Minor checks on the metadata node and attributes
MetadataNode metadata = source.getMetadata(null, null);
assertNotNull(metadata);
Map<String, MetadataAttribute> attributes = metadata.getAttributes();
assertNotNull(attributes);
assertTrue(!attributes.isEmpty());
MetadataAttribute metadataAttribute = attributes.get("testAttribute");
assertNotNull(metadataAttribute);
assertNotNull(metadata.getNodes());
}
@Test
public void testDomainTypes() {
assertTrue(DomainType.DATE.toString().equalsIgnoreCase("DATE"));
assertTrue(DomainType.DATERANGE.toString().equalsIgnoreCase("DATERANGE"));
assertTrue(DomainType.NUMBER.toString().equalsIgnoreCase("NUMBER"));
assertTrue(DomainType.NUMBERRANGE.toString().equalsIgnoreCase("NUMBERRANGE"));
assertTrue(DomainType.STRING.toString().equalsIgnoreCase("STRING"));
}
@Test
public void testRequestAndResponse() throws IOException, MismatchedDimensionException,
TransformException {
Map<String, Serializable> connectionParams = new HashMap<String, Serializable>();
connectionParams.put(DefaultFileDriver.URL.key, new URL(TEST_URL));
CoverageAccess access = driver.access(DriverCapabilities.CONNECT, connectionParams, null,
null);
final CoverageSource source = access.access(TEST_NAME, null, AccessType.READ_ONLY, null,
null);
// Checking proper coverage name
final List<Name> names = access.getNames(null);
final Name coverageName = names.get(0);
// Creation of a dummy Request
CoverageReadRequest request = new CoverageReadRequest();
// Definition of the parameters
CoordinateReferenceSystem crs = source.getCoordinateReferenceSystem();
Rectangle rasterArea = new Rectangle(0, 0, 10, 10);
Hints hints = new Hints();
String handle = "test_handle";
DateRange range = new DateRange(new Date(10000), new Date(20000));
DateRangeTreeSet set = new DateRangeTreeSet();
set.add(range);
Filter filter = Filter.INCLUDE;
MathTransform2D gridToWorldTransform = new AffineTransform2D(
AffineTransform.getTranslateInstance(0, 0));
Set<NumberRange<Double>> verticalSubset = new HashSet<NumberRange<Double>>();
verticalSubset.add(new NumberRange<Double>(Double.class, 0.0d, 10000.0d));
// Setting of the request parameters
request.setName(coverageName);
request.setHints(hints);
request.setHandle(handle);
request.setDomainSubset(rasterArea, gridToWorldTransform, crs);
// Ensure that both geographic and raster area have been set
assertTrue(request.getRasterArea() != null);
assertTrue(request.getGeographicArea() != null);
// Check that there is no Filter already set
assertTrue(request.getFilter() == null);
// Setting the filter
request.setFilter(filter);
assertTrue(request.getFilter() != null);
// Check that there is no temporal subset already set
assertTrue(request.getTemporalSubset().isEmpty());
// Setting temporal subset
request.setTemporalSubset(set);
assertTrue(!request.getTemporalSubset().isEmpty());
// Check that there is no vertical subset already set
assertTrue(request.getVerticalSubset().isEmpty());
// Setting vertical subset
request.setVerticalSubset(verticalSubset);
assertTrue(!request.getVerticalSubset().isEmpty());
// Get the response
CoverageResponse response = source.read(request, null);
// Ensure the response status is success
assertTrue(response.getStatus() == Status.SUCCESS);
// Ensure the request is the same
assertTrue(response.getRequest().equals(request));
// Ensure the Handle is the same
assertTrue(response.getHandle().equalsIgnoreCase(handle));
// Ensure the result is not null
Collection<? extends Coverage> results = response.getResults(null);
assertTrue(results != null);
assertTrue(results.size() > 0);
assertTrue(results.iterator().next() instanceof GridCoverage2D);
}
@Test
public void testUpdateRequestAndResponse() throws IOException, MismatchedDimensionException,
TransformException {
Map<String, Serializable> connectionParams = new HashMap<String, Serializable>();
connectionParams.put(DefaultFileDriver.URL.key, new URL(TEST_URL));
CoverageAccess access = driver.access(DriverCapabilities.CONNECT, connectionParams, null,
null);
final CoverageStore store = access.create(TEST_NAME, null, new Hints(), null);
// Creation of a dummy Request
CoverageUpdateRequest request = new CoverageUpdateRequest();
// Setting of the parameters
Map<String, String> metadata = new HashMap<String, String>();
metadata.put("testKey", "testMetadata");
List<GridCoverage2D> data = new ArrayList<GridCoverage2D>();
GridCoverage2D cov = new GridCoverageFactory().create(TEST_NAME.getLocalPart(),
new float[][] { { 1.0f, 1.0f } }, new ReferencedEnvelope(0.0d, 1.0d, 0.0d, 1.0d,
null));
data.add(cov);
request.setMetadata(metadata);
request.setData(data);
// Get the response
CoverageResponse response = store.update(request, null);
Collection<? extends Coverage> results = response.getResults(null);
// Ensure the results are not null and it is not empty
assertTrue(results != null);
assertTrue(!results.isEmpty());
// Get the first result from the collection and ensure it is the same coverage of the input
GridCoverage2D covOutput = (GridCoverage2D) results.iterator().next();
assertSame(cov, covOutput);
// Ensure they have the same metadata
CoverageUpdateRequest request2 = (CoverageUpdateRequest) response.getRequest();
assertEquals(metadata.get("testKey"), request2.getMetadata().get("testKey"));
}
static class TestVerticalDomain extends VerticalDomain {
static Set<NumberRange<Double>> verticalSubset = new HashSet<NumberRange<Double>>();
static {
verticalSubset.add(new NumberRange<Double>(Double.class, 0.0d, 10000.0d));
}
@Override
public SortedSet<? extends NumberRange<Double>> getVerticalElements(boolean overall,
ProgressListener listener) throws IOException {
return new DoubleRangeTreeSet(verticalSubset);
}
@Override
public CoordinateReferenceSystem getCoordinateReferenceSystem() {
return DefaultGeographicCRS.WGS84;
}
}
static class TestAdditionalDomain extends AdditionalDomain {
static Set<Object> test = new HashSet<Object>();
static {
test.add("test");
}
@Override
public Set<Object> getElements(boolean overall, ProgressListener listener)
throws IOException {
return test;
}
@Override
public String getName() {
return "test";
}
@Override
public DomainType getType() {
return DomainType.STRING;
}
}
static class TestCoverageSourceDescriptorNew extends TestCoverageSourceDescriptor {
public TestCoverageSourceDescriptorNew() {
super(TEST_NAME.getLocalPart());
setVerticalDomain(new TestVerticalDomain());
setHasVerticalDomain(true);
ArrayList<AdditionalDomain> additionalDomains = new ArrayList<AdditionalDomain>();
additionalDomains.add(new TestAdditionalDomain());
setAdditionalDomains(additionalDomains);
setHasAdditionalDomains(true);
}
}
public static class TestDriverNew extends DefaultFileDriver implements Driver {
public TestDriverNew() {
super(TestDriver.TEST_DRIVER, TestDriver.TEST_DRIVER, TestDriver.TEST_DRIVER, new Hints(), Collections
.singletonList(".EXT"), EnumSet.of(DriverCapabilities.CONNECT,
DriverCapabilities.CREATE, DriverCapabilities.DELETE));
}
private static Map<String, Parameter<?>> emptyMap = Collections.emptyMap();
@Override
protected CoverageAccess connect(Map<String, Serializable> params, Hints hints,
ProgressListener listener) throws IOException {
return new TestCoverageAccessNew(this, EnumSet.of(AccessType.READ_WRITE), emptyMap,
params);
}
}
static class TestCoverageAccessNew extends DefaultFileCoverageAccess {
@Override
public CoverageSource access(Name name, Map<String, Serializable> params,
AccessType accessType, Hints hints, ProgressListener listener) throws IOException {
return new TestCoverageSourceNew(name, new TestCoverageSourceDescriptorNew());
}
@Override
public CoverageStore create(Name name, Map<String, Serializable> params, Hints hints,
ProgressListener listener) throws IOException {
return new TestCoverageSourceNew(name, new TestCoverageSourceDescriptorNew());
}
public TestCoverageAccessNew(Driver driver, EnumSet<AccessType> allowedAccessTypes,
Map<String, Parameter<?>> accessParams,
Map<String, Serializable> connectionParameters) throws DataSourceException {
super(driver, allowedAccessTypes, accessParams, null, connectionParameters);
names = new ArrayList<Name>();
names.add(TEST_NAME);
}
}
static class TestCoverageSourceNew extends DefaultCoverageSource implements CoverageStore {
protected TestCoverageSourceNew(Name name, CoverageSourceDescriptor descriptor) {
super(name, descriptor);
}
@Override
public CoverageResponse read(CoverageReadRequest request, ProgressListener listener)
throws IOException {
// creating a simple response
CoverageResponse response = new CoverageResponse();
response.setRequest(request);
response.setHandle(request.getHandle());
response.setStatus(Status.SUCCESS);
// Adding results
response.addResult(new GridCoverageFactory().create(TEST_NAME.getLocalPart(),
new float[][] { { 1.0f, 1.0f } }, new ReferencedEnvelope(0.0d, 1.0d, 0.0d,
1.0d, null)));
return response;
}
@Override
public Map<String, Parameter<?>> getUpdateParameterInfo() {
Map<String, Parameter<?>> parameterInfo = new HashMap<String, Parameter<?>>();
return parameterInfo;
}
@Override
public CoverageResponse update(CoverageUpdateRequest writeRequest, ProgressListener progress) {
CoverageResponse response = new CoverageResponse();
response.setRequest(writeRequest);
response.addResults((Collection<GridCoverage>) writeRequest.getData());
return response;
}
@Override
public MetadataNode getMetadata( String metadataDomain, ProgressListener listener ) {
MetadataNode metadataNode = new MetadataNode();
Map<String, MetadataAttribute> attributes = new HashMap<String, MetadataAttribute>();
attributes.put("testAttribute", new MetadataAttribute());
metadataNode.setAttributes(attributes);
metadataNode.setNodes(new ArrayList<MetadataNode>());
return metadataNode;
}
}
}