/* (c) 2014 Open Source Geospatial Foundation - all rights reserved * (c) 2001 - 2014 OpenPlans * This code is licensed under the GPL 2.0 license, available at the root * application directory. */ package org.geoserver.wms.dimension; import static org.junit.Assert.assertTrue; import java.io.IOException; import java.sql.Date; import java.util.Collections; import java.util.TimeZone; import javax.xml.namespace.QName; import org.geoserver.catalog.DimensionDefaultValueSetting; import org.geoserver.catalog.DimensionInfo; import org.geoserver.catalog.DimensionPresentation; import org.geoserver.catalog.FeatureTypeInfo; import org.geoserver.catalog.ResourceInfo; import org.geoserver.catalog.DimensionDefaultValueSetting.Strategy; import org.geoserver.catalog.impl.DimensionInfoImpl; import org.geoserver.data.test.MockData; import org.geoserver.data.test.SystemTestData; import org.geoserver.wms.WMS; import org.geoserver.wms.WMSTestSupport; import org.geotools.data.DataUtilities; import org.geotools.data.FeatureStore; import org.geotools.data.memory.MemoryFeatureCollection; import org.geotools.feature.type.DateUtil; import org.junit.Before; import org.junit.Test; import org.opengis.feature.simple.SimpleFeature; import org.opengis.feature.simple.SimpleFeatureType; /** * Tests the WMS default value support for a custom dimension for both * vector and raster layers. * * @author Ilkka Rinne <ilkka.rinne@spatineo.com> */ public class VectorCustomDimensionDefaultValueTest extends WMSTestSupport { private static final QName TIME_ELEVATION_CUSTOM = new QName(MockData.SF_URI, "TimeElevationCustom", MockData.SF_PREFIX); private static final String REFERENCE_TIME_DIMENSION = "REFERENCE_TIME"; private static final String SCANNING_ANGLE_DIMENSION = "SCANNING_ANGLE"; WMS wms; @Override protected void onSetUp(SystemTestData testData) throws Exception { super.onSetUp(testData); TimeZone.setDefault(TimeZone.getTimeZone("UTC")); } @Before public void setup() throws Exception { wms = getWMS(); //with the initialized application context ((SystemTestData)testData).addVectorLayer(TIME_ELEVATION_CUSTOM,Collections.EMPTY_MAP,"TimeElevationCustom.properties", getClass(),getCatalog()); } @Test public void testDefaultCustomDimDateValueVectorSelector() throws Exception { int fid = 1000; //Use default value DimensionInfo setup, should return the minimum value setupFeatureCustomDimension(REFERENCE_TIME_DIMENSION,"referenceTime",null); FeatureTypeInfo timeElevationCustom = getCatalog().getFeatureTypeByName( TIME_ELEVATION_CUSTOM.getLocalPart()); //From src/test/resources/org/geoserver/wms/TimeElevationCustom.properties: Date originallySmallest = Date.valueOf("2011-04-20"); java.util.Date d = wms.getDefaultCustomDimensionValue(REFERENCE_TIME_DIMENSION, timeElevationCustom, java.util.Date.class); assertTrue("Default value is null", d != null); assertTrue("Default value should be the smallest one", d.getTime() == originallySmallest.getTime()); Date biggest = Date.valueOf("2021-01-01"); addFeatureWithReferenceTime(fid++, biggest); d = wms.getDefaultCustomDimensionValue(REFERENCE_TIME_DIMENSION, timeElevationCustom, java.util.Date.class); assertTrue("Default value is null", d != null); assertTrue("Default value should be the smallest one", d.getTime() == originallySmallest.getTime()); Date smaller = Date.valueOf("2010-01-01"); addFeatureWithReferenceTime(fid++, smaller); d = wms.getDefaultCustomDimensionValue(REFERENCE_TIME_DIMENSION, timeElevationCustom, java.util.Date.class); assertTrue("Default value is null", d != null); assertTrue("Default value should be the smallest one", d.getTime() == smaller.getTime()); } @Test public void testDefaultCustomDimDoubleValueVectorSelector() throws Exception { int fid = 1000; //Use default value DimensionInfo setup, should return the minimum value setupFeatureCustomDimension(SCANNING_ANGLE_DIMENSION,"scanningAngle",null); FeatureTypeInfo timeElevationCustom = getCatalog().getFeatureTypeByName( TIME_ELEVATION_CUSTOM.getLocalPart()); //From src/test/resources/org/geoserver/wms/TimeElevationCustom.properties: Double originallySmallest = Double.valueOf(0d); Double d = wms.getDefaultCustomDimensionValue(SCANNING_ANGLE_DIMENSION, timeElevationCustom, Double.class); assertTrue("Default value is null", d != null); assertTrue("Default value should be the smallest one", Math.abs(d.doubleValue() - originallySmallest.doubleValue()) < 0.0001); Double biggest = Double.valueOf(2.1d); addFeatureWithScanningAngle(fid++, biggest); d = wms.getDefaultCustomDimensionValue(SCANNING_ANGLE_DIMENSION, timeElevationCustom, Double.class); assertTrue("Default value is null", d != null); assertTrue("Default value should be the smallest one", Math.abs(d.doubleValue() - originallySmallest.doubleValue()) < 0.0001); Double smaller = Double.valueOf(-1d); addFeatureWithScanningAngle(fid++, smaller); d = wms.getDefaultCustomDimensionValue(SCANNING_ANGLE_DIMENSION, timeElevationCustom, Double.class); assertTrue("Default value is null", d != null); assertTrue("Default value should be the smallest one", Math.abs(d.doubleValue() - smaller.doubleValue()) < 0.0001); } @Test public void testExplicitMinCustomDimDateValueVectorSelector() throws Exception { int fid = 1000; //Use explicit default value DimensionInfo setup: DimensionDefaultValueSetting defaultValueSetting = new DimensionDefaultValueSetting(); defaultValueSetting.setStrategyType(Strategy.MINIMUM); setupFeatureCustomDimension(REFERENCE_TIME_DIMENSION,"referenceTime",defaultValueSetting); FeatureTypeInfo timeElevationCustom = getCatalog().getFeatureTypeByName( TIME_ELEVATION_CUSTOM.getLocalPart()); //From src/test/resources/org/geoserver/wms/TimeElevationCustom.properties: Date originallySmallest = Date.valueOf("2011-04-20"); java.util.Date d = wms.getDefaultCustomDimensionValue(REFERENCE_TIME_DIMENSION, timeElevationCustom, java.util.Date.class); assertTrue("Default value is null", d != null); assertTrue("Default value should be the smallest one", d.getTime() == originallySmallest.getTime()); Date biggest = Date.valueOf("2021-01-01"); addFeatureWithReferenceTime(fid++, biggest); d = wms.getDefaultCustomDimensionValue(REFERENCE_TIME_DIMENSION, timeElevationCustom, java.util.Date.class); assertTrue("Default value is null", d != null); assertTrue("Default value should be the smallest one", d.getTime() == originallySmallest.getTime()); Date smaller = Date.valueOf("2010-01-01"); addFeatureWithReferenceTime(fid++, smaller); d = wms.getDefaultCustomDimensionValue(REFERENCE_TIME_DIMENSION, timeElevationCustom, java.util.Date.class); assertTrue("Default value is null", d != null); assertTrue("Default value should be the smallest one", d.getTime() == smaller.getTime()); } @Test public void testExplicitMinCustomDimDoubleValueVectorSelector() throws Exception { int fid = 1000; //Use explicit default value DimensionInfo setup: DimensionDefaultValueSetting defaultValueSetting = new DimensionDefaultValueSetting(); defaultValueSetting.setStrategyType(Strategy.MINIMUM); setupFeatureCustomDimension(SCANNING_ANGLE_DIMENSION,"scanningAngle",defaultValueSetting); FeatureTypeInfo timeElevationCustom = getCatalog().getFeatureTypeByName( TIME_ELEVATION_CUSTOM.getLocalPart()); //From src/test/resources/org/geoserver/wms/TimeElevationCustom.properties: Double originallySmallest = Double.valueOf(0d); Double d = wms.getDefaultCustomDimensionValue(SCANNING_ANGLE_DIMENSION, timeElevationCustom, Double.class); assertTrue("Default value is null", d != null); assertTrue("Default value should be the smallest one", Math.abs(d.doubleValue() - originallySmallest.doubleValue()) < 0.0001); Double biggest = Double.valueOf(2.1d); addFeatureWithScanningAngle(fid++, biggest); d = wms.getDefaultCustomDimensionValue(SCANNING_ANGLE_DIMENSION, timeElevationCustom, Double.class); assertTrue("Default value is null", d != null); assertTrue("Default value should be the smallest one", Math.abs(d.doubleValue() - originallySmallest.doubleValue()) < 0.0001); Double smaller = Double.valueOf(-1d); addFeatureWithScanningAngle(fid++, smaller); d = wms.getDefaultCustomDimensionValue(SCANNING_ANGLE_DIMENSION, timeElevationCustom, Double.class); assertTrue("Default value is null", d != null); assertTrue("Default value should be the smallest one", Math.abs(d.doubleValue() - smaller.doubleValue()) < 0.0001); } @Test public void testExplicitMaxCustomDimDateValueVectorSelector() throws Exception { int fid = 1000; //Use explicit default value DimensionInfo setup: DimensionDefaultValueSetting defaultValueSetting = new DimensionDefaultValueSetting(); defaultValueSetting.setStrategyType(Strategy.MAXIMUM); setupFeatureCustomDimension(REFERENCE_TIME_DIMENSION,"referenceTime",defaultValueSetting); FeatureTypeInfo timeElevationCustom = getCatalog().getFeatureTypeByName( TIME_ELEVATION_CUSTOM.getLocalPart()); //From src/test/resources/org/geoserver/wms/TimeElevationCustom.properties: Date originallyBiggest = Date.valueOf("2011-04-23"); java.util.Date d = wms.getDefaultCustomDimensionValue(REFERENCE_TIME_DIMENSION, timeElevationCustom, java.util.Date.class); assertTrue("Default value is null", d != null); assertTrue("Default value should be the biggest one", d.getTime() == originallyBiggest.getTime()); Date biggest = Date.valueOf("2021-01-01"); addFeatureWithReferenceTime(fid++, biggest); d = wms.getDefaultCustomDimensionValue(REFERENCE_TIME_DIMENSION, timeElevationCustom, java.util.Date.class); assertTrue("Default value is null", d != null); assertTrue("Default value should be the biggest one", d.getTime() == biggest.getTime()); Date smaller = Date.valueOf("2014-01-01"); addFeatureWithReferenceTime(fid++, smaller); d = wms.getDefaultCustomDimensionValue(REFERENCE_TIME_DIMENSION, timeElevationCustom, java.util.Date.class); assertTrue("Default value is null", d != null); assertTrue("Default value should be the biggest one", d.getTime() == biggest.getTime()); } @Test public void testExplicitMaxCustomDimDoubleValueVectorSelector() throws Exception { int fid = 1000; //Use explicit default value DimensionInfo setup: DimensionDefaultValueSetting defaultValueSetting = new DimensionDefaultValueSetting(); defaultValueSetting.setStrategyType(Strategy.MAXIMUM); setupFeatureCustomDimension(SCANNING_ANGLE_DIMENSION,"scanningAngle",defaultValueSetting); FeatureTypeInfo timeElevationCustom = getCatalog().getFeatureTypeByName( TIME_ELEVATION_CUSTOM.getLocalPart()); //From src/test/resources/org/geoserver/wms/TimeElevationCustom.properties: Double originallyBiggest = Double.valueOf(1.5d); Double d = wms.getDefaultCustomDimensionValue(SCANNING_ANGLE_DIMENSION, timeElevationCustom, Double.class); assertTrue("Default value is null", d != null); assertTrue("Default value should be the smallest one", Math.abs(d.doubleValue() - originallyBiggest.doubleValue()) < 0.0001); Double biggest = Double.valueOf(2.1d); addFeatureWithScanningAngle(fid++, biggest); d = wms.getDefaultCustomDimensionValue(SCANNING_ANGLE_DIMENSION, timeElevationCustom, Double.class); assertTrue("Default value is null", d != null); assertTrue("Default value should be the smallest one", Math.abs(d.doubleValue() - biggest.doubleValue()) < 0.0001); Double smaller = Double.valueOf(1.8); addFeatureWithScanningAngle(fid++, smaller); d = wms.getDefaultCustomDimensionValue(SCANNING_ANGLE_DIMENSION, timeElevationCustom, Double.class); assertTrue("Default value is null", d != null); assertTrue("Default value should be the smallest one", Math.abs(d.doubleValue() - biggest.doubleValue()) < 0.0001); } @Test public void testExplicitFixedCustomDimDateValueVectorSelector() throws Exception { int fid = 1000; //Use explicit default value DimensionInfo setup: DimensionDefaultValueSetting defaultValueSetting = new DimensionDefaultValueSetting(); defaultValueSetting.setStrategyType(Strategy.FIXED); String fixedStr = "2014-01-20T00:00:00Z"; defaultValueSetting.setReferenceValue(fixedStr); setupFeatureCustomDimension(REFERENCE_TIME_DIMENSION,"referenceTime",defaultValueSetting); FeatureTypeInfo timeElevationCustom = getCatalog().getFeatureTypeByName( TIME_ELEVATION_CUSTOM.getLocalPart()); long fixed = DateUtil.parseDateTime(fixedStr); java.util.Date d = wms.getDefaultCustomDimensionValue(REFERENCE_TIME_DIMENSION, timeElevationCustom, java.util.Date.class); assertTrue("Default value is null", d != null); assertTrue("Default value should be the fixed one", d.getTime() == fixed); Date biggest = Date.valueOf("2021-01-01"); addFeatureWithReferenceTime(fid++, biggest); d = wms.getDefaultCustomDimensionValue(REFERENCE_TIME_DIMENSION, timeElevationCustom, java.util.Date.class); assertTrue("Default value is null", d != null); assertTrue("Default value should be the fixed one", d.getTime() == fixed); Date smaller = Date.valueOf("2010-01-01"); addFeatureWithReferenceTime(fid++, smaller); d = wms.getDefaultCustomDimensionValue(REFERENCE_TIME_DIMENSION, timeElevationCustom, java.util.Date.class); assertTrue("Default value is null", d != null); assertTrue("Default value should be the fixed one", d.getTime() == fixed); } @Test public void testExplicitFixedCustomDimDoubleValueVectorSelector() throws Exception { int fid = 1000; //Use explicit default value DimensionInfo setup: DimensionDefaultValueSetting defaultValueSetting = new DimensionDefaultValueSetting(); defaultValueSetting.setStrategyType(Strategy.FIXED); String fixedStr = "42.1"; defaultValueSetting.setReferenceValue(fixedStr); double fixed = Double.parseDouble(fixedStr); setupFeatureCustomDimension(SCANNING_ANGLE_DIMENSION,"scanningAngle",defaultValueSetting); FeatureTypeInfo timeElevationCustom = getCatalog().getFeatureTypeByName( TIME_ELEVATION_CUSTOM.getLocalPart()); Double d = wms.getDefaultCustomDimensionValue(SCANNING_ANGLE_DIMENSION, timeElevationCustom, Double.class); assertTrue("Default value is null", d != null); assertTrue("Default value should be the smallest one", Math.abs(d.doubleValue() - fixed) < 0.0001); Double biggest = Double.valueOf(2.1d); addFeatureWithScanningAngle(fid++, biggest); d = wms.getDefaultCustomDimensionValue(SCANNING_ANGLE_DIMENSION, timeElevationCustom, Double.class); assertTrue("Default value is null", d != null); assertTrue("Default value should be the smallest one", Math.abs(d.doubleValue() - fixed) < 0.0001); Double smaller = Double.valueOf(1.8); addFeatureWithScanningAngle(fid++, smaller); d = wms.getDefaultCustomDimensionValue(SCANNING_ANGLE_DIMENSION, timeElevationCustom, Double.class); assertTrue("Default value is null", d != null); assertTrue("Default value should be the smallest one", Math.abs(d.doubleValue() - fixed) < 0.0001); } @Test public void testExplicitNearestToGivenValueCustomDimDateValueVectorSelector() throws Exception { int fid = 1000; //Use explicit default value DimensionInfo setup: DimensionDefaultValueSetting defaultValueSetting = new DimensionDefaultValueSetting(); defaultValueSetting.setStrategyType(Strategy.NEAREST); String referenceStr = "2014-01-20T00:00:00Z"; defaultValueSetting.setReferenceValue(referenceStr); setupFeatureCustomDimension(REFERENCE_TIME_DIMENSION,"referenceTime",defaultValueSetting); FeatureTypeInfo timeElevationCustom = getCatalog().getFeatureTypeByName( TIME_ELEVATION_CUSTOM.getLocalPart()); Date originallyBiggest = Date.valueOf("2011-04-23"); java.util.Date d = wms.getDefaultCustomDimensionValue(REFERENCE_TIME_DIMENSION, timeElevationCustom, java.util.Date.class); assertTrue("Default value is null", d != null); assertTrue("Default value should be the closest one", d.getTime() == originallyBiggest.getTime()); Date biggerThanOriginal = Date.valueOf("2012-01-01"); addFeatureWithReferenceTime(fid++, biggerThanOriginal); d = wms.getDefaultCustomDimensionValue(REFERENCE_TIME_DIMENSION, timeElevationCustom, java.util.Date.class); assertTrue("Default value is null", d != null); assertTrue("Default value should be the closest one", d.getTime() == biggerThanOriginal.getTime()); Date biggerThanReference = Date.valueOf("2014-06-01"); addFeatureWithReferenceTime(fid++, biggerThanReference); d = wms.getDefaultCustomDimensionValue(REFERENCE_TIME_DIMENSION, timeElevationCustom, java.util.Date.class); assertTrue("Default value is null", d != null); assertTrue("Default value should be the closest one", d.getTime() == biggerThanReference.getTime()); } @Test public void testExplicitNearestToGivenValueCustomDimDoubleValueVectorSelector() throws Exception { int fid = 1000; //Use explicit default value DimensionInfo setup: DimensionDefaultValueSetting defaultValueSetting = new DimensionDefaultValueSetting(); defaultValueSetting.setStrategyType(Strategy.NEAREST); String referenceStr = "2.3"; defaultValueSetting.setReferenceValue(referenceStr); setupFeatureCustomDimension(SCANNING_ANGLE_DIMENSION,"scanningAngle",defaultValueSetting); FeatureTypeInfo timeElevationCustom = getCatalog().getFeatureTypeByName( TIME_ELEVATION_CUSTOM.getLocalPart()); double originallyBiggest = Double.valueOf(1.5d); Double d = wms.getDefaultCustomDimensionValue(SCANNING_ANGLE_DIMENSION, timeElevationCustom, Double.class); assertTrue("Default value is null", d != null); assertTrue("Default value should be the closest one", Math.abs(d.doubleValue() - originallyBiggest) < 0.0001); double biggerThanOriginal = 1.7d; addFeatureWithScanningAngle(fid++, biggerThanOriginal); d = wms.getDefaultCustomDimensionValue(SCANNING_ANGLE_DIMENSION, timeElevationCustom, Double.class); assertTrue("Default value is null", d != null); assertTrue("Default value should be the closest one", Math.abs(d.doubleValue() - biggerThanOriginal) < 0.0001); double biggerThanReference = 2.45d; addFeatureWithScanningAngle(fid++, biggerThanReference); d = wms.getDefaultCustomDimensionValue(SCANNING_ANGLE_DIMENSION, timeElevationCustom, Double.class); assertTrue("Default value is null", d != null); assertTrue("Default value should be the closest one", Math.abs(d.doubleValue() - biggerThanReference) < 0.0001); } protected void setupFeatureCustomDimension(String dimensionName, String attrName, DimensionDefaultValueSetting defaultValue) { FeatureTypeInfo info = getCatalog() .getFeatureTypeByName(TIME_ELEVATION_CUSTOM.getLocalPart()); DimensionInfo di = new DimensionInfoImpl(); di.setEnabled(true); di.setAttribute(attrName); di.setDefaultValue(defaultValue); di.setPresentation(DimensionPresentation.LIST); info.getMetadata().put(ResourceInfo.CUSTOM_DIMENSION_PREFIX+dimensionName, di); getCatalog().save(info); } protected void addFeature(int id, Date time, Double elevation, Date referenceTime, Double scanningAngle) throws IOException { FeatureTypeInfo timeElevationCustom = getCatalog().getFeatureTypeByName( TIME_ELEVATION_CUSTOM.getLocalPart()); FeatureStore fs = (FeatureStore) timeElevationCustom.getFeatureSource(null, null); SimpleFeatureType type = (SimpleFeatureType)timeElevationCustom.getFeatureType(); MemoryFeatureCollection coll = new MemoryFeatureCollection(type); StringBuffer content = new StringBuffer(); content.append(id); content.append('|'); content.append(time.toString()); content.append('|'); content.append(elevation); content.append('|'); content.append(referenceTime.toString()); content.append('|'); content.append(scanningAngle); SimpleFeature f = DataUtilities.createFeature(type, content.toString()); coll.add(f); org.geotools.data.Transaction tx = fs.getTransaction(); fs.addFeatures(coll); tx.commit(); } private void addFeatureWithReferenceTime(int fid, Date time) throws IOException{ this.addFeature(fid, Date.valueOf("2013-01-13"), Double.valueOf(0d), time, Double.valueOf(0d)); } private void addFeatureWithScanningAngle(int fid, Double angle) throws IOException{ this.addFeature(fid, Date.valueOf("2013-01-13"), Double.valueOf(0d), Date.valueOf("2014-01-20"), angle); } }