/* * Copyright (c) 2016 Martin Davis. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * and Eclipse Distribution License v. 1.0 which accompanies this distribution. * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html * and the Eclipse Distribution License is available at * * http://www.eclipse.org/org/documents/edl-v10.php. */ package test.jts.perf.operation.distance; import java.util.List; import org.locationtech.jts.densify.Densifier; import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.Envelope; import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.GeometryFactory; import org.locationtech.jts.geom.Polygon; import org.locationtech.jts.io.WKTFileReader; import org.locationtech.jts.io.WKTReader; import org.locationtech.jts.operation.distance.DistanceOp; import org.locationtech.jts.operation.distance.IndexedFacetDistance; import org.locationtech.jts.util.Stopwatch; /** * Tests performance of {@link IndexedFacetDistance} versus standard * {@link DistanceOp} * using a grid of points to a target set of lines * * @author Martin Davis * */ public class TestPerfDistanceLinesPoints { static final boolean USE_INDEXED_DIST = true; static GeometryFactory geomFact = new GeometryFactory(); static final int MAX_ITER = 1; static final int NUM_TARGET_ITEMS = 4000; static final double EXTENT = 1000; static final int NUM_PTS_SIDE = 100; public static void main(String[] args) { TestPerfDistanceLinesPoints test = new TestPerfDistanceLinesPoints(); try { test.test(); } catch (Exception ex) { ex.printStackTrace(); } } boolean verbose = true; public TestPerfDistanceLinesPoints() { } public void test() throws Exception { //test(200); //if (true) return; // test(5000); // test(8001); //test(50); test(100); test(200); test(500); test(1000); //test(5000); //test(10000); //test(50000); //test(100000); } public void test(int num) throws Exception { //Geometry lines = createLine(EXTENT, num); Geometry target = createDiagonalCircles(EXTENT, NUM_TARGET_ITEMS); Geometry[] pts = createPoints(target.getEnvelopeInternal(), num); /* Geometry target = loadData("C:\\data\\martin\\proj\\jts\\testing\\distance\\bc_coast.wkt"); Envelope bcEnv_Albers = new Envelope(-45838, 1882064, 255756, 1733287); Geometry[] pts = createPoints(bcEnv_Albers, num); */ test(pts, target); } public void xtest(int num) throws Exception { Geometry target = loadData("C:\\proj\\JTS\\test\\g2e\\ffmwdec08.wkt"); Envelope bcEnv_Albers = new Envelope(-45838, 1882064, 255756, 1733287); Geometry[] pts = createPoints(bcEnv_Albers, num); test(pts, target); } public void test(Geometry[] pts, Geometry target) { if (verbose) System.out.println("Query points = " + pts.length + " Target points = " + target.getNumPoints()); // if (! verbose) System.out.print(num + ", "); Stopwatch sw = new Stopwatch(); double dist = 0.0; for (int i = 0; i < MAX_ITER; i++) { computeDistance(pts, target); } if (! verbose) System.out.println(sw.getTimeString()); if (verbose) { String name = USE_INDEXED_DIST ? "IndexedFacetDistance" : "Distance"; System.out.println(name + " - Run time: " + sw.getTimeString()); //System.out.println(" (Distance = " + dist + ")\n"); System.out.println(); } } void computeDistance(Geometry[] pts, Geometry geom) { IndexedFacetDistance bbd = null; if (USE_INDEXED_DIST) bbd = new IndexedFacetDistance(geom); for (int i = 0; i < pts.length; i++ ) { if (USE_INDEXED_DIST) { double dist = bbd.getDistance(pts[i]); // double dist = bbd.getDistanceWithin(pts[i].getCoordinate(), 100000); } else { double dist = geom.distance(pts[i]); } } } Geometry createDiagonalCircles(double extent, int nSegs) { Polygon[] circles = new Polygon[nSegs]; double inc = extent / nSegs; for (int i = 0; i < nSegs; i++) { double ord = i * inc; Coordinate p = new Coordinate(ord, ord); Geometry pt = geomFact.createPoint(p); circles[i] = (Polygon) pt.buffer(inc/2); } return geomFact.createMultiPolygon(circles); } Geometry createLine(double extent, int nSegs) { Coordinate[] pts = new Coordinate[] { new Coordinate(0,0), new Coordinate(0, extent), new Coordinate(extent, extent), new Coordinate(extent, 0) }; Geometry outline = geomFact.createLineString(pts); double inc = extent / nSegs; return Densifier.densify(outline, inc); } Geometry createDiagonalLine(double extent, int nSegs) { Coordinate[] pts = new Coordinate[nSegs + 1]; pts[0] = new Coordinate(0,0); double inc = extent / nSegs; for (int i = 1; i <= nSegs; i++) { double ord = i * inc; pts[i] = new Coordinate(ord, ord); } return geomFact.createLineString(pts); } Geometry[] createPoints(Envelope extent, int nPtsSide) { Geometry[] pts = new Geometry[nPtsSide * nPtsSide]; int index = 0; double xinc = extent.getWidth() / nPtsSide; double yinc = extent.getHeight() / nPtsSide; for (int i = 0; i < nPtsSide; i++) { for (int j = 0; j < nPtsSide; j++) { pts[index++] = geomFact.createPoint( new Coordinate( extent.getMinX() + i * xinc, extent.getMinY() + j * yinc)); } } return pts; } Geometry loadData(String file) throws Exception { List geoms = loadWKT(file); return geomFact.buildGeometry(geoms); } List loadWKT(String filename) throws Exception { WKTReader rdr = new WKTReader(); WKTFileReader fileRdr = new WKTFileReader(filename, rdr); return fileRdr.read(); } }