package mil.nga.giat.geowave.analytic.partitioner;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.io.IOException;
import java.util.List;
import org.apache.commons.cli.ParseException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.mapreduce.Job;
import org.geotools.feature.type.BasicFeatureTypes;
import org.geotools.referencing.CRS;
import org.junit.Test;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.GeometryFactory;
import mil.nga.giat.geowave.adapter.vector.FeatureDataAdapter;
import mil.nga.giat.geowave.analytic.AnalyticFeature;
import mil.nga.giat.geowave.analytic.PropertyManagement;
import mil.nga.giat.geowave.analytic.clustering.ClusteringUtils;
import mil.nga.giat.geowave.analytic.model.SpatialIndexModelBuilder;
import mil.nga.giat.geowave.analytic.param.CommonParameters;
import mil.nga.giat.geowave.analytic.param.ParameterEnum;
import mil.nga.giat.geowave.analytic.param.PartitionParameters;
import mil.nga.giat.geowave.analytic.param.StoreParameters.StoreParam;
import mil.nga.giat.geowave.analytic.partitioner.AdapterBasedPartitioner.AdapterDataEntry;
import mil.nga.giat.geowave.analytic.partitioner.Partitioner.PartitionData;
import mil.nga.giat.geowave.analytic.store.PersistableStore;
import mil.nga.giat.geowave.core.index.ByteArrayId;
import mil.nga.giat.geowave.core.index.sfc.data.MultiDimensionalNumericData;
import mil.nga.giat.geowave.core.store.GeoWaveStoreFinder;
import mil.nga.giat.geowave.core.store.memory.MemoryStoreFactoryFamily;
import mil.nga.giat.geowave.core.store.operations.remote.options.DataStorePluginOptions;
public class AdapterBasedPartitionerTest
{
public static CoordinateReferenceSystem DEFAULT_CRS;
static {
try {
DEFAULT_CRS = CRS.decode(
"EPSG:4326",
true);
}
catch (final FactoryException e) {
e.printStackTrace();
}
}
@Test
public void testPartition()
throws IOException,
ParseException {
final SimpleFeatureType ftype = AnalyticFeature.createGeometryFeatureAdapter(
"centroid",
new String[] {
"extra1"
},
BasicFeatureTypes.DEFAULT_NAMESPACE,
ClusteringUtils.CLUSTERING_CRS).getFeatureType();
final GeometryFactory factory = new GeometryFactory();
SimpleFeature feature = AnalyticFeature.createGeometryFeature(
ftype,
"b1",
"123",
"fred",
"NA",
20.30203,
factory.createPoint(new Coordinate(
0,
0)),
new String[] {
"extra1"
},
new double[] {
0.022
},
1,
1,
0);
final PropertyManagement propertyManagement = new PropertyManagement();
final AdapterBasedPartitioner partitioner = new AdapterBasedPartitioner();
propertyManagement.store(
PartitionParameters.Partition.DISTANCE_THRESHOLDS,
"1.00001,1.00001");
propertyManagement.store(
CommonParameters.Common.INDEX_MODEL_BUILDER_CLASS,
SpatialIndexModelBuilder.class);
final Configuration configuration = new Configuration();
final Class<?> scope = OrthodromicDistancePartitionerTest.class;
propertyManagement.setJobConfiguration(
configuration,
scope);
final DataStorePluginOptions pluginOptions = new DataStorePluginOptions();
GeoWaveStoreFinder.getRegisteredStoreFactoryFamilies().put(
"memory",
new MemoryStoreFactoryFamily());
pluginOptions.selectPlugin("memory");
final PersistableStore store = new PersistableStore(
pluginOptions);
store.getDataStoreOptions().createAdapterStore().addAdapter(
new FeatureDataAdapter(
ftype));
((ParameterEnum<PersistableStore>) StoreParam.INPUT_STORE).getHelper().setValue(
configuration,
scope,
store);
partitioner.initialize(
Job.getInstance(configuration),
scope);
List<PartitionData> partitions = partitioner.getCubeIdentifiers(new AdapterDataEntry(
new ByteArrayId(
ftype.getName().getLocalPart()),
feature));
assertEquals(
4,
partitions.size());
assertTrue(hasOnePrimary(partitions));
for (final PartitionData partition : partitions) {
final MultiDimensionalNumericData ranges = partitioner.getRangesForPartition(partition);
assertTrue(ranges.getDataPerDimension()[0].getMin() < 0.0000000001);
assertTrue(ranges.getDataPerDimension()[0].getMax() > -0.0000000001);
assertTrue(ranges.getDataPerDimension()[1].getMin() < 0.00000000001);
assertTrue(ranges.getDataPerDimension()[1].getMax() > -0.0000000001);
}
feature = AnalyticFeature.createGeometryFeature(
ftype,
"b1",
"123",
"fred",
"NA",
20.30203,
factory.createPoint(new Coordinate(
-179.99999996,
0)),
new String[] {
"extra1"
},
new double[] {
0.022
},
1,
1,
0);
partitions = partitioner.getCubeIdentifiers(new AdapterDataEntry(
new ByteArrayId(
ftype.getName().getLocalPart()),
feature));
assertEquals(
4,
partitions.size());
assertTrue(hasOnePrimary(partitions));
feature = AnalyticFeature.createGeometryFeature(
ftype,
"b1",
"123",
"fred",
"NA",
20.30203,
factory.createPoint(new Coordinate(
179.99999996,
91)),
new String[] {
"extra1"
},
new double[] {
0.022
},
1,
1,
0);
partitions = partitioner.getCubeIdentifiers(new AdapterDataEntry(
new ByteArrayId(
ftype.getName().getLocalPart()),
feature));
assertEquals(
2,
partitions.size());
assertTrue(hasOnePrimary(partitions));
feature = AnalyticFeature.createGeometryFeature(
ftype,
"b1",
"123",
"fred",
"NA",
20.30203,
factory.createPoint(new Coordinate(
88,
0)),
new String[] {
"extra1"
},
new double[] {
0.022
},
1,
1,
0);
partitions = partitioner.getCubeIdentifiers(new AdapterDataEntry(
new ByteArrayId(
ftype.getName().getLocalPart()),
feature));
assertEquals(
4,
partitions.size());
assertTrue(hasOnePrimary(partitions));
double maxX = 0;
double minX = 0;
double maxY = 0;
double minY = 0;
for (final PartitionData partition : partitions) {
final MultiDimensionalNumericData ranges = partitioner.getRangesForPartition(partition);
// System.out.println(ranges.getDataPerDimension()[0] + "; "
// +ranges.getDataPerDimension()[1] + " = " + partition.isPrimary);
maxX = Math.max(
maxX,
ranges.getMaxValuesPerDimension()[1]);
maxY = Math.max(
maxY,
ranges.getMaxValuesPerDimension()[0]);
minX = Math.min(
minX,
ranges.getMinValuesPerDimension()[1]);
minY = Math.min(
minY,
ranges.getMinValuesPerDimension()[0]);
}
assertTrue(maxY > 88.0);
assertTrue(minY < 88.0);
assertTrue(maxX > 0);
assertTrue(minX < 0);
}
private boolean hasOnePrimary(
final List<PartitionData> data ) {
int count = 0;
for (final PartitionData dataitem : data) {
count += (dataitem.isPrimary() ? 1 : 0);
}
return count == 1;
}
}