package org.wikibrain.spatial.distance; import com.vividsolutions.jts.geom.*; import org.junit.Before; import org.junit.Test; import org.wikibrain.core.dao.DaoException; import org.wikibrain.spatial.constants.Precision; import org.wikibrain.spatial.dao.SpatialDataDao; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Random; import static junit.framework.Assert.assertEquals; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; /** * @author Shilad Sen */ public class TestGraphDistanceMetric { private static final int LATTICE_ROWS = 5; private static final int LATTICE_COLS = 100; private Random random = new Random(); private GeometryFactory factory = new GeometryFactory(new PrecisionModel(),8307); private Point[][] lattice = new Point[LATTICE_ROWS][LATTICE_COLS]; @Before public void makeLattice() { for (int i = 0; i < LATTICE_ROWS; i++) { for (int j = 0; j < LATTICE_COLS; j++) { lattice[i][j] = factory.createPoint(new Coordinate(j, i)); } } } private GraphDistanceMetric getLatticeMetric() throws DaoException { Map<Integer, Geometry> points = new HashMap<Integer, Geometry>(); for (int i = 0; i < LATTICE_ROWS; i++) { for (int j = 0; j < LATTICE_COLS; j++) { points.put(points.size(), lattice[i][j]); } } SpatialDataDao dao = mock(SpatialDataDao.class); when(dao.getAllGeometriesInLayer("wikidata", Precision.LatLonPrecision.HIGH)) .thenReturn(points); SphericalDistanceMetric metric1 = new SphericalDistanceMetric(dao); metric1.enableCache(true); GraphDistanceMetric metric2 = new GraphDistanceMetric(dao, metric1); metric2.enableCache(true); metric2.setMaxDistance(10); metric2.setNumNeighbors(25); return metric2; } @Test public void testKnn() throws DaoException { Map<Integer, Geometry> points = new HashMap<Integer, Geometry>(); for (int i = 0; i < 10000; i++) { points.put(i * 3, makePoint()); } SpatialDataDao dao = mock(SpatialDataDao.class); when(dao.getAllGeometriesInLayer("wikidata", Precision.LatLonPrecision.HIGH)) .thenReturn(points); SphericalDistanceMetric metric1 = new SphericalDistanceMetric(dao); metric1.enableCache(true); GraphDistanceMetric metric2 = new GraphDistanceMetric(dao, metric1); metric2.enableCache(true); Point query = makePoint(); List<SpatialDistanceMetric.Neighbor> neighbors = metric2.getNeighbors(query, Integer.MAX_VALUE, 15); for (int i = 0; i < 100; i++) { Point p1 = makePoint(); Point p2 = makePoint(); System.out.println("distance is " + metric2.distance(p1, p2)); } System.out.println("Num neighbors are: " + neighbors.size()); } @Test public void testLattice() throws DaoException { GraphDistanceMetric metric = getLatticeMetric(); // Test distances from middle row, first column to other rows in first column assertEquals(1.0, metric.distance(lattice[2][0], lattice[0][0]), 0.01); assertEquals(1.0, metric.distance(lattice[2][0], lattice[1][0]), 0.01); assertEquals(0.0, metric.distance(lattice[2][0], lattice[2][0]), 0.01); assertEquals(1.0, metric.distance(lattice[2][0], lattice[3][0]), 0.01); assertEquals(1.0, metric.distance(lattice[2][0], lattice[4][0]), 0.01); /* * Distances from target node: * * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 * * 1 1 1 1 1 2 2 2 3 3 3 4 4 4 5 5 5 6 6 6 * 1 1 1 1 1 2 2 2 3 3 3 4 4 5 5 5 5 6 6 7 * 0 1 1 1 1 2 2 3 3 3 4 4 4 5 5 5 6 6 6 7 * 1 1 1 1 1 2 2 2 3 3 3 4 4 4 5 5 5 6 6 6 * 1 1 1 1 1 2 2 2 3 3 3 4 4 4 5 5 5 6 6 6 */ for (int i = 0; i < LATTICE_ROWS; i++) { for (int j = 0; j < 20; j++) { int d = (int) Math.round(metric.distance(lattice[2][0], lattice[i][j])); System.err.print(" " + d); } System.err.println(""); } } private Point makePoint() { double lat = 90 - random.nextDouble() * 180; double lon = 180 - random.nextDouble() * 360; return factory.createPoint(new Coordinate(lon, lat)); } }