package org.wikibrain.spatial.utils;
import com.vividsolutions.jts.geom.*;
import org.apache.commons.io.FileUtils;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.junit.Before;
import org.junit.Test;
import org.opengis.feature.simple.SimpleFeature;
import org.wikibrain.core.dao.DaoException;
import org.wikibrain.spatial.WikiBrainShapeFile;
import org.wikibrain.spatial.util.ContainmentIndex;
import org.wikibrain.utils.WpIOUtils;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
/**
* @author Shilad Sen
*/
public class TestContainmentIndex {
private static final String SHP_PREFIX = "cb_2013_us_state_20m";
private Random random = new Random();
private GeometryFactory factory = new GeometryFactory(new PrecisionModel(),8307);
private File shpDir;
private List<StateGeom> states;
private ContainmentIndex index;
private
static final class StateGeom {
public String name;
public int id;
public Geometry geometry;
}
@Before
public void prepareIndex() throws IOException {
File shpDir = WpIOUtils.createTempDirectory("wikibrain-state-shp");
for (String ext : WikiBrainShapeFile.EXTENSIONS) {
String src = "/states/" + SHP_PREFIX + ext;
InputStream is = WpIOUtils.class.getResourceAsStream(src);
if (is == null) {
throw new FileNotFoundException("Unknown resource: " + src);
}
File dest = FileUtils.getFile(shpDir, SHP_PREFIX + ext);
FileUtils.copyInputStreamToFile(is, dest);
}
FileUtils.forceDeleteOnExit(shpDir);
WikiBrainShapeFile shp = new WikiBrainShapeFile(FileUtils.getFile(shpDir, SHP_PREFIX + ".shp"));
SimpleFeatureIterator iter = shp.getFeatureIter();
states = new ArrayList<StateGeom>();
this.index = new ContainmentIndex();
int i = 0;
while (iter.hasNext()) {
SimpleFeature f = iter.next();
StateGeom sg = new StateGeom();
sg.name = (String) f.getAttribute("NAME");
sg.geometry = (Geometry) f.getDefaultGeometry();
sg.id = i++;
states.add(sg);
index.insert(sg.id, sg.geometry);
}
}
@Test
public void testSimple() throws DaoException {
// In minnesota
List<ContainmentIndex.Result> result = index.getContainer(point(-97.0448, 48.8994));
assertEquals(1, result.size());
assertEquals("Minnesota", name(result.get(0).id));
// just across the border, but only near MN.
result = index.getContainer(point(-96.9167, 49.0968));
assertEquals(1, result.size());
assertEquals("Minnesota", name(result.get(0).id));
// just across the border, but equidistant to both MN and ND
result = index.getContainer(point(-97.2286, 49.0136));
assertEquals(2, result.size());
assertTrue(Arrays.asList("Minnesota", "North Dakota").contains(name(result.get(0).id)));
assertTrue(Arrays.asList("Minnesota", "North Dakota").contains(name(result.get(1).id)));
// just across the border, but equidistant to both MN and ND
result = index.getContainer(point(-97.2286, 49.2136));
assertEquals(0, result.size());
}
private Point point(double lon, double lat) {
return factory.createPoint(new Coordinate(lon, lat));
}
private String name(int id) {
for (StateGeom g : states) {
if (g.id == id) {
return g.name;
}
}
throw new IllegalArgumentException(""+id);
}
}