package mil.nga.giat.geowave.analytic.clustering;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.io.IOException;
import java.util.List;
import org.geotools.feature.type.BasicFeatureTypes;
import org.junit.Before;
import org.junit.Test;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
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.AnalyticItemWrapper;
import mil.nga.giat.geowave.analytic.SimpleFeatureItemWrapperFactory;
import mil.nga.giat.geowave.analytic.clustering.DistortionGroupManagement.DistortionDataAdapter;
import mil.nga.giat.geowave.analytic.clustering.DistortionGroupManagement.DistortionEntry;
import mil.nga.giat.geowave.core.geotime.ingest.SpatialDimensionalityTypeProvider;
import mil.nga.giat.geowave.core.index.StringUtils;
import mil.nga.giat.geowave.core.store.DataStore;
import mil.nga.giat.geowave.core.store.IndexWriter;
import mil.nga.giat.geowave.core.store.StoreFactoryFamilySpi;
import mil.nga.giat.geowave.core.store.StoreFactoryOptions;
import mil.nga.giat.geowave.core.store.adapter.AdapterStore;
import mil.nga.giat.geowave.core.store.adapter.WritableDataAdapter;
import mil.nga.giat.geowave.core.store.index.IndexStore;
import mil.nga.giat.geowave.core.store.index.PrimaryIndex;
import mil.nga.giat.geowave.core.store.memory.MemoryStoreFactoryFamily;
public class DistortionGroupManagementTest
{
final GeometryFactory factory = new GeometryFactory();
final SimpleFeatureType ftype;
final PrimaryIndex index = new SpatialDimensionalityTypeProvider().createPrimaryIndex();
final FeatureDataAdapter adapter;
final DataStore dataStore;
final AdapterStore adapterStore;
final IndexStore indexStore;
private <T> void ingest(
final WritableDataAdapter<T> adapter,
final PrimaryIndex index,
final T entry )
throws IOException {
try (IndexWriter writer = dataStore.createWriter(
adapter,
index)) {
writer.write(entry);
writer.close();
}
}
public DistortionGroupManagementTest() {
ftype = AnalyticFeature.createGeometryFeatureAdapter(
"centroid",
new String[] {
"extra1"
},
BasicFeatureTypes.DEFAULT_NAMESPACE,
ClusteringUtils.CLUSTERING_CRS).getFeatureType();
adapter = new FeatureDataAdapter(
ftype);
final String namespace = "test_" + getClass().getName();
final StoreFactoryFamilySpi storeFamily = new MemoryStoreFactoryFamily();
StoreFactoryOptions opts = storeFamily.getDataStoreFactory().createOptionsInstance();
opts.setGeowaveNamespace(namespace);
dataStore = storeFamily.getDataStoreFactory().createStore(
opts);
indexStore = storeFamily.getIndexStoreFactory().createStore(
opts);
adapterStore = storeFamily.getAdapterStoreFactory().createStore(
opts);
adapterStore.addAdapter(adapter);
indexStore.addIndex(index);
}
private void addDistortion(
final String grp,
final String batchId,
final int count,
final Double distortion )
throws IOException {
ingest(
new DistortionDataAdapter(),
DistortionGroupManagement.DISTORTIONS_INDEX,
new DistortionEntry(
grp,
batchId,
count,
distortion));
}
@Before
public void setup()
throws IOException {
// big jump for grp1 between batch 2 and 3
// big jump for grp2 between batch 1 and 2
// thus, the jump occurs for different groups between different batches!
// b1
addDistortion(
"grp1",
"b1",
1,
0.1);
addDistortion(
"grp2",
"b1",
1,
0.1);
// b2
addDistortion(
"grp1",
"b1",
2,
0.2);
addDistortion(
"grp2",
"b1",
2,
0.3);
// b3
addDistortion(
"grp1",
"b1",
3,
0.4);
addDistortion(
"grp2",
"b1",
3,
0.4);
// another batch to catch wrong batch error case
addDistortion(
"grp1",
"b2",
3,
0.05);
ingest(
adapter,
index,
AnalyticFeature.createGeometryFeature(
ftype,
"b1_1",
"123",
"fred",
"grp1",
20.30203,
factory.createPoint(new Coordinate(
02.33,
0.23)),
new String[] {
"extra1"
},
new double[] {
0.022
},
1,
1,
0));
ingest(
adapter,
index,
AnalyticFeature.createGeometryFeature(
ftype,
"b1_1",
"124",
"barney",
"grp1",
20.30203,
factory.createPoint(new Coordinate(
02.33,
0.23)),
new String[] {
"extra1"
},
new double[] {
0.022
},
1,
1,
0));
ingest(
adapter,
index,
AnalyticFeature.createGeometryFeature(
ftype,
"b1_1",
"125",
"wilma",
"grp2",
20.30203,
factory.createPoint(new Coordinate(
02.33,
0.23)),
new String[] {
"extra1"
},
new double[] {
0.022
},
1,
1,
0));
ingest(
adapter,
index,
AnalyticFeature.createGeometryFeature(
ftype,
"b1_1",
"126",
"betty",
"grp2",
20.30203,
factory.createPoint(new Coordinate(
02.33,
0.23)),
new String[] {
"extra1"
},
new double[] {
0.022
},
1,
1,
0));
ingest(
adapter,
index,
AnalyticFeature.createGeometryFeature(
ftype,
"b1_2",
"130",
"dusty",
"grp1",
20.30203,
factory.createPoint(new Coordinate(
02.33,
0.23)),
new String[] {
"extra1"
},
new double[] {
0.022
},
1,
1,
0));
ingest(
adapter,
index,
AnalyticFeature.createGeometryFeature(
ftype,
"b1_2",
"131",
"dino",
"grp1",
20.30203,
factory.createPoint(new Coordinate(
02.33,
0.23)),
new String[] {
"extra1"
},
new double[] {
0.022
},
1,
1,
0));
ingest(
adapter,
index,
AnalyticFeature.createGeometryFeature(
ftype,
"b1_2",
"127",
"bamm-bamm",
"grp2",
20.30203,
factory.createPoint(new Coordinate(
02.33,
0.23)),
new String[] {
"extra1"
},
new double[] {
0.022
},
1,
1,
0));
ingest(
adapter,
index,
AnalyticFeature.createGeometryFeature(
ftype,
"b1_2",
"128",
"chip",
"grp2",
20.30203,
factory.createPoint(new Coordinate(
02.33,
0.23)),
new String[] {
"extra1"
},
new double[] {
0.022
},
1,
1,
0));
ingest(
adapter,
index,
AnalyticFeature.createGeometryFeature(
ftype,
"b1_3",
"140",
"pearl",
"grp1",
20.30203,
factory.createPoint(new Coordinate(
02.33,
0.23)),
new String[] {
"extra1"
},
new double[] {
0.022
},
1,
1,
0));
ingest(
adapter,
index,
AnalyticFeature.createGeometryFeature(
ftype,
"b1_3",
"141",
"roxy",
"grp1",
20.30203,
factory.createPoint(new Coordinate(
02.33,
0.23)),
new String[] {
"extra1"
},
new double[] {
0.022
},
1,
1,
0));
ingest(
adapter,
index,
AnalyticFeature.createGeometryFeature(
ftype,
"b1_3",
"142",
"giggles",
"grp2",
20.30203,
factory.createPoint(new Coordinate(
02.33,
0.23)),
new String[] {
"extra1"
},
new double[] {
0.022
},
1,
1,
0));
ingest(
adapter,
index,
AnalyticFeature.createGeometryFeature(
ftype,
"b1_3",
"143",
"gazoo",
"grp2",
20.30203,
factory.createPoint(new Coordinate(
02.33,
0.23)),
new String[] {
"extra1"
},
new double[] {
0.022
},
1,
1,
0));
}
@Test
public void test()
throws IOException {
final DistortionGroupManagement distortionGroupManagement = new DistortionGroupManagement(
dataStore,
indexStore,
adapterStore);
distortionGroupManagement.retainBestGroups(
new SimpleFeatureItemWrapperFactory(),
StringUtils.stringFromBinary(adapter.getAdapterId().getBytes()),
StringUtils.stringFromBinary(index.getId().getBytes()),
"b1",
1);
final CentroidManagerGeoWave<SimpleFeature> centroidManager = new CentroidManagerGeoWave<SimpleFeature>(
dataStore,
indexStore,
adapterStore,
new SimpleFeatureItemWrapperFactory(),
StringUtils.stringFromBinary(adapter.getAdapterId().getBytes()),
StringUtils.stringFromBinary(index.getId().getBytes()),
"b1",
1);
final List<String> groups = centroidManager.getAllCentroidGroups();
assertEquals(
2,
groups.size());
final boolean groupFound[] = new boolean[2];
for (final String grpId : groups) {
final List<AnalyticItemWrapper<SimpleFeature>> items = centroidManager.getCentroidsForGroup(grpId);
assertEquals(
2,
items.size());
if ("grp1".equals(grpId)) {
groupFound[0] = true;
assertTrue("pearl".equals(items.get(
0).getName()) || "roxy".equals(items.get(
0).getName()));
}
else if ("grp2".equals(grpId)) {
groupFound[1] = true;
assertTrue("chip".equals(items.get(
0).getName()) || "bamm-bamm".equals(items.get(
0).getName()));
}
}
// each unique group is found?
int c = 0;
for (final boolean gf : groupFound) {
c += (gf ? 1 : 0);
}
assertEquals(
2,
c);
}
}