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