LUCENE-7934: Add planet model interface.

This commit is contained in:
Karl Wright 2017-08-20 08:01:19 -04:00
parent a4374e840d
commit 94b695e672
19 changed files with 97 additions and 27 deletions

View File

@ -134,12 +134,12 @@ class Geo3DUtil {
final GeoPolygon component = fromPolygon(polygons[0]); final GeoPolygon component = fromPolygon(polygons[0]);
if (component == null) { if (component == null) {
// Polygon is degenerate // Polygon is degenerate
shape = new GeoCompositePolygon(); shape = new GeoCompositePolygon(PlanetModel.WGS84);
} else { } else {
shape = component; shape = component;
} }
} else { } else {
final GeoCompositePolygon poly = new GeoCompositePolygon(); final GeoCompositePolygon poly = new GeoCompositePolygon(PlanetModel.WGS84);
for (final Polygon p : polygons) { for (final Polygon p : polygons) {
final GeoPolygon component = fromPolygon(p); final GeoPolygon component = fromPolygon(p);
if (component != null) { if (component != null) {

View File

@ -22,7 +22,7 @@ package org.apache.lucene.spatial3d.geom;
* *
* @lucene.internal * @lucene.internal
*/ */
public abstract class BasePlanetObject { public abstract class BasePlanetObject implements PlanetObject {
/** This is the planet model embedded in all objects derived from this /** This is the planet model embedded in all objects derived from this
* class. */ * class. */
@ -35,7 +35,7 @@ public abstract class BasePlanetObject {
this.planetModel = planetModel; this.planetModel = planetModel;
} }
/** Returns the {@link PlanetModel} provided when this shape was created. */ @Override
public PlanetModel getPlanetModel() { public PlanetModel getPlanetModel() {
return planetModel; return planetModel;
} }

View File

@ -94,6 +94,9 @@ abstract class GeoBaseAreaShape extends GeoBaseMembershipShape implements GeoAre
@Override @Override
public int getRelationship(GeoShape geoShape) { public int getRelationship(GeoShape geoShape) {
if (!geoShape.getPlanetModel().equals(planetModel)) {
throw new IllegalArgumentException("Cannot relate shapes with different planet models.");
}
final int insideGeoAreaShape = isShapeInsideGeoAreaShape(geoShape); final int insideGeoAreaShape = isShapeInsideGeoAreaShape(geoShape);
if (insideGeoAreaShape == SOME_INSIDE) { if (insideGeoAreaShape == SOME_INSIDE) {
return GeoArea.OVERLAPS; return GeoArea.OVERLAPS;

View File

@ -35,7 +35,8 @@ abstract class GeoBaseCompositeAreaShape<T extends GeoAreaShape> extends GeoBase
/** /**
* Constructor. * Constructor.
*/ */
public GeoBaseCompositeAreaShape() { public GeoBaseCompositeAreaShape(PlanetModel planetModel) {
super(planetModel);
} }
@Override @Override
@ -50,6 +51,9 @@ abstract class GeoBaseCompositeAreaShape<T extends GeoAreaShape> extends GeoBase
@Override @Override
public int getRelationship(GeoShape geoShape) { public int getRelationship(GeoShape geoShape) {
if (!geoShape.getPlanetModel().equals(planetModel)) {
throw new IllegalArgumentException("Cannot relate shapes with different planet models.");
}
final int insideGeoAreaShape = isShapeInsideGeoAreaShape(geoShape); final int insideGeoAreaShape = isShapeInsideGeoAreaShape(geoShape);
if (insideGeoAreaShape == SOME_INSIDE) { if (insideGeoAreaShape == SOME_INSIDE) {
return GeoArea.OVERLAPS; return GeoArea.OVERLAPS;

View File

@ -29,7 +29,8 @@ abstract class GeoBaseCompositeMembershipShape<T extends GeoMembershipShape>
/** /**
* Constructor. * Constructor.
*/ */
GeoBaseCompositeMembershipShape() { GeoBaseCompositeMembershipShape(PlanetModel planetModel) {
super(planetModel);
} }
@Override @Override

View File

@ -27,7 +27,7 @@ import java.util.List;
* @param <T> is the type of GeoShapes of the composite. * @param <T> is the type of GeoShapes of the composite.
* @lucene.experimental * @lucene.experimental
*/ */
public abstract class GeoBaseCompositeShape<T extends GeoShape> implements GeoShape { public abstract class GeoBaseCompositeShape<T extends GeoShape> extends BasePlanetObject implements GeoShape {
/** /**
* Shape's container * Shape's container
@ -37,7 +37,8 @@ public abstract class GeoBaseCompositeShape<T extends GeoShape> implements GeoSh
/** /**
* Constructor. * Constructor.
*/ */
public GeoBaseCompositeShape() { public GeoBaseCompositeShape(PlanetModel planetModel) {
super(planetModel);
} }
/** /**
@ -46,6 +47,9 @@ public abstract class GeoBaseCompositeShape<T extends GeoShape> implements GeoSh
* @param shape is the shape to add. * @param shape is the shape to add.
*/ */
public void addShape(final T shape) { public void addShape(final T shape) {
if (!shape.getPlanetModel().equals(planetModel)) {
throw new IllegalArgumentException("Cannot add a shape into a composite with different planet models.");
}
shapes.add(shape); shapes.add(shape);
} }
@ -108,7 +112,7 @@ public abstract class GeoBaseCompositeShape<T extends GeoShape> implements GeoSh
@Override @Override
public int hashCode() { public int hashCode() {
return shapes.hashCode(); return super.hashCode() + shapes.hashCode();
} }
@Override @Override
@ -116,6 +120,6 @@ public abstract class GeoBaseCompositeShape<T extends GeoShape> implements GeoSh
if (!(o instanceof GeoBaseCompositeShape<?>)) if (!(o instanceof GeoBaseCompositeShape<?>))
return false; return false;
GeoBaseCompositeShape<?> other = (GeoBaseCompositeShape<?>) o; GeoBaseCompositeShape<?> other = (GeoBaseCompositeShape<?>) o;
return shapes.equals(other.shapes); return super.equals(other) && shapes.equals(other.shapes);
} }
} }

View File

@ -27,7 +27,15 @@ public class GeoCompositeAreaShape extends GeoBaseCompositeAreaShape<GeoAreaShap
/** /**
* Constructor. * Constructor.
*/ */
public GeoCompositeAreaShape() { public GeoCompositeAreaShape(PlanetModel planetModel) {
super(planetModel);
}
@Override
public boolean equals(Object o) {
if (!(o instanceof GeoCompositeAreaShape))
return false;
return super.equals(o);
} }
@Override @Override

View File

@ -26,7 +26,15 @@ public class GeoCompositeMembershipShape extends GeoBaseCompositeMembershipShape
/** /**
* Constructor. * Constructor.
*/ */
public GeoCompositeMembershipShape() { public GeoCompositeMembershipShape(PlanetModel planetModel) {
super(planetModel);
}
@Override
public boolean equals(Object o) {
if (!(o instanceof GeoCompositeMembershipShape))
return false;
return super.equals(o);
} }
@Override @Override

View File

@ -25,7 +25,15 @@ public class GeoCompositePolygon extends GeoBaseCompositeAreaShape<GeoPolygon> i
/** /**
* Constructor. * Constructor.
*/ */
public GeoCompositePolygon() { public GeoCompositePolygon(PlanetModel planetModel) {
super(planetModel);
}
@Override
public boolean equals(Object o) {
if (!(o instanceof GeoCompositePolygon))
return false;
return super.equals(o);
} }
@Override @Override

View File

@ -39,6 +39,11 @@ class GeoDegeneratePoint extends GeoPoint implements GeoBBox, GeoCircle {
this.edgePoints = new GeoPoint[]{this}; this.edgePoints = new GeoPoint[]{this};
} }
@Override
public PlanetModel getPlanetModel() {
return planetModel;
}
@Override @Override
public GeoBBox expand(final double angle) { public GeoBBox expand(final double angle) {
final double newTopLat = latitude + angle; final double newTopLat = latitude + angle;

View File

@ -336,19 +336,19 @@ public class GeoPolygonFactory {
final SidedPlane initialPlane = new SidedPlane(testPoint, filteredPointList.get(0), filteredPointList.get(1)); final SidedPlane initialPlane = new SidedPlane(testPoint, filteredPointList.get(0), filteredPointList.get(1));
// We don't know if this is the correct siding choice. We will only know as we build the complex polygon. // We don't know if this is the correct siding choice. We will only know as we build the complex polygon.
// So we need to be prepared to try both possibilities. // So we need to be prepared to try both possibilities.
GeoCompositePolygon rval = new GeoCompositePolygon(); GeoCompositePolygon rval = new GeoCompositePolygon(planetModel);
MutableBoolean seenConcave = new MutableBoolean(); MutableBoolean seenConcave = new MutableBoolean();
if (buildPolygonShape(rval, seenConcave, planetModel, filteredPointList, new BitSet(), 0, 1, initialPlane, holes, testPoint) == false) { if (buildPolygonShape(rval, seenConcave, planetModel, filteredPointList, new BitSet(), 0, 1, initialPlane, holes, testPoint) == false) {
// The testPoint was within the shape. Was that intended? // The testPoint was within the shape. Was that intended?
if (testPointInside) { if (testPointInside) {
// Yes: build it for real // Yes: build it for real
rval = new GeoCompositePolygon(); rval = new GeoCompositePolygon(planetModel);
seenConcave = new MutableBoolean(); seenConcave = new MutableBoolean();
buildPolygonShape(rval, seenConcave, planetModel, filteredPointList, new BitSet(), 0, 1, initialPlane, holes, null); buildPolygonShape(rval, seenConcave, planetModel, filteredPointList, new BitSet(), 0, 1, initialPlane, holes, null);
return rval; return rval;
} }
// No: do the complement and return that. // No: do the complement and return that.
rval = new GeoCompositePolygon(); rval = new GeoCompositePolygon(planetModel);
seenConcave = new MutableBoolean(); seenConcave = new MutableBoolean();
buildPolygonShape(rval, seenConcave, planetModel, filteredPointList, new BitSet(), 0, 1, new SidedPlane(initialPlane), holes, null); buildPolygonShape(rval, seenConcave, planetModel, filteredPointList, new BitSet(), 0, 1, new SidedPlane(initialPlane), holes, null);
return rval; return rval;
@ -359,7 +359,7 @@ public class GeoPolygonFactory {
return rval; return rval;
} }
// No: return the complement // No: return the complement
rval = new GeoCompositePolygon(); rval = new GeoCompositePolygon(planetModel);
seenConcave = new MutableBoolean(); seenConcave = new MutableBoolean();
buildPolygonShape(rval, seenConcave, planetModel, filteredPointList, new BitSet(), 0, 1, new SidedPlane(initialPlane), holes, null); buildPolygonShape(rval, seenConcave, planetModel, filteredPointList, new BitSet(), 0, 1, new SidedPlane(initialPlane), holes, null);
return rval; return rval;

View File

@ -23,7 +23,7 @@ package org.apache.lucene.spatial3d.geom;
* *
* @lucene.experimental * @lucene.experimental
*/ */
public interface GeoShape extends Membership { public interface GeoShape extends Membership, PlanetObject {
/** /**
* Return a sample point that is on the outside edge/boundary of the shape. * Return a sample point that is on the outside edge/boundary of the shape.

View File

@ -0,0 +1,29 @@
/*
* 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.
*/
package org.apache.lucene.spatial3d.geom;
/**
* Relates all Geo3d shape with a specific {@link PlanetModel}.
*
* @lucene.experimental
*/
public interface PlanetObject {
/** Returns the {@link PlanetModel} provided when this shape was created. */
PlanetModel getPlanetModel();
}

View File

@ -21,6 +21,6 @@ package org.apache.lucene.spatial3d.geom;
* *
* @lucene.internal * @lucene.internal
*/ */
public interface XYZSolid extends GeoArea { public interface XYZSolid extends GeoArea, PlanetObject {
} }

View File

@ -833,7 +833,7 @@ public class CompositeGeoPolygonRelationshipsTest {
points2.add(point8); points2.add(point8);
GeoPolygon p1 = GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points1); GeoPolygon p1 = GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points1);
GeoPolygon p2 = GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points2); GeoPolygon p2 = GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points2);
GeoCompositeMembershipShape compositeMembershipShape = new GeoCompositeMembershipShape(); GeoCompositeMembershipShape compositeMembershipShape = new GeoCompositeMembershipShape(PlanetModel.SPHERE);
compositeMembershipShape.addShape(p1); compositeMembershipShape.addShape(p1);
compositeMembershipShape.addShape(p2); compositeMembershipShape.addShape(p2);
return compositeMembershipShape; return compositeMembershipShape;

View File

@ -134,12 +134,12 @@ class Geo3DUtil {
final GeoPolygon component = fromPolygon(polygons[0]); final GeoPolygon component = fromPolygon(polygons[0]);
if (component == null) { if (component == null) {
// Polygon is degenerate // Polygon is degenerate
shape = new GeoCompositePolygon(); shape = new GeoCompositePolygon(PlanetModel.WGS84);
} else { } else {
shape = component; shape = component;
} }
} else { } else {
final GeoCompositePolygon poly = new GeoCompositePolygon(); final GeoCompositePolygon poly = new GeoCompositePolygon(PlanetModel.WGS84);
for (final Polygon p : polygons) { for (final Polygon p : polygons) {
final GeoPolygon component = fromPolygon(p); final GeoPolygon component = fromPolygon(p);
if (component != null) { if (component != null) {

View File

@ -441,7 +441,7 @@ public class GeoPolygonTest {
PlanetModel pm = new PlanetModel(0.7563871189161702, 1.2436128810838298); PlanetModel pm = new PlanetModel(0.7563871189161702, 1.2436128810838298);
// Build the polygon // Build the polygon
GeoCompositeMembershipShape c = new GeoCompositeMembershipShape(); GeoCompositeMembershipShape c = new GeoCompositeMembershipShape(pm);
List<GeoPoint> points1 = new ArrayList<>(); List<GeoPoint> points1 = new ArrayList<>();
points1.add(new GeoPoint(pm, 0.014071770744627236, 0.011030818292803128)); points1.add(new GeoPoint(pm, 0.014071770744627236, 0.011030818292803128));
points1.add(new GeoPoint(pm, 0.006772117088906782, -0.0012531892445234592)); points1.add(new GeoPoint(pm, 0.006772117088906782, -0.0012531892445234592));
@ -500,7 +500,7 @@ shape:
*/ */
PlanetModel pm = new PlanetModel(0.8568069516722363, 1.1431930483277637); PlanetModel pm = new PlanetModel(0.8568069516722363, 1.1431930483277637);
// Build the polygon // Build the polygon
GeoCompositeMembershipShape c = new GeoCompositeMembershipShape(); GeoCompositeMembershipShape c = new GeoCompositeMembershipShape(pm);
List<GeoPoint> points1 = new ArrayList<>(); List<GeoPoint> points1 = new ArrayList<>();
points1.add(new GeoPoint(pm, 1.1577814487635816, 1.6283601832010004)); points1.add(new GeoPoint(pm, 1.1577814487635816, 1.6283601832010004));
points1.add(new GeoPoint(pm, 0.6664570999069251, 2.0855825542851574)); points1.add(new GeoPoint(pm, 0.6664570999069251, 2.0855825542851574));
@ -626,7 +626,7 @@ shape:
points.add(p1); points.add(p1);
final BitSet internal = new BitSet(); final BitSet internal = new BitSet();
final GeoCompositePolygon rval = new GeoCompositePolygon(); final GeoCompositePolygon rval = new GeoCompositePolygon(PlanetModel.WGS84);
final GeoPolygonFactory.MutableBoolean mutableBoolean = new GeoPolygonFactory.MutableBoolean(); final GeoPolygonFactory.MutableBoolean mutableBoolean = new GeoPolygonFactory.MutableBoolean();
boolean result = GeoPolygonFactory.buildPolygonShape(rval, mutableBoolean, PlanetModel.WGS84, points, internal, 0, 1, boolean result = GeoPolygonFactory.buildPolygonShape(rval, mutableBoolean, PlanetModel.WGS84, points, internal, 0, 1,

View File

@ -380,7 +380,7 @@ public class RandomGeoShapeGenerator extends LuceneTestCase {
while (iterations < MAX_SHAPE_ITERATIONS) { while (iterations < MAX_SHAPE_ITERATIONS) {
iterations++; iterations++;
int numberShapes = random().nextInt(3) + 2; int numberShapes = random().nextInt(3) + 2;
GeoCompositeAreaShape collection = new GeoCompositeAreaShape(); GeoCompositeAreaShape collection = new GeoCompositeAreaShape(planetModel);
for(int i=0; i<numberShapes;i++){ for(int i=0; i<numberShapes;i++){
GeoPolygon member = convexPolygon(planetModel, constraints); GeoPolygon member = convexPolygon(planetModel, constraints);
if (member != null){ if (member != null){

View File

@ -829,7 +829,7 @@ public class SimpleGeoPolygonRelationshipsTest {
points2.add(point7); points2.add(point7);
points2.add(point8); points2.add(point8);
GeoPolygon pol2 = GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points2); GeoPolygon pol2 = GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points2);
GeoCompositeMembershipShape composite = new GeoCompositeMembershipShape(); GeoCompositeMembershipShape composite = new GeoCompositeMembershipShape(PlanetModel.SPHERE);
composite.addShape(pol1); composite.addShape(pol1);
composite.addShape(pol2); composite.addShape(pol2);
return composite; return composite;