diff --git a/lucene/core/src/test/org/apache/lucene/geo/TestGeoUtils.java b/lucene/core/src/test/org/apache/lucene/geo/TestGeoUtils.java index 8727b42afa6..48db105b084 100644 --- a/lucene/core/src/test/org/apache/lucene/geo/TestGeoUtils.java +++ b/lucene/core/src/test/org/apache/lucene/geo/TestGeoUtils.java @@ -308,7 +308,10 @@ public class TestGeoUtils extends LuceneTestCase { centerLat, centerLon, lat, lon, distance, Rectangle.fromPointDistance(centerLat, centerLon, radius)), distance > radius); } catch (AssertionError e) { - GeoTestUtil.toWebGLEarth(latMin, latMax, lonMin, lonMax, centerLat, centerLon, radius); + EarthDebugger ed = new EarthDebugger(); + ed.addRect(latMin, latMax, lonMin, lonMax); + ed.addCircle(centerLat, centerLon, radius, true); + System.out.println(ed.finish()); throw e; } } diff --git a/lucene/test-framework/src/java/org/apache/lucene/geo/EarthDebugger.java b/lucene/test-framework/src/java/org/apache/lucene/geo/EarthDebugger.java new file mode 100644 index 00000000000..14956f2c167 --- /dev/null +++ b/lucene/test-framework/src/java/org/apache/lucene/geo/EarthDebugger.java @@ -0,0 +1,267 @@ +package org.apache.lucene.geo; + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import org.apache.lucene.geo.Polygon; +import org.apache.lucene.geo.Rectangle; +import org.apache.lucene.util.SloppyMath; + +/** Draws shapes on the earth surface and renders using the very cool http://www.webglearth.org. + * + * Just instantiate this class, add the things you want plotted, and call {@link #finish} to get the + * resulting HTML that you should save and load with a browser. */ + +public class EarthDebugger { + final StringBuilder b = new StringBuilder(); + private int nextShape; + + public EarthDebugger() { + b.append("\n"); + b.append("\n"); + b.append(" \n"); + b.append(" \n"); + b.append(" \n"); + b.append(" \n"); + b.append(" WebGL Earth API: Hello World\n"); + b.append(" \n"); + b.append(" \n"); + b.append("
\n"); + b.append(" \n"); + b.append("\n"); + + return b.toString(); + } + + private static void inverseHaversin(StringBuilder b, double centerLat, double centerLon, double radiusMeters) { + double angle = 0; + int steps = 100; + + newAngle: + while (angle < 360) { + double x = Math.cos(Math.toRadians(angle)); + double y = Math.sin(Math.toRadians(angle)); + double factor = 2.0; + double step = 1.0; + int last = 0; + double lastDistanceMeters = 0.0; + //System.out.println("angle " + angle + " slope=" + slope); + while (true) { + double lat = wrapLat(centerLat + y * factor); + double lon = wrapLon(centerLon + x * factor); + double distanceMeters = SloppyMath.haversinMeters(centerLat, centerLon, lat, lon); + + if (last == 1 && distanceMeters < lastDistanceMeters) { + // For large enough circles, some angles are not possible: + //System.out.println(" done: give up on angle " + angle); + angle += 360./steps; + continue newAngle; + } + if (last == -1 && distanceMeters > lastDistanceMeters) { + // For large enough circles, some angles are not possible: + //System.out.println(" done: give up on angle " + angle); + angle += 360./steps; + continue newAngle; + } + lastDistanceMeters = distanceMeters; + + //System.out.println(" iter lat=" + lat + " lon=" + lon + " distance=" + distanceMeters + " vs " + radiusMeters); + if (Math.abs(distanceMeters - radiusMeters) < 0.1) { + b.append(" [" + lat + ", " + lon + "],\n"); + break; + } + if (distanceMeters > radiusMeters) { + // too big + //System.out.println(" smaller"); + factor -= step; + if (last == 1) { + //System.out.println(" half-step"); + step /= 2.0; + } + last = -1; + } else if (distanceMeters < radiusMeters) { + // too small + //System.out.println(" bigger"); + factor += step; + if (last == -1) { + //System.out.println(" half-step"); + step /= 2.0; + } + last = 1; + } + } + angle += 360./steps; + } + } + // craziness for plotting stuff :) + + private static double wrapLat(double lat) { + //System.out.println("wrapLat " + lat); + if (lat > 90) { + //System.out.println(" " + (180 - lat)); + return 180 - lat; + } else if (lat < -90) { + //System.out.println(" " + (-180 - lat)); + return -180 - lat; + } else { + //System.out.println(" " + lat); + return lat; + } + } + + private static double wrapLon(double lon) { + //System.out.println("wrapLon " + lon); + if (lon > 180) { + //System.out.println(" " + (lon - 360)); + return lon - 360; + } else if (lon < -180) { + //System.out.println(" " + (lon + 360)); + return lon + 360; + } else { + //System.out.println(" " + lon); + return lon; + } + } +} diff --git a/lucene/test-framework/src/java/org/apache/lucene/geo/GeoTestUtil.java b/lucene/test-framework/src/java/org/apache/lucene/geo/GeoTestUtil.java index 0d241f6dc66..23e34164668 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/geo/GeoTestUtil.java +++ b/lucene/test-framework/src/java/org/apache/lucene/geo/GeoTestUtil.java @@ -281,232 +281,4 @@ public class GeoTestUtil { private static Random random() { return RandomizedContext.current().getRandom(); } - - // craziness for plotting stuff :) - - private static double wrapLat(double lat) { - //System.out.println("wrapLat " + lat); - if (lat > 90) { - //System.out.println(" " + (180 - lat)); - return 180 - lat; - } else if (lat < -90) { - //System.out.println(" " + (-180 - lat)); - return -180 - lat; - } else { - //System.out.println(" " + lat); - return lat; - } - } - - private static double wrapLon(double lon) { - //System.out.println("wrapLon " + lon); - if (lon > 180) { - //System.out.println(" " + (lon - 360)); - return lon - 360; - } else if (lon < -180) { - //System.out.println(" " + (lon + 360)); - return lon + 360; - } else { - //System.out.println(" " + lon); - return lon; - } - } - - private static void drawRectApproximatelyOnEarthSurface(String name, String color, double minLat, double maxLat, double minLon, double maxLon) { - int steps = 20; - System.out.println(" var " + name + " = WE.polygon(["); - System.out.println(" // min -> max lat, min lon"); - for(int i=0;i max lon"); - for(int i=0;i min lat, max lon"); - for(int i=0;i min lon"); - for(int i=0;i=minLon;lon -= (maxLon-minLon)/36) { - System.out.println(" [" + lat + ", " + lon + "],"); - } - System.out.println(" ], {color: \"" + color + "\", fillColor: \"#ffffff\", opacity: " + (color.equals("#ffffff") ? "0.3" : "1") + ", fillOpacity: 0.0001});"); - System.out.println(" " + name + ".addTo(earth);"); - } - - private static void plotLonApproximatelyOnEarthSurface(String name, String color, double lon, double minLat, double maxLat) { - System.out.println(" var " + name + " = WE.polygon(["); - double lat; - for(lat = minLat;lat<=maxLat;lat += (maxLat-minLat)/36) { - System.out.println(" [" + lat + ", " + lon + "],"); - } - System.out.println(" [" + maxLat + ", " + lon + "],"); - lat -= (maxLat-minLat)/36; - for(;lat>=minLat;lat -= (maxLat-minLat)/36) { - System.out.println(" [" + lat + ", " + lon + "],"); - } - System.out.println(" ], {color: \"" + color + "\", fillColor: \"#ffffff\", opacity: " + (color.equals("#ffffff") ? "0.3" : "1") + ", fillOpacity: 0.0001});"); - System.out.println(" " + name + ".addTo(earth);"); - } - - // http://www.webglearth.org has API details: - public static void polysToWebGLEarth(List polys) { - System.out.println(""); - System.out.println(""); - System.out.println(" "); - System.out.println(" "); - System.out.println(" "); - System.out.println(" "); - System.out.println(" WebGL Earth API: Hello World"); - System.out.println(" "); - System.out.println(" "); - System.out.println("
"); - System.out.println(" "); - System.out.println(""); - } - - // http://www.webglearth.org has API details: - public static void toWebGLEarth(double rectMinLatitude, double rectMaxLatitude, - double rectMinLongitude, double rectMaxLongitude, - double centerLatitude, double centerLongitude, - double radiusMeters) { - Rectangle box = Rectangle.fromPointDistance(centerLatitude, centerLongitude, radiusMeters); - System.out.println(""); - System.out.println(""); - System.out.println(" "); - System.out.println(" "); - System.out.println(" "); - System.out.println(" "); - System.out.println(" WebGL Earth API: Hello World"); - System.out.println(" "); - System.out.println(" "); - System.out.println("
"); - System.out.println(" "); - System.out.println(""); - } - - private static void inverseHaversin(StringBuilder b, double centerLat, double centerLon, double radiusMeters) { - double angle = 0; - int steps = 100; - - newAngle: - while (angle < 360) { - double x = Math.cos(Math.toRadians(angle)); - double y = Math.sin(Math.toRadians(angle)); - double factor = 2.0; - double step = 1.0; - int last = 0; - double lastDistanceMeters = 0.0; - //System.out.println("angle " + angle + " slope=" + slope); - while (true) { - double lat = wrapLat(centerLat + y * factor); - double lon = wrapLon(centerLon + x * factor); - double distanceMeters = SloppyMath.haversinMeters(centerLat, centerLon, lat, lon); - - if (last == 1 && distanceMeters < lastDistanceMeters) { - // For large enough circles, some angles are not possible: - //System.out.println(" done: give up on angle " + angle); - angle += 360./steps; - continue newAngle; - } - if (last == -1 && distanceMeters > lastDistanceMeters) { - // For large enough circles, some angles are not possible: - //System.out.println(" done: give up on angle " + angle); - angle += 360./steps; - continue newAngle; - } - lastDistanceMeters = distanceMeters; - - //System.out.println(" iter lat=" + lat + " lon=" + lon + " distance=" + distanceMeters + " vs " + radiusMeters); - if (Math.abs(distanceMeters - radiusMeters) < 0.1) { - b.append(" [" + lat + ", " + lon + "],\n"); - break; - } - if (distanceMeters > radiusMeters) { - // too big - //System.out.println(" smaller"); - factor -= step; - if (last == 1) { - //System.out.println(" half-step"); - step /= 2.0; - } - last = -1; - } else if (distanceMeters < radiusMeters) { - // too small - //System.out.println(" bigger"); - factor += step; - if (last == -1) { - //System.out.println(" half-step"); - step /= 2.0; - } - last = 1; - } - } - angle += 360./steps; - } - } }