/**
* This file is hereby placed into the Public Domain. This means anyone is
* free to do whatever they wish with this file.
*/
package mil.nga.giat.process.elasticsearch;
import static org.junit.Assert.*;
import java.awt.geom.Point2D;
import java.util.List;
import org.geotools.coverage.grid.GridCoverage2D;
import org.geotools.data.Query;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.factory.CommonFactoryFinder;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.geotools.referencing.CRS;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.junit.Before;
import org.junit.Test;
import org.opengis.filter.Filter;
import org.opengis.filter.FilterFactory;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.NoSuchAuthorityCodeException;
import org.opengis.referencing.crs.CRSAuthorityFactory;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.TransformException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.davidmoten.geo.GeoHash;
import com.github.davidmoten.geo.LatLong;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.vividsolutions.jts.geom.Envelope;
public class GeoHashGridProcessTest {
private SimpleFeatureCollection features;
private double fineDelta;
private GeoHashGridProcess process;
private FilterFactory ff;
@Before
public void setup() throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
features = TestUtil.createAggregationFeatures(ImmutableList.of(
ImmutableMap.of("_aggregation", mapper.writeValueAsBytes(ImmutableMap.of("key",GeoHash.encodeHash(new LatLong(-89.9,-179.9),1),"doc_count",10))),
ImmutableMap.of("_aggregation", mapper.writeValueAsBytes(ImmutableMap.of("key",GeoHash.encodeHash(new LatLong(0.1,0.1),1),"doc_count",10))),
ImmutableMap.of("_aggregation", mapper.writeValueAsBytes(ImmutableMap.of("key",GeoHash.encodeHash(new LatLong(89.9,179.9),1),"doc_count",10)))
));
fineDelta = 0.45;
ff = CommonFactoryFinder.getFilterFactory(null);
process = new GeoHashGridProcess();
}
@Test
public void testBasic() throws NoSuchAuthorityCodeException, TransformException, FactoryException {
ReferencedEnvelope envelope = new ReferencedEnvelope(-180,180,-90,90,DefaultGeographicCRS.WGS84);
int width = 8;
int height = 4;
int pixelsPerCell = 1;
String strategy = "Basic";
List<String> strategyArgs = null;
Float emptyCellValue = null;
Float scaleMin = 0f;
Float scaleMax = null;
boolean useLog = false;
GridCoverage2D coverage = process.execute(features, pixelsPerCell, strategy, strategyArgs, emptyCellValue, scaleMin, scaleMax, useLog, envelope, width, height, null);
checkInternal(coverage, fineDelta);
checkEdge(coverage, envelope, fineDelta);
}
@Test
public void testScaled() throws NoSuchAuthorityCodeException, TransformException, FactoryException {
ReferencedEnvelope envelope = new ReferencedEnvelope(-180,180,-90,90,DefaultGeographicCRS.WGS84);
int width = 16;
int height = 8;
int pixelsPerCell = 1;
String strategy = "Basic";
List<String> strategyArgs = null;
Float emptyCellValue = null;
Float scaleMin = 0f;
Float scaleMax = null;
boolean useLog = false;
GridCoverage2D coverage = process.execute(features, pixelsPerCell, strategy, strategyArgs, emptyCellValue, scaleMin, scaleMax, useLog, envelope, width, height, null);
checkInternal(coverage, fineDelta);
checkEdge(coverage, envelope, fineDelta);
}
@Test
public void testSubCellCrop() throws NoSuchAuthorityCodeException, TransformException, FactoryException {
ReferencedEnvelope envelope = new ReferencedEnvelope(-168.75,168.75,-78.75,78.75,DefaultGeographicCRS.WGS84);
int width = 16;
int height = 8;
int pixelsPerCell = 1;
String strategy = "Basic";
List<String> strategyArgs = null;
Float emptyCellValue = null;
Float scaleMin = 0f;
Float scaleMax = null;
boolean useLog = false;
GridCoverage2D coverage = process.execute(features, pixelsPerCell, strategy, strategyArgs, emptyCellValue, scaleMin, scaleMax, useLog, envelope, width, height, null);
checkInternal(coverage, fineDelta);
checkEdge(coverage, envelope, fineDelta);
}
@Test
public void testSubCellCropWithSheer() throws NoSuchAuthorityCodeException, TransformException, FactoryException {
ReferencedEnvelope envelope = new ReferencedEnvelope(-168.75,168.75,-78.75,78.75,DefaultGeographicCRS.WGS84);
int width = 900;
int height = 600;
int pixelsPerCell = 1;
String strategy = "Basic";
List<String> strategyArgs = null;
Float emptyCellValue = null;
Float scaleMin = 0f;
Float scaleMax = null;
boolean useLog = false;
GridCoverage2D coverage = process.execute(features, pixelsPerCell, strategy, strategyArgs, emptyCellValue, scaleMin, scaleMax, useLog, envelope, width, height, null);
checkInternal(coverage, fineDelta);
}
@Test
public void testInvertQuery() throws Exception {
Filter filter = ff.bbox("geom", 0, 0, 0, 0, "EPSG:4326");
ReferencedEnvelope env = new ReferencedEnvelope(0,1,2,3,DefaultGeographicCRS.WGS84);
Query query = new Query();
query.setFilter(filter);
Query queryOut = process.invertQuery(env, query, null);
assertEquals(ff.bbox("geom", 0, 2, 1, 3, "EPSG:4326"), queryOut.getFilter());
}
@Test
public void testInvertQueryAcrossDateline() throws Exception {
Filter filter = ff.bbox("geom", 0, 0, 0, 0, "EPSG:4326");
ReferencedEnvelope env = new ReferencedEnvelope(-179,179,2,3,DefaultGeographicCRS.WGS84);
Query query = new Query();
query.setFilter(filter);
Query queryOut = process.invertQuery(env, query, null);
assertEquals(ff.bbox("geom", -179, 2, 179, 3, "EPSG:4326"), queryOut.getFilter());
}
@Test
public void testInvertQueryNorthEastAxisOrder() throws Exception {
Filter filter = ff.bbox("geom", 0, 0, 0, 0, "EPSG:4326");
CRSAuthorityFactory factory = CRS.getAuthorityFactory(false);
CoordinateReferenceSystem crs = factory.createCoordinateReferenceSystem("EPSG:4326");
ReferencedEnvelope env = new ReferencedEnvelope(2,3,0,1,crs);
Query query = new Query();
query.setFilter(filter);
Query queryOut = process.invertQuery(env, query, null);
assertEquals(ff.bbox("geom", 0, 2, 1, 3, "EPSG:4326"), queryOut.getFilter());
}
@Test
public void testInvertQueryWithOtherFilterElement() {
Filter filter = ff.and(ff.equals(ff.property("key"), ff.literal("value")), ff.bbox("geom", 0, 0, 0, 0, "EPSG:4326"));
ReferencedEnvelope env = new ReferencedEnvelope(0,1,2,3,DefaultGeographicCRS.WGS84);
Query query = new Query();
query.setFilter(filter);
Query queryOut = process.invertQuery(env, query, null);
assertEquals(ff.and(ff.equals(ff.property("key"), ff.literal("value")), ff.bbox("geom", 0, 2, 1, 3, "EPSG:4326")), queryOut.getFilter());
}
private void checkInternal(GridCoverage2D coverage, double delta) {
assertEquals(10, coverage.evaluate(new Point2D.Double(-135-delta, -45-delta), new float[1])[0],1e-10);
assertEquals(0, coverage.evaluate(new Point2D.Double(-135+delta, -45+delta), new float[1])[0],1e-10);
assertEquals(0, coverage.evaluate(new Point2D.Double(-delta, -delta), new float[1])[0],1e-10);
assertEquals(10, coverage.evaluate(new Point2D.Double(delta, delta), new float[1])[0],1e-10);
assertEquals(10, coverage.evaluate(new Point2D.Double(45-delta, 45-delta), new float[1])[0],1e-10);
assertEquals(0, coverage.evaluate(new Point2D.Double(45+delta, 45+delta), new float[1])[0],1e-10);
assertEquals(10, coverage.evaluate(new Point2D.Double(135+delta, 45+delta), new float[1])[0],1e-10);
assertEquals(0, coverage.evaluate(new Point2D.Double(135-delta, 45-delta), new float[1])[0],1e-10);
}
private void checkEdge(GridCoverage2D coverage, Envelope env, double delta) {
assertEquals(10, coverage.evaluate(new Point2D.Double(env.getMinX()+delta, env.getMinY()+delta), new float[1])[0],1e-10);
assertEquals(10, coverage.evaluate(new Point2D.Double(env.getMaxX()-delta, env.getMaxY()-delta), new float[1])[0],1e-10);
}
}