You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by kw...@apache.org on 2016/04/08 21:55:50 UTC

lucene-solr:branch_6x: LUCENE-7195: Clockwise/counterclockwise detection was rotating coordinates in the wrong direction.

Repository: lucene-solr
Updated Branches:
  refs/heads/branch_6x 707960fb2 -> 30d612f84


LUCENE-7195: Clockwise/counterclockwise detection was rotating coordinates in the wrong direction.


Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/30d612f8
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/30d612f8
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/30d612f8

Branch: refs/heads/branch_6x
Commit: 30d612f84ed71b00ef981c24dd77d305b326a7e8
Parents: 707960f
Author: Karl Wright <Da...@gmail.com>
Authored: Fri Apr 8 15:53:12 2016 -0400
Committer: Karl Wright <Da...@gmail.com>
Committed: Fri Apr 8 15:54:29 2016 -0400

----------------------------------------------------------------------
 .../spatial3d/geom/GeoPolygonFactory.java       | 45 ++++++++++----------
 .../apache/lucene/spatial3d/TestGeo3DPoint.java | 34 +++++++++------
 2 files changed, 44 insertions(+), 35 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/30d612f8/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoPolygonFactory.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoPolygonFactory.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoPolygonFactory.java
index 67804a2..a68f908 100755
--- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoPolygonFactory.java
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoPolygonFactory.java
@@ -116,6 +116,7 @@ public class GeoPolygonFactory {
       final Boolean isPoleInside = isInsidePolygon(pole, pointList);
       if (isPoleInside != null) {
         // Legal pole
+        //System.out.println("Pole = "+pole+"; isInside="+isPoleInside+"; pointList = "+pointList);
         return makeGeoPolygon(planetModel, pointList, holes, pole, isPoleInside);
       }
       // If pole choice was illegal, try another one
@@ -177,24 +178,17 @@ public class GeoPolygonFactory {
    */
   private static Boolean isInsidePolygon(final GeoPoint point, final List<GeoPoint> polyPoints) {
     // First, compute sine and cosine of pole point latitude and longitude
-    final double norm = 1.0 / point.magnitude();
-    final double xyDenom = Math.sqrt(point.x * point.x + point.y * point.y);
-    final double sinLatitude = point.z * norm;
-    final double cosLatitude = xyDenom * norm;
-    final double sinLongitude;
-    final double cosLongitude;
-    if (Math.abs(xyDenom) < Vector.MINIMUM_RESOLUTION) {
-      sinLongitude = 0.0;
-      cosLongitude = 1.0;
-    } else {
-      final double xyNorm = 1.0 / xyDenom;
-      sinLongitude = point.y * xyNorm;
-      cosLongitude = point.x * xyNorm;
-    }
+    final double latitude = point.getLatitude();
+    final double longitude = point.getLongitude();
+    final double sinLatitude = Math.sin(latitude);
+    final double cosLatitude = Math.cos(latitude);
+    final double sinLongitude = Math.sin(longitude);
+    final double cosLongitude = Math.cos(longitude);
     
     // Now, compute the incremental arc distance around the points of the polygon
     double arcDistance = 0.0;
     Double prevAngle = null;
+    //System.out.println("Computing angles:");
     for (final GeoPoint polyPoint : polyPoints) {
       final Double angle = computeAngle(polyPoint, sinLatitude, cosLatitude, sinLongitude, cosLongitude);
       if (angle == null) {
@@ -215,6 +209,7 @@ public class GeoPolygonFactory {
         }
         //System.out.println(" angle delta = "+angleDelta);
         arcDistance += angleDelta;
+        //System.out.println(" For point "+polyPoint+" angle is "+angle+"; delta is "+angleDelta+"; arcDistance is "+arcDistance);
       }
       prevAngle = angle;
     }
@@ -237,7 +232,9 @@ public class GeoPolygonFactory {
       }
       //System.out.println(" angle delta = "+angleDelta);
       arcDistance += angleDelta;
+      //System.out.println(" For point "+polyPoints.get(0)+" angle is "+lastAngle+"; delta is "+angleDelta+"; arcDistance is "+arcDistance);
     }
+
     // Clockwise == inside == negative
     //System.out.println("Arcdistance = "+arcDistance);
     if (Math.abs(arcDistance) < Vector.MINIMUM_RESOLUTION) {
@@ -266,21 +263,23 @@ public class GeoPolygonFactory {
     // We need to rotate the point in question into the coordinate frame specified by
     // the lat and lon trig functions.
     // To do this we need to do two rotations on it.  First rotation is in x/y.  Second rotation is in x/z.
+    // And we rotate in the negative direction.
     // So:
-    // x1 = x0 cos az - y0 sin az
-    // y1 = x0 sin az + y0 cos az
+    // x1 = x0 cos az + y0 sin az
+    // y1 = - x0 sin az + y0 cos az
     // z1 = z0
-    // x2 = x1 cos al - z1 sin al
+    // x2 = x1 cos al + z1 sin al
     // y2 = y1
-    // z2 = x1 sin al + z1 cos al
+    // z2 = - x1 sin al + z1 cos al
       
-    final double x1 = point.x * cosLongitude - point.y * sinLongitude;
-    final double y1 = point.x * sinLongitude + point.y * cosLongitude;
+    final double x1 = point.x * cosLongitude + point.y * sinLongitude;
+    final double y1 = - point.x * sinLongitude + point.y * cosLongitude;
     final double z1 = point.z;
-    //final double x2 = x1 * cosLatitude - z1 * sinLatitude;
-    final double y2 = y1;
-    final double z2 = x1 * sinLatitude + z1 * cosLatitude;
       
+    // final double x2 = x1 * cosLatitude + z1 * sinLatitude;
+    final double y2 = y1;
+    final double z2 = - x1 * sinLatitude + z1 * cosLatitude;
+    
     // Now we should be looking down the X axis; the original point has rotated coordinates (N, 0, 0).
     // So we can just compute the angle using y2 and z2.  (If Math.sqrt(y2*y2 + z2 * z2) is 0.0, then the point is on the pole and we need another one).
     if (Math.sqrt(y2*y2 + z2*z2) < Vector.MINIMUM_RESOLUTION) {

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/30d612f8/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/TestGeo3DPoint.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/TestGeo3DPoint.java b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/TestGeo3DPoint.java
index d1aa416..4e2e02e 100644
--- a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/TestGeo3DPoint.java
+++ b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/TestGeo3DPoint.java
@@ -517,6 +517,16 @@ public class TestGeo3DPoint extends LuceneTestCase {
     verify(lats, lons);
   }
 
+  public void testPolygonOrdering() {
+    final double[] lats = new double[] {
+      51.204382859999996, 50.89947531437482, 50.8093624806861,50.8093624806861, 50.89947531437482, 51.204382859999996, 51.51015366140113, 51.59953838204167, 51.59953838204167, 51.51015366140113, 51.204382859999996};
+    final double[] lons = new double[] {
+      0.8747711978759765, 0.6509219832137298, 0.35960265165247807, 0.10290284834752167, -0.18841648321373008, -0.41226569787597667, -0.18960465285650027, 0.10285893781346236, 0.35964656218653757, 0.6521101528565002, 0.8747711978759765};
+    final Query q = Geo3DPoint.newPolygonQuery("point", new Polygon(lats, lons));
+    //System.out.println(q);
+    assertTrue(!q.toString().contains("GeoConcavePolygon"));
+  }
+  
   private static final double MEAN_EARTH_RADIUS_METERS = PlanetModel.WGS84_MEAN;
   
   private static Query random3DQuery(final String field) {
@@ -982,26 +992,26 @@ public class TestGeo3DPoint extends LuceneTestCase {
     // x1 = x0 cos T - y0 sin T
     // y1 = x0 sin T + y0 cos T
     // We're in essence undoing the following transformation (from GeoPolygonFactory):
-    // x1 = x0 cos az - y0 sin az
-    // y1 = x0 sin az + y0 cos az
+    // x1 = x0 cos az + y0 sin az
+    // y1 = - x0 sin az + y0 cos az
     // z1 = z0
-    // x2 = x1 cos al - z1 sin al
+    // x2 = x1 cos al + z1 sin al
     // y2 = y1
-    // z2 = x1 sin al + z1 cos al
+    // z2 = - x1 sin al + z1 cos al
     // So, we reverse the order of the transformations, AND we transform backwards.
     // Transforming backwards means using these identities: sin(-angle) = -sin(angle), cos(-angle) = cos(angle)
     // So:
-    // x1 = x0 cos al + z0 sin al
+    // x1 = x0 cos al - z0 sin al
     // y1 = y0
-    // z1 = - x0 sin al + z0 cos al
-    // x2 = x1 cos az + y1 sin az
-    // y2 = - x1 sin az + y1 cos az
+    // z1 = x0 sin al + z0 cos al
+    // x2 = x1 cos az - y1 sin az
+    // y2 = x1 sin az + y1 cos az
     // z2 = z1
-    final double x1 = x * cosLatitude + z * sinLatitude;
+    final double x1 = x * cosLatitude - z * sinLatitude;
     final double y1 = y;
-    final double z1 = - x * sinLatitude + z * cosLatitude;
-    final double x2 = x1 * cosLongitude + y1 * sinLongitude;
-    final double y2 = - x1 * sinLongitude + y1 * cosLongitude;
+    final double z1 = x * sinLatitude + z * cosLatitude;
+    final double x2 = x1 * cosLongitude - y1 * sinLongitude;
+    final double y2 = x1 * sinLongitude + y1 * cosLongitude;
     final double z2 = z1;
 
     // Scale final (x,y,z) to land on planet surface