mirror of https://github.com/apache/lucene.git
LUCENE-7606: Add spatial relationships between all currently-defined Geo shapes
This commit is contained in:
parent
f80f1c0962
commit
39d6be4ecc
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Shape that implements GeoArea. This type of shapes are able to resolve the
|
||||
* spatial relationship of other shapes with itself.
|
||||
*
|
||||
* @lucene.experimental
|
||||
*/
|
||||
|
||||
public interface GeoAreaShape extends GeoMembershipShape, GeoArea{
|
||||
|
||||
/**
|
||||
* Assess whether a shape intersects with any of the edges this shape.
|
||||
* Note well that this method return false if the shape contains, is within
|
||||
* or is disjoint with the given shape.
|
||||
*
|
||||
* @param geoShape is the shape to assess for intersection with this shape's edges.
|
||||
*
|
||||
* @return true if there's such an intersection, false if not.
|
||||
*/
|
||||
boolean intersects(GeoShape geoShape);
|
||||
}
|
|
@ -23,7 +23,7 @@ package org.apache.lucene.spatial3d.geom;
|
|||
*
|
||||
* @lucene.experimental
|
||||
*/
|
||||
public interface GeoBBox extends GeoMembershipShape, GeoSizeable, GeoArea {
|
||||
public interface GeoBBox extends GeoAreaShape, GeoSizeable {
|
||||
|
||||
/**
|
||||
* Expand box by specified angle.
|
||||
|
|
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Base extended areaShape object.
|
||||
*
|
||||
* @lucene.internal
|
||||
*/
|
||||
abstract class GeoBaseAreaShape extends GeoBaseMembershipShape implements GeoAreaShape {
|
||||
|
||||
/** Constructor.
|
||||
*@param planetModel is the planet model to use.
|
||||
*/
|
||||
public GeoBaseAreaShape(final PlanetModel planetModel) {
|
||||
super(planetModel);
|
||||
}
|
||||
|
||||
/** All edgepoints inside shape */
|
||||
protected final static int ALL_INSIDE = 0;
|
||||
/** Some edgepoints inside shape */
|
||||
protected final static int SOME_INSIDE = 1;
|
||||
/** No edgepoints inside shape */
|
||||
protected final static int NONE_INSIDE = 2;
|
||||
|
||||
/** Determine the relationship between the GeoAreShape and the
|
||||
* shape's edgepoints.
|
||||
*@param geoShape is the shape.
|
||||
*@return the relationship.
|
||||
*/
|
||||
protected int isShapeInsideGeoAreaShape(final GeoShape geoShape) {
|
||||
boolean foundOutside = false;
|
||||
boolean foundInside = false;
|
||||
for (GeoPoint p : geoShape.getEdgePoints()) {
|
||||
if (isWithin(p)) {
|
||||
foundInside = true;
|
||||
} else {
|
||||
foundOutside = true;
|
||||
}
|
||||
if (foundInside && foundOutside) {
|
||||
return SOME_INSIDE;
|
||||
}
|
||||
}
|
||||
if (!foundInside && !foundOutside)
|
||||
return NONE_INSIDE;
|
||||
if (foundInside && !foundOutside)
|
||||
return ALL_INSIDE;
|
||||
if (foundOutside && !foundInside)
|
||||
return NONE_INSIDE;
|
||||
return SOME_INSIDE;
|
||||
}
|
||||
|
||||
/** Determine the relationship between the GeoAreaShape's edgepoints and the
|
||||
* provided shape.
|
||||
*@param geoshape is the shape.
|
||||
*@return the relationship.
|
||||
*/
|
||||
protected int isGeoAreaShapeInsideShape(final GeoShape geoshape) {
|
||||
boolean foundOutside = false;
|
||||
boolean foundInside = false;
|
||||
for (GeoPoint p : getEdgePoints()) {
|
||||
if (geoshape.isWithin(p)) {
|
||||
foundInside = true;
|
||||
} else {
|
||||
foundOutside = true;
|
||||
}
|
||||
if (foundInside && foundOutside) {
|
||||
return SOME_INSIDE;
|
||||
}
|
||||
}
|
||||
if (!foundInside && !foundOutside)
|
||||
return NONE_INSIDE;
|
||||
if (foundInside && !foundOutside)
|
||||
return ALL_INSIDE;
|
||||
if (foundOutside && !foundInside)
|
||||
return NONE_INSIDE;
|
||||
return SOME_INSIDE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRelationship(GeoShape geoShape) {
|
||||
final int insideGeoAreaShape = isShapeInsideGeoAreaShape(geoShape);
|
||||
if (insideGeoAreaShape == SOME_INSIDE) {
|
||||
return GeoArea.OVERLAPS;
|
||||
}
|
||||
|
||||
final int insideShape = isGeoAreaShapeInsideShape(geoShape);
|
||||
if (insideShape == SOME_INSIDE) {
|
||||
return GeoArea.OVERLAPS;
|
||||
}
|
||||
|
||||
if (insideGeoAreaShape == ALL_INSIDE && insideShape==ALL_INSIDE) {
|
||||
return GeoArea.OVERLAPS;
|
||||
}
|
||||
|
||||
if (intersects(geoShape)){
|
||||
return GeoArea.OVERLAPS;
|
||||
}
|
||||
|
||||
if (insideGeoAreaShape == ALL_INSIDE) {
|
||||
return GeoArea.WITHIN;
|
||||
}
|
||||
|
||||
if (insideShape==ALL_INSIDE) {
|
||||
return GeoArea.CONTAINS;
|
||||
}
|
||||
|
||||
return GeoArea.DISJOINT;
|
||||
}
|
||||
}
|
|
@ -22,7 +22,7 @@ package org.apache.lucene.spatial3d.geom;
|
|||
*
|
||||
* @lucene.internal
|
||||
*/
|
||||
abstract class GeoBaseBBox extends GeoBaseMembershipShape implements GeoBBox {
|
||||
abstract class GeoBaseBBox extends GeoBaseAreaShape implements GeoBBox {
|
||||
|
||||
/** Construct, given planet model.
|
||||
*@param planetModel is the planet model.
|
||||
|
@ -31,42 +31,6 @@ abstract class GeoBaseBBox extends GeoBaseMembershipShape implements GeoBBox {
|
|||
super(planetModel);
|
||||
}
|
||||
|
||||
// Signals for relationship of edge points to shape
|
||||
|
||||
/** All edgepoints inside shape */
|
||||
protected final static int ALL_INSIDE = 0;
|
||||
/** Some edgepoints inside shape */
|
||||
protected final static int SOME_INSIDE = 1;
|
||||
/** No edgepoints inside shape */
|
||||
protected final static int NONE_INSIDE = 2;
|
||||
|
||||
/** Determine the relationship between this BBox and the provided
|
||||
* shape's edgepoints.
|
||||
*@param path is the shape.
|
||||
*@return the relationship.
|
||||
*/
|
||||
protected int isShapeInsideBBox(final GeoShape path) {
|
||||
final GeoPoint[] pathPoints = path.getEdgePoints();
|
||||
boolean foundOutside = false;
|
||||
boolean foundInside = false;
|
||||
for (GeoPoint p : pathPoints) {
|
||||
if (isWithin(p)) {
|
||||
foundInside = true;
|
||||
} else {
|
||||
foundOutside = true;
|
||||
}
|
||||
if (foundInside && foundOutside) {
|
||||
return SOME_INSIDE;
|
||||
}
|
||||
}
|
||||
if (!foundInside && !foundOutside)
|
||||
return NONE_INSIDE;
|
||||
if (foundInside && !foundOutside)
|
||||
return ALL_INSIDE;
|
||||
if (foundOutside && !foundInside)
|
||||
return NONE_INSIDE;
|
||||
return SOME_INSIDE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ package org.apache.lucene.spatial3d.geom;
|
|||
*
|
||||
* @lucene.experimental
|
||||
*/
|
||||
public abstract class GeoBaseDistanceShape extends GeoBaseMembershipShape implements GeoDistanceShape {
|
||||
public abstract class GeoBaseDistanceShape extends GeoBaseAreaShape implements GeoDistanceShape {
|
||||
|
||||
/** Constructor.
|
||||
*@param planetModel is the planet model to use.
|
||||
|
|
|
@ -21,7 +21,7 @@ package org.apache.lucene.spatial3d.geom;
|
|||
*
|
||||
* @lucene.internal
|
||||
*/
|
||||
abstract class GeoBasePolygon extends GeoBaseMembershipShape implements GeoPolygon {
|
||||
abstract class GeoBasePolygon extends GeoBaseAreaShape implements GeoPolygon {
|
||||
|
||||
/** Constructor.
|
||||
*@param planetModel is the planet model to use.
|
||||
|
|
|
@ -369,6 +369,32 @@ class GeoComplexPolygon extends GeoBasePolygon {
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean intersects(GeoShape geoShape) {
|
||||
// Create the intersector
|
||||
final EdgeIterator intersector = new IntersectorShapeIterator(geoShape);
|
||||
// First, compute the bounds for the the plane
|
||||
final XYZBounds xyzBounds = new XYZBounds();
|
||||
geoShape.getBounds(xyzBounds);
|
||||
|
||||
// Figure out which tree likely works best
|
||||
final double xDelta = xyzBounds.getMaximumX() - xyzBounds.getMinimumX();
|
||||
final double yDelta = xyzBounds.getMaximumY() - xyzBounds.getMinimumY();
|
||||
final double zDelta = xyzBounds.getMaximumZ() - xyzBounds.getMinimumZ();
|
||||
// Select the smallest range
|
||||
if (xDelta <= yDelta && xDelta <= zDelta) {
|
||||
// Drill down in x
|
||||
return !xTree.traverse(intersector, xyzBounds.getMinimumX(), xyzBounds.getMaximumX());
|
||||
} else if (yDelta <= xDelta && yDelta <= zDelta) {
|
||||
// Drill down in y
|
||||
return !yTree.traverse(intersector, xyzBounds.getMinimumY(), xyzBounds.getMaximumY());
|
||||
} else if (zDelta <= xDelta && zDelta <= yDelta) {
|
||||
// Drill down in z
|
||||
return !zTree.traverse(intersector, xyzBounds.getMinimumZ(), xyzBounds.getMaximumZ());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void getBounds(Bounds bounds) {
|
||||
|
@ -691,7 +717,24 @@ class GeoComplexPolygon extends GeoBasePolygon {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** Assess whether edge intersects the provided shape.
|
||||
*/
|
||||
private class IntersectorShapeIterator implements EdgeIterator {
|
||||
|
||||
private final GeoShape shape;
|
||||
|
||||
public IntersectorShapeIterator(final GeoShape shape) {
|
||||
this.shape = shape;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(final Edge edge) {
|
||||
return !shape.intersects(edge.plane, edge.notablePoints, edge.startPlane, edge.endPlane);
|
||||
}
|
||||
}
|
||||
|
||||
/** Count the number of verifiable edge crossings.
|
||||
*/
|
||||
private class LinearCrossingEdgeIterator implements EdgeIterator {
|
||||
|
|
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* GeoCompositeAreShape is a set of GeoAreaShape's, treated as a unit.
|
||||
*
|
||||
* @lucene.experimental
|
||||
*/
|
||||
public class GeoCompositeAreaShape extends GeoCompositeMembershipShape implements GeoAreaShape {
|
||||
|
||||
/**
|
||||
* Add a shape to the composite. It throw an IllegalArgumentException
|
||||
* if the shape is not a GeoAreaShape
|
||||
*@param shape is the shape to add.
|
||||
*/
|
||||
@Override
|
||||
public void addShape(final GeoMembershipShape shape) {
|
||||
if (!(shape instanceof GeoAreaShape)){
|
||||
throw new IllegalArgumentException("GeoCompositeAreaShape must be composed of GeoAreaShapes");
|
||||
}
|
||||
shapes.add(shape);
|
||||
}
|
||||
|
||||
public boolean intersects(GeoShape geoShape){
|
||||
for(GeoShape inShape : shapes){
|
||||
if (((GeoAreaShape)inShape).intersects(geoShape)){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** All edgepoints inside shape */
|
||||
protected final static int ALL_INSIDE = 0;
|
||||
/** Some edgepoints inside shape */
|
||||
protected final static int SOME_INSIDE = 1;
|
||||
/** No edgepoints inside shape */
|
||||
protected final static int NONE_INSIDE = 2;
|
||||
|
||||
/** Determine the relationship between the GeoAreShape and the
|
||||
* shape's edgepoints.
|
||||
*@param geoShape is the shape.
|
||||
*@return the relationship.
|
||||
*/
|
||||
protected int isShapeInsideGeoAreaShape(final GeoShape geoShape) {
|
||||
boolean foundOutside = false;
|
||||
boolean foundInside = false;
|
||||
for (GeoPoint p : geoShape.getEdgePoints()) {
|
||||
if (isWithin(p)) {
|
||||
foundInside = true;
|
||||
} else {
|
||||
foundOutside = true;
|
||||
}
|
||||
if (foundInside && foundOutside) {
|
||||
return SOME_INSIDE;
|
||||
}
|
||||
}
|
||||
if (!foundInside && !foundOutside)
|
||||
return NONE_INSIDE;
|
||||
if (foundInside && !foundOutside)
|
||||
return ALL_INSIDE;
|
||||
if (foundOutside && !foundInside)
|
||||
return NONE_INSIDE;
|
||||
return SOME_INSIDE;
|
||||
}
|
||||
|
||||
/** Determine the relationship between the GeoAreShape's edgepoints and the
|
||||
* provided shape.
|
||||
*@param geoshape is the shape.
|
||||
*@return the relationship.
|
||||
*/
|
||||
protected int isGeoAreaShapeInsideShape(final GeoShape geoshape) {
|
||||
boolean foundOutside = false;
|
||||
boolean foundInside = false;
|
||||
for (GeoPoint p : getEdgePoints()) {
|
||||
if (geoshape.isWithin(p)) {
|
||||
foundInside = true;
|
||||
} else {
|
||||
foundOutside = true;
|
||||
}
|
||||
if (foundInside && foundOutside) {
|
||||
return SOME_INSIDE;
|
||||
}
|
||||
}
|
||||
if (!foundInside && !foundOutside)
|
||||
return NONE_INSIDE;
|
||||
if (foundInside && !foundOutside)
|
||||
return ALL_INSIDE;
|
||||
if (foundOutside && !foundInside)
|
||||
return NONE_INSIDE;
|
||||
return SOME_INSIDE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRelationship(GeoShape geoShape) {
|
||||
final int insideGeoAreaShape = isShapeInsideGeoAreaShape(geoShape);
|
||||
if (insideGeoAreaShape == SOME_INSIDE) {
|
||||
return GeoArea.OVERLAPS;
|
||||
}
|
||||
|
||||
final int insideShape = isGeoAreaShapeInsideShape(geoShape);
|
||||
if (insideShape == SOME_INSIDE) {
|
||||
return GeoArea.OVERLAPS;
|
||||
}
|
||||
|
||||
if (insideGeoAreaShape == ALL_INSIDE && insideShape==ALL_INSIDE) {
|
||||
return GeoArea.OVERLAPS;
|
||||
}
|
||||
|
||||
if (intersects(geoShape)){
|
||||
return GeoArea.OVERLAPS;
|
||||
}
|
||||
|
||||
if (insideGeoAreaShape == ALL_INSIDE) {
|
||||
return GeoArea.WITHIN;
|
||||
}
|
||||
|
||||
if (insideShape==ALL_INSIDE) {
|
||||
return GeoArea.CONTAINS;
|
||||
}
|
||||
|
||||
return GeoArea.DISJOINT;
|
||||
}
|
||||
|
||||
}
|
|
@ -17,6 +17,7 @@
|
|||
package org.apache.lucene.spatial3d.geom;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
|
@ -57,7 +58,11 @@ public class GeoCompositeMembershipShape implements GeoMembershipShape {
|
|||
|
||||
@Override
|
||||
public GeoPoint[] getEdgePoints() {
|
||||
return shapes.get(0).getEdgePoints();
|
||||
List<GeoPoint> edgePoints = new ArrayList<>();
|
||||
for(int i=0;i<shapes.size();i++){
|
||||
edgePoints.addAll(Arrays.asList(shapes.get(i).getEdgePoints()));
|
||||
}
|
||||
return edgePoints.toArray(new GeoPoint[edgePoints.size()]);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -21,7 +21,7 @@ package org.apache.lucene.spatial3d.geom;
|
|||
*
|
||||
* @lucene.experimental
|
||||
*/
|
||||
public class GeoCompositePolygon extends GeoCompositeMembershipShape implements GeoPolygon {
|
||||
public class GeoCompositePolygon extends GeoCompositeAreaShape implements GeoPolygon {
|
||||
/** Constructor.
|
||||
*/
|
||||
public GeoCompositePolygon() {
|
||||
|
|
|
@ -366,6 +366,27 @@ class GeoConcavePolygon extends GeoBasePolygon {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean intersects(GeoShape geoShape) {
|
||||
for (int edgeIndex = 0; edgeIndex < edges.length; edgeIndex++) {
|
||||
final SidedPlane edge = edges[edgeIndex];
|
||||
final GeoPoint[] points = this.notableEdgePoints[edgeIndex];
|
||||
if (!isInternalEdges.get(edgeIndex)) {
|
||||
if (geoShape.intersects(edge, points, eitherBounds.get(edge))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (holes != null) {
|
||||
for (final GeoPolygon hole : holes) {
|
||||
if (hole.intersects(geoShape)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** A membership implementation representing polygon edges that must apply.
|
||||
*/
|
||||
protected static class EitherBound implements Membership {
|
||||
|
|
|
@ -356,6 +356,27 @@ class GeoConvexPolygon extends GeoBasePolygon {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean intersects(GeoShape shape) {
|
||||
for (int edgeIndex = 0; edgeIndex < edges.length; edgeIndex++) {
|
||||
final SidedPlane edge = edges[edgeIndex];
|
||||
final GeoPoint[] points = this.notableEdgePoints[edgeIndex];
|
||||
if (!isInternalEdges.get(edgeIndex)) {
|
||||
if (shape.intersects(edge, points, eitherBounds.get(edge))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (holes != null) {
|
||||
for (final GeoPolygon hole : holes) {
|
||||
if (hole.intersects(shape)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** A membership implementation representing polygon edges that must apply.
|
||||
*/
|
||||
protected static class EitherBound implements Membership {
|
||||
|
|
|
@ -154,6 +154,11 @@ class GeoDegenerateHorizontalLine extends GeoBaseBBox {
|
|||
return p.intersects(planetModel, plane, notablePoints, planePoints, bounds, leftPlane, rightPlane);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean intersects(final GeoShape geoShape) {
|
||||
return geoShape.intersects(plane, planePoints, leftPlane, rightPlane);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getBounds(Bounds bounds) {
|
||||
super.getBounds(bounds);
|
||||
|
@ -164,7 +169,7 @@ class GeoDegenerateHorizontalLine extends GeoBaseBBox {
|
|||
@Override
|
||||
public int getRelationship(final GeoShape path) {
|
||||
//System.err.println("getting relationship between "+this+" and "+path);
|
||||
if (path.intersects(plane, planePoints, leftPlane, rightPlane)) {
|
||||
if (intersects(path)) {
|
||||
//System.err.println(" overlaps");
|
||||
return OVERLAPS;
|
||||
}
|
||||
|
|
|
@ -85,6 +85,11 @@ class GeoDegenerateLatitudeZone extends GeoBaseBBox {
|
|||
return p.intersects(planetModel, plane, notablePoints, planePoints, bounds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean intersects(final GeoShape geoShape) {
|
||||
return geoShape.intersects(plane, planePoints);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getBounds(Bounds bounds) {
|
||||
super.getBounds(bounds);
|
||||
|
@ -98,7 +103,7 @@ class GeoDegenerateLatitudeZone extends GeoBaseBBox {
|
|||
// work with no area endpoints. So we rely entirely on intersections.
|
||||
//System.out.println("Got here! latitude="+latitude+" path="+path);
|
||||
|
||||
if (path.intersects(plane, planePoints)) {
|
||||
if (intersects(path)) {
|
||||
return OVERLAPS;
|
||||
}
|
||||
|
||||
|
|
|
@ -96,6 +96,11 @@ class GeoDegenerateLongitudeSlice extends GeoBaseBBox {
|
|||
return p.intersects(planetModel, plane, notablePoints, planePoints, bounds, boundingPlane);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean intersects(final GeoShape geoShape) {
|
||||
return geoShape.intersects(plane, planePoints, boundingPlane);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getBounds(Bounds bounds) {
|
||||
super.getBounds(bounds);
|
||||
|
@ -107,7 +112,7 @@ class GeoDegenerateLongitudeSlice extends GeoBaseBBox {
|
|||
@Override
|
||||
public int getRelationship(final GeoShape path) {
|
||||
// Look for intersections.
|
||||
if (path.intersects(plane, planePoints, boundingPlane))
|
||||
if (intersects(path))
|
||||
return OVERLAPS;
|
||||
|
||||
if (path.isWithin(interiorPoint))
|
||||
|
|
|
@ -66,6 +66,11 @@ class GeoDegeneratePoint extends GeoPoint implements GeoBBox, GeoCircle {
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean intersects(GeoShape geoShape) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getBounds(Bounds bounds) {
|
||||
bounds.addPoint(this);
|
||||
|
|
|
@ -144,6 +144,11 @@ public class GeoDegenerateVerticalLine extends GeoBaseBBox {
|
|||
return p.intersects(planetModel, plane, notablePoints, planePoints, bounds, boundingPlane, topPlane, bottomPlane);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean intersects(final GeoShape geoShape) {
|
||||
return geoShape.intersects(plane, planePoints, boundingPlane, topPlane, bottomPlane);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getBounds(Bounds bounds) {
|
||||
super.getBounds(bounds);
|
||||
|
@ -154,7 +159,7 @@ public class GeoDegenerateVerticalLine extends GeoBaseBBox {
|
|||
@Override
|
||||
public int getRelationship(final GeoShape path) {
|
||||
//System.err.println(this+" relationship to "+path);
|
||||
if (path.intersects(plane, planePoints, boundingPlane, topPlane, bottomPlane)) {
|
||||
if (intersects(path)) {
|
||||
//System.err.println(" overlaps");
|
||||
return OVERLAPS;
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ package org.apache.lucene.spatial3d.geom;
|
|||
*
|
||||
* @lucene.experimental
|
||||
*/
|
||||
public interface GeoDistanceShape extends GeoMembershipShape, GeoDistance {
|
||||
public interface GeoDistanceShape extends GeoAreaShape, GeoDistance {
|
||||
|
||||
/**
|
||||
* Compute a bound based on a provided distance measure.
|
||||
|
|
|
@ -119,6 +119,12 @@ class GeoLatitudeZone extends GeoBaseBBox {
|
|||
p.intersects(planetModel, bottomPlane, notablePoints, planePoints, bounds, topPlane);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean intersects(final GeoShape geoShape) {
|
||||
return geoShape.intersects(topPlane, planePoints, bottomPlane) ||
|
||||
geoShape.intersects(bottomPlane, planePoints, topPlane);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getBounds(Bounds bounds) {
|
||||
super.getBounds(bounds);
|
||||
|
@ -127,46 +133,6 @@ class GeoLatitudeZone extends GeoBaseBBox {
|
|||
.addHorizontalPlane(planetModel, bottomLat, bottomPlane);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRelationship(final GeoShape path) {
|
||||
final int insideRectangle = isShapeInsideBBox(path);
|
||||
if (insideRectangle == SOME_INSIDE)
|
||||
return OVERLAPS;
|
||||
|
||||
final boolean topBoundaryInsideShape = path.isWithin(topBoundaryPoint);
|
||||
final boolean bottomBoundaryInsideShape = path.isWithin(bottomBoundaryPoint);
|
||||
|
||||
if (topBoundaryInsideShape && !bottomBoundaryInsideShape ||
|
||||
!topBoundaryInsideShape && bottomBoundaryInsideShape)
|
||||
return OVERLAPS;
|
||||
|
||||
final boolean insideShape = topBoundaryInsideShape && bottomBoundaryInsideShape;
|
||||
|
||||
if (insideRectangle == ALL_INSIDE && insideShape)
|
||||
return OVERLAPS;
|
||||
|
||||
// Second, the shortcut of seeing whether endpoints are in/out is not going to
|
||||
// work with no area endpoints. So we rely entirely on intersections.
|
||||
|
||||
if (path.intersects(topPlane, planePoints, bottomPlane) ||
|
||||
path.intersects(bottomPlane, planePoints, topPlane))
|
||||
return OVERLAPS;
|
||||
|
||||
// There is another case for latitude zones only. This is when the boundaries of the shape all fit
|
||||
// within the zone, but the shape includes areas outside the zone crossing a pole.
|
||||
// In this case, the above "overlaps" check is insufficient. We also need to check a point on either boundary
|
||||
// whether it is within the shape. If both such points are within, then CONTAINS is the right answer. If
|
||||
// one such point is within, then OVERLAPS is the right answer.
|
||||
|
||||
if (insideShape)
|
||||
return CONTAINS;
|
||||
|
||||
if (insideRectangle == ALL_INSIDE)
|
||||
return WITHIN;
|
||||
|
||||
return DISJOINT;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
|
||||
final double topDistance = distanceStyle.computeDistance(planetModel, topPlane, x,y,z, bottomPlane);
|
||||
|
|
|
@ -127,6 +127,12 @@ class GeoLongitudeSlice extends GeoBaseBBox {
|
|||
p.intersects(planetModel, rightPlane, notablePoints, planePoints, bounds, leftPlane);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean intersects(final GeoShape geoShape) {
|
||||
return geoShape.intersects(leftPlane, planePoints, rightPlane) ||
|
||||
geoShape.intersects(rightPlane, planePoints, leftPlane);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getBounds(Bounds bounds) {
|
||||
super.getBounds(bounds);
|
||||
|
@ -138,33 +144,6 @@ class GeoLongitudeSlice extends GeoBaseBBox {
|
|||
.addPoint(planetModel.SOUTH_POLE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRelationship(final GeoShape path) {
|
||||
final int insideRectangle = isShapeInsideBBox(path);
|
||||
if (insideRectangle == SOME_INSIDE)
|
||||
return OVERLAPS;
|
||||
|
||||
final boolean insideShape = path.isWithin(planetModel.NORTH_POLE);
|
||||
|
||||
if (insideRectangle == ALL_INSIDE && insideShape)
|
||||
return OVERLAPS;
|
||||
|
||||
if (path.intersects(leftPlane, planePoints, rightPlane) ||
|
||||
path.intersects(rightPlane, planePoints, leftPlane)) {
|
||||
return OVERLAPS;
|
||||
}
|
||||
|
||||
if (insideRectangle == ALL_INSIDE) {
|
||||
return WITHIN;
|
||||
}
|
||||
|
||||
if (insideShape) {
|
||||
return CONTAINS;
|
||||
}
|
||||
|
||||
return DISJOINT;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
|
||||
final double leftDistance = distanceStyle.computeDistance(planetModel, leftPlane, x,y,z, rightPlane);
|
||||
|
|
|
@ -98,6 +98,12 @@ class GeoNorthLatitudeZone extends GeoBaseBBox {
|
|||
p.intersects(planetModel, bottomPlane, notablePoints, planePoints, bounds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean intersects(final GeoShape geoShape) {
|
||||
return
|
||||
geoShape.intersects(bottomPlane, planePoints);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getBounds(Bounds bounds) {
|
||||
super.getBounds(bounds);
|
||||
|
@ -105,38 +111,6 @@ class GeoNorthLatitudeZone extends GeoBaseBBox {
|
|||
.addHorizontalPlane(planetModel, bottomLat, bottomPlane);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRelationship(final GeoShape path) {
|
||||
final int insideRectangle = isShapeInsideBBox(path);
|
||||
if (insideRectangle == SOME_INSIDE)
|
||||
return OVERLAPS;
|
||||
|
||||
final boolean insideShape = path.isWithin(bottomBoundaryPoint);
|
||||
|
||||
if (insideRectangle == ALL_INSIDE && insideShape)
|
||||
return OVERLAPS;
|
||||
|
||||
// Second, the shortcut of seeing whether endpoints are in/out is not going to
|
||||
// work with no area endpoints. So we rely entirely on intersections.
|
||||
|
||||
if (path.intersects(bottomPlane, planePoints))
|
||||
return OVERLAPS;
|
||||
|
||||
// There is another case for latitude zones only. This is when the boundaries of the shape all fit
|
||||
// within the zone, but the shape includes areas outside the zone crossing a pole.
|
||||
// In this case, the above "overlaps" check is insufficient. We also need to check a point on either boundary
|
||||
// whether it is within the shape. If both such points are within, then CONTAINS is the right answer. If
|
||||
// one such point is within, then OVERLAPS is the right answer.
|
||||
|
||||
if (insideShape)
|
||||
return CONTAINS;
|
||||
|
||||
if (insideRectangle == ALL_INSIDE)
|
||||
return WITHIN;
|
||||
|
||||
return DISJOINT;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
|
||||
return distanceStyle.computeDistance(planetModel, bottomPlane, x,y,z);
|
||||
|
|
|
@ -174,6 +174,14 @@ class GeoNorthRectangle extends GeoBaseBBox {
|
|||
p.intersects(planetModel, rightPlane, notablePoints, rightPlanePoints, bounds, leftPlane, bottomPlane);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean intersects(final GeoShape geoShape) {
|
||||
return
|
||||
geoShape.intersects(bottomPlane, bottomPlanePoints, leftPlane, rightPlane) ||
|
||||
geoShape.intersects(leftPlane, leftPlanePoints, rightPlane, bottomPlane) ||
|
||||
geoShape.intersects(rightPlane, rightPlanePoints, leftPlane, bottomPlane);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getBounds(Bounds bounds) {
|
||||
super.getBounds(bounds);
|
||||
|
@ -185,43 +193,6 @@ class GeoNorthRectangle extends GeoBaseBBox {
|
|||
.addPoint(LLHC).addPoint(LRHC).addPoint(planetModel.NORTH_POLE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRelationship(final GeoShape path) {
|
||||
//System.err.println(this+" getrelationship with "+path);
|
||||
final int insideRectangle = isShapeInsideBBox(path);
|
||||
if (insideRectangle == SOME_INSIDE) {
|
||||
//System.err.println(" some inside");
|
||||
return OVERLAPS;
|
||||
}
|
||||
|
||||
final boolean insideShape = path.isWithin(planetModel.NORTH_POLE);
|
||||
|
||||
if (insideRectangle == ALL_INSIDE && insideShape) {
|
||||
//System.err.println(" inside of each other");
|
||||
return OVERLAPS;
|
||||
}
|
||||
|
||||
if (
|
||||
path.intersects(bottomPlane, bottomPlanePoints, leftPlane, rightPlane) ||
|
||||
path.intersects(leftPlane, leftPlanePoints, bottomPlane, rightPlane) ||
|
||||
path.intersects(rightPlane, rightPlanePoints, leftPlane, bottomPlane)) {
|
||||
//System.err.println(" edges intersect");
|
||||
return OVERLAPS;
|
||||
}
|
||||
|
||||
if (insideRectangle == ALL_INSIDE) {
|
||||
//System.err.println(" shape inside rectangle");
|
||||
return WITHIN;
|
||||
}
|
||||
|
||||
if (insideShape) {
|
||||
//System.err.println(" shape contains rectangle");
|
||||
return CONTAINS;
|
||||
}
|
||||
//System.err.println(" disjoint");
|
||||
return DISJOINT;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
|
||||
final double bottomDistance = distanceStyle.computeDistance(planetModel, bottomPlane, x,y,z, leftPlane, rightPlane);
|
||||
|
|
|
@ -21,6 +21,6 @@ package org.apache.lucene.spatial3d.geom;
|
|||
*
|
||||
* @lucene.experimental
|
||||
*/
|
||||
public interface GeoPolygon extends GeoMembershipShape {
|
||||
public interface GeoPolygon extends GeoAreaShape {
|
||||
|
||||
}
|
||||
|
|
|
@ -196,6 +196,14 @@ class GeoRectangle extends GeoBaseBBox {
|
|||
p.intersects(planetModel, rightPlane, notablePoints, rightPlanePoints, bounds, leftPlane, topPlane, bottomPlane);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean intersects(GeoShape geoShape) {
|
||||
return geoShape.intersects(topPlane, topPlanePoints, bottomPlane, leftPlane, rightPlane) ||
|
||||
geoShape.intersects(bottomPlane, bottomPlanePoints, topPlane, leftPlane, rightPlane) ||
|
||||
geoShape.intersects(leftPlane, leftPlanePoints, rightPlane, topPlane, bottomPlane) ||
|
||||
geoShape.intersects(rightPlane, rightPlanePoints, leftPlane, topPlane, bottomPlane);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getBounds(Bounds bounds) {
|
||||
super.getBounds(bounds);
|
||||
|
@ -207,43 +215,6 @@ class GeoRectangle extends GeoBaseBBox {
|
|||
.addPoint(ULHC).addPoint(URHC).addPoint(LLHC).addPoint(LRHC);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRelationship(final GeoShape path) {
|
||||
//System.err.println(this+" getrelationship with "+path);
|
||||
final int insideRectangle = isShapeInsideBBox(path);
|
||||
if (insideRectangle == SOME_INSIDE) {
|
||||
//System.err.println(" some inside");
|
||||
return OVERLAPS;
|
||||
}
|
||||
|
||||
final boolean insideShape = path.isWithin(ULHC);
|
||||
|
||||
if (insideRectangle == ALL_INSIDE && insideShape) {
|
||||
//System.err.println(" inside of each other");
|
||||
return OVERLAPS;
|
||||
}
|
||||
|
||||
if (path.intersects(topPlane, topPlanePoints, bottomPlane, leftPlane, rightPlane) ||
|
||||
path.intersects(bottomPlane, bottomPlanePoints, topPlane, leftPlane, rightPlane) ||
|
||||
path.intersects(leftPlane, leftPlanePoints, topPlane, bottomPlane, rightPlane) ||
|
||||
path.intersects(rightPlane, rightPlanePoints, leftPlane, topPlane, bottomPlane)) {
|
||||
//System.err.println(" edges intersect");
|
||||
return OVERLAPS;
|
||||
}
|
||||
|
||||
if (insideRectangle == ALL_INSIDE) {
|
||||
//System.err.println(" shape inside rectangle");
|
||||
return WITHIN;
|
||||
}
|
||||
|
||||
if (insideShape) {
|
||||
//System.err.println(" shape contains rectangle");
|
||||
return CONTAINS;
|
||||
}
|
||||
//System.err.println(" disjoint");
|
||||
return DISJOINT;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
|
||||
final double topDistance = distanceStyle.computeDistance(planetModel, topPlane, x,y,z, bottomPlane, leftPlane, rightPlane);
|
||||
|
|
|
@ -101,6 +101,11 @@ class GeoSouthLatitudeZone extends GeoBaseBBox {
|
|||
return p.intersects(planetModel, topPlane, notablePoints, planePoints, bounds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean intersects(final GeoShape geoShape) {
|
||||
return geoShape.intersects(topPlane, planePoints);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getBounds(Bounds bounds) {
|
||||
super.getBounds(bounds);
|
||||
|
@ -108,38 +113,6 @@ class GeoSouthLatitudeZone extends GeoBaseBBox {
|
|||
.addHorizontalPlane(planetModel, topLat, topPlane);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRelationship(final GeoShape path) {
|
||||
final int insideRectangle = isShapeInsideBBox(path);
|
||||
if (insideRectangle == SOME_INSIDE)
|
||||
return OVERLAPS;
|
||||
|
||||
final boolean insideShape = path.isWithin(topBoundaryPoint);
|
||||
|
||||
if (insideRectangle == ALL_INSIDE && insideShape)
|
||||
return OVERLAPS;
|
||||
|
||||
// Second, the shortcut of seeing whether endpoints are in/out is not going to
|
||||
// work with no area endpoints. So we rely entirely on intersections.
|
||||
|
||||
if (path.intersects(topPlane, planePoints))
|
||||
return OVERLAPS;
|
||||
|
||||
// There is another case for latitude zones only. This is when the boundaries of the shape all fit
|
||||
// within the zone, but the shape includes areas outside the zone crossing a pole.
|
||||
// In this case, the above "overlaps" check is insufficient. We also need to check a point on either boundary
|
||||
// whether it is within the shape. If both such points are within, then CONTAINS is the right answer. If
|
||||
// one such point is within, then OVERLAPS is the right answer.
|
||||
|
||||
if (insideShape)
|
||||
return CONTAINS;
|
||||
|
||||
if (insideRectangle == ALL_INSIDE)
|
||||
return WITHIN;
|
||||
|
||||
return DISJOINT;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
|
||||
return distanceStyle.computeDistance(planetModel, topPlane, x,y,z);
|
||||
|
|
|
@ -172,6 +172,13 @@ class GeoSouthRectangle extends GeoBaseBBox {
|
|||
p.intersects(planetModel, rightPlane, notablePoints, rightPlanePoints, bounds, leftPlane, topPlane);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean intersects(final GeoShape geoShape) {
|
||||
return geoShape.intersects(topPlane, topPlanePoints, leftPlane, rightPlane) ||
|
||||
geoShape.intersects(leftPlane, leftPlanePoints, rightPlane, topPlane) ||
|
||||
geoShape.intersects(rightPlane, rightPlanePoints, leftPlane, topPlane);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getBounds(Bounds bounds) {
|
||||
super.getBounds(bounds);
|
||||
|
@ -183,42 +190,6 @@ class GeoSouthRectangle extends GeoBaseBBox {
|
|||
.addPoint(URHC).addPoint(ULHC).addPoint(planetModel.SOUTH_POLE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRelationship(final GeoShape path) {
|
||||
//System.err.println(this+" getrelationship with "+path);
|
||||
final int insideRectangle = isShapeInsideBBox(path);
|
||||
if (insideRectangle == SOME_INSIDE) {
|
||||
//System.err.println(" some inside");
|
||||
return OVERLAPS;
|
||||
}
|
||||
|
||||
final boolean insideShape = path.isWithin(planetModel.SOUTH_POLE);
|
||||
|
||||
if (insideRectangle == ALL_INSIDE && insideShape) {
|
||||
//System.err.println(" inside of each other");
|
||||
return OVERLAPS;
|
||||
}
|
||||
|
||||
if (path.intersects(topPlane, topPlanePoints, leftPlane, rightPlane) ||
|
||||
path.intersects(leftPlane, leftPlanePoints, topPlane, rightPlane) ||
|
||||
path.intersects(rightPlane, rightPlanePoints, leftPlane, topPlane)) {
|
||||
//System.err.println(" edges intersect");
|
||||
return OVERLAPS;
|
||||
}
|
||||
|
||||
if (insideRectangle == ALL_INSIDE) {
|
||||
//System.err.println(" shape inside rectangle");
|
||||
return WITHIN;
|
||||
}
|
||||
|
||||
if (insideShape) {
|
||||
//System.err.println(" shape contains rectangle");
|
||||
return CONTAINS;
|
||||
}
|
||||
//System.err.println(" disjoint");
|
||||
return DISJOINT;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
|
||||
final double topDistance = distanceStyle.computeDistance(planetModel, topPlane, x,y,z, leftPlane, rightPlane);
|
||||
|
|
|
@ -139,6 +139,14 @@ class GeoStandardCircle extends GeoBaseCircle {
|
|||
return circlePlane.intersects(planetModel, p, notablePoints, circlePoints, bounds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean intersects(GeoShape geoShape) {
|
||||
if (circlePlane == null) {
|
||||
return false;
|
||||
}
|
||||
return geoShape.intersects(circlePlane, circlePoints);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getBounds(Bounds bounds) {
|
||||
super.getBounds(bounds);
|
||||
|
|
|
@ -288,6 +288,23 @@ class GeoStandardPath extends GeoBasePath {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean intersects(GeoShape geoShape) {
|
||||
for (final SegmentEndpoint pathPoint : endPoints) {
|
||||
if (pathPoint.intersects(geoShape)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
for (final PathSegment pathSegment : segments) {
|
||||
if (pathSegment.intersects(geoShape)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getBounds(Bounds bounds) {
|
||||
super.getBounds(bounds);
|
||||
|
@ -549,6 +566,17 @@ class GeoStandardPath extends GeoBasePath {
|
|||
return circlePlane.intersects(planetModel, p, notablePoints, this.notablePoints, bounds, this.cutoffPlanes);
|
||||
}
|
||||
|
||||
/** Determine if this endpoint intersects a GeoShape.
|
||||
*@param geoShape is the GeoShape.
|
||||
*@return true if there is shape intersect this endpoint.
|
||||
*/
|
||||
public boolean intersects(final GeoShape geoShape) {
|
||||
//System.err.println(" looking for intersection between plane "+p+" and circle "+circlePlane+" on proper side of "+cutoffPlanes+" within "+bounds);
|
||||
if (circlePlane == null)
|
||||
return false;
|
||||
return geoShape.intersects(circlePlane, this.notablePoints, this.cutoffPlanes);
|
||||
}
|
||||
|
||||
/** Get the bounds for a segment endpoint.
|
||||
*@param planetModel is the planet model.
|
||||
*@param bounds are the bounds to be modified.
|
||||
|
@ -799,6 +827,15 @@ class GeoStandardPath extends GeoBasePath {
|
|||
lowerConnectingPlane.intersects(planetModel, p, notablePoints, lowerConnectingPlanePoints, bounds, upperConnectingPlane, startCutoffPlane, endCutoffPlane);
|
||||
}
|
||||
|
||||
/** Determine if this endpoint intersects a specified GeoShape.
|
||||
*@param geoShape is the GeoShape.
|
||||
*@return true if there GeoShape intersects this endpoint.
|
||||
*/
|
||||
public boolean intersects(final GeoShape geoShape) {
|
||||
return geoShape.intersects(upperConnectingPlane, upperConnectingPlanePoints, lowerConnectingPlane, startCutoffPlane, endCutoffPlane) ||
|
||||
geoShape.intersects(lowerConnectingPlane, lowerConnectingPlanePoints, upperConnectingPlane, startCutoffPlane, endCutoffPlane);
|
||||
}
|
||||
|
||||
/** Get the bounds for a segment endpoint.
|
||||
*@param planetModel is the planet model.
|
||||
*@param bounds are the bounds to be modified.
|
||||
|
|
|
@ -165,6 +165,13 @@ class GeoWideDegenerateHorizontalLine extends GeoBaseBBox {
|
|||
return p.intersects(planetModel, plane, notablePoints, planePoints, bounds, eitherBound);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean intersects(final GeoShape geoShape) {
|
||||
// Right and left bounds are essentially independent hemispheres; crossing into the wrong part of one
|
||||
// requires crossing into the right part of the other. So intersection can ignore the left/right bounds.
|
||||
return geoShape.intersects(plane, planePoints, eitherBound);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getBounds(Bounds bounds) {
|
||||
super.getBounds(bounds);
|
||||
|
@ -176,7 +183,7 @@ class GeoWideDegenerateHorizontalLine extends GeoBaseBBox {
|
|||
|
||||
@Override
|
||||
public int getRelationship(final GeoShape path) {
|
||||
if (path.intersects(plane, planePoints, eitherBound)) {
|
||||
if (intersects(path)) {
|
||||
return OVERLAPS;
|
||||
}
|
||||
|
||||
|
|
|
@ -139,6 +139,14 @@ class GeoWideLongitudeSlice extends GeoBaseBBox {
|
|||
p.intersects(planetModel, rightPlane, notablePoints, planePoints, bounds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean intersects(final GeoShape geoShape) {
|
||||
// Right and left bounds are essentially independent hemispheres; crossing into the wrong part of one
|
||||
// requires crossing into the right part of the other. So intersection can ignore the left/right bounds.
|
||||
return geoShape.intersects(leftPlane, planePoints) ||
|
||||
geoShape.intersects(rightPlane, planePoints);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getBounds(Bounds bounds) {
|
||||
super.getBounds(bounds);
|
||||
|
@ -150,30 +158,6 @@ class GeoWideLongitudeSlice extends GeoBaseBBox {
|
|||
.addPoint(planetModel.SOUTH_POLE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRelationship(final GeoShape path) {
|
||||
final int insideRectangle = isShapeInsideBBox(path);
|
||||
if (insideRectangle == SOME_INSIDE)
|
||||
return OVERLAPS;
|
||||
|
||||
final boolean insideShape = path.isWithin(planetModel.NORTH_POLE);
|
||||
|
||||
if (insideRectangle == ALL_INSIDE && insideShape)
|
||||
return OVERLAPS;
|
||||
|
||||
if (path.intersects(leftPlane, planePoints) ||
|
||||
path.intersects(rightPlane, planePoints))
|
||||
return OVERLAPS;
|
||||
|
||||
if (insideRectangle == ALL_INSIDE)
|
||||
return WITHIN;
|
||||
|
||||
if (insideShape)
|
||||
return CONTAINS;
|
||||
|
||||
return DISJOINT;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
|
||||
// Because the rectangle exceeds 180 degrees, it is safe to compute the horizontally
|
||||
|
|
|
@ -176,6 +176,16 @@ class GeoWideNorthRectangle extends GeoBaseBBox {
|
|||
p.intersects(planetModel, rightPlane, notablePoints, rightPlanePoints, bounds, bottomPlane);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean intersects(final GeoShape geoShape) {
|
||||
// Right and left bounds are essentially independent hemispheres; crossing into the wrong part of one
|
||||
// requires crossing into the right part of the other. So intersection can ignore the left/right bounds.
|
||||
return
|
||||
geoShape.intersects(bottomPlane, bottomPlanePoints, eitherBound) ||
|
||||
geoShape.intersects(leftPlane, leftPlanePoints, bottomPlane) ||
|
||||
geoShape.intersects(rightPlane, rightPlanePoints, bottomPlane);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getBounds(Bounds bounds) {
|
||||
super.getBounds(bounds);
|
||||
|
@ -187,44 +197,6 @@ class GeoWideNorthRectangle extends GeoBaseBBox {
|
|||
.addPoint(LLHC).addPoint(LRHC).addPoint(planetModel.NORTH_POLE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRelationship(final GeoShape path) {
|
||||
//System.err.println(this+" comparing to "+path);
|
||||
final int insideRectangle = isShapeInsideBBox(path);
|
||||
if (insideRectangle == SOME_INSIDE) {
|
||||
//System.err.println(" some inside");
|
||||
return OVERLAPS;
|
||||
}
|
||||
|
||||
final boolean insideShape = path.isWithin(planetModel.NORTH_POLE);
|
||||
|
||||
if (insideRectangle == ALL_INSIDE && insideShape) {
|
||||
//System.err.println(" both inside each other");
|
||||
return OVERLAPS;
|
||||
}
|
||||
|
||||
if (
|
||||
path.intersects(bottomPlane, bottomPlanePoints, eitherBound) ||
|
||||
path.intersects(leftPlane, leftPlanePoints, bottomPlane) ||
|
||||
path.intersects(rightPlane, rightPlanePoints, bottomPlane)) {
|
||||
//System.err.println(" edges intersect");
|
||||
return OVERLAPS;
|
||||
}
|
||||
|
||||
if (insideRectangle == ALL_INSIDE) {
|
||||
//System.err.println(" shape inside rectangle");
|
||||
return WITHIN;
|
||||
}
|
||||
|
||||
if (insideShape) {
|
||||
//System.err.println(" rectangle inside shape");
|
||||
return CONTAINS;
|
||||
}
|
||||
|
||||
//System.err.println(" disjoint");
|
||||
return DISJOINT;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
|
||||
final double bottomDistance = distanceStyle.computeDistance(planetModel, bottomPlane, x,y,z, eitherBound);
|
||||
|
|
|
@ -204,6 +204,14 @@ class GeoWideRectangle extends GeoBaseBBox {
|
|||
p.intersects(planetModel, rightPlane, notablePoints, rightPlanePoints, bounds, topPlane, bottomPlane);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean intersects(final GeoShape geoShape) {
|
||||
return geoShape.intersects(topPlane, topPlanePoints, bottomPlane, eitherBound) ||
|
||||
geoShape.intersects(bottomPlane, bottomPlanePoints, topPlane, eitherBound) ||
|
||||
geoShape.intersects(leftPlane, leftPlanePoints, topPlane, bottomPlane) ||
|
||||
geoShape.intersects(rightPlane, rightPlanePoints, topPlane, bottomPlane);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getBounds(Bounds bounds) {
|
||||
super.getBounds(bounds);
|
||||
|
@ -216,44 +224,6 @@ class GeoWideRectangle extends GeoBaseBBox {
|
|||
.addPoint(ULHC).addPoint(URHC).addPoint(LRHC).addPoint(LLHC);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRelationship(final GeoShape path) {
|
||||
//System.err.println(this+" comparing to "+path);
|
||||
final int insideRectangle = isShapeInsideBBox(path);
|
||||
if (insideRectangle == SOME_INSIDE) {
|
||||
//System.err.println(" some inside");
|
||||
return OVERLAPS;
|
||||
}
|
||||
|
||||
final boolean insideShape = path.isWithin(ULHC);
|
||||
|
||||
if (insideRectangle == ALL_INSIDE && insideShape) {
|
||||
//System.err.println(" both inside each other");
|
||||
return OVERLAPS;
|
||||
}
|
||||
|
||||
if (path.intersects(topPlane, topPlanePoints, bottomPlane, eitherBound) ||
|
||||
path.intersects(bottomPlane, bottomPlanePoints, topPlane, eitherBound) ||
|
||||
path.intersects(leftPlane, leftPlanePoints, topPlane, bottomPlane) ||
|
||||
path.intersects(rightPlane, rightPlanePoints, topPlane, bottomPlane)) {
|
||||
//System.err.println(" edges intersect");
|
||||
return OVERLAPS;
|
||||
}
|
||||
|
||||
if (insideRectangle == ALL_INSIDE) {
|
||||
//System.err.println(" shape inside rectangle");
|
||||
return WITHIN;
|
||||
}
|
||||
|
||||
if (insideShape) {
|
||||
//System.err.println(" rectangle inside shape");
|
||||
return CONTAINS;
|
||||
}
|
||||
|
||||
//System.err.println(" disjoint");
|
||||
return DISJOINT;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
|
||||
final double topDistance = distanceStyle.computeDistance(planetModel, topPlane, x,y,z, bottomPlane, eitherBound);
|
||||
|
|
|
@ -175,6 +175,13 @@ class GeoWideSouthRectangle extends GeoBaseBBox {
|
|||
p.intersects(planetModel, rightPlane, notablePoints, rightPlanePoints, bounds, topPlane);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean intersects(final GeoShape geoShape) {
|
||||
return geoShape.intersects(topPlane, topPlanePoints, eitherBound) ||
|
||||
geoShape.intersects(leftPlane, leftPlanePoints, topPlane) ||
|
||||
geoShape.intersects(rightPlane, rightPlanePoints, topPlane);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getBounds(Bounds bounds) {
|
||||
super.getBounds(bounds);
|
||||
|
@ -186,43 +193,6 @@ class GeoWideSouthRectangle extends GeoBaseBBox {
|
|||
.addPoint(ULHC).addPoint(URHC).addPoint(planetModel.SOUTH_POLE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRelationship(final GeoShape path) {
|
||||
//System.err.println(this+" comparing to "+path);
|
||||
final int insideRectangle = isShapeInsideBBox(path);
|
||||
if (insideRectangle == SOME_INSIDE) {
|
||||
//System.err.println(" some inside");
|
||||
return OVERLAPS;
|
||||
}
|
||||
|
||||
final boolean insideShape = path.isWithin(planetModel.SOUTH_POLE);
|
||||
|
||||
if (insideRectangle == ALL_INSIDE && insideShape) {
|
||||
//System.err.println(" both inside each other");
|
||||
return OVERLAPS;
|
||||
}
|
||||
|
||||
if (path.intersects(topPlane, topPlanePoints, eitherBound) ||
|
||||
path.intersects(leftPlane, leftPlanePoints, topPlane) ||
|
||||
path.intersects(rightPlane, rightPlanePoints, topPlane)) {
|
||||
//System.err.println(" edges intersect");
|
||||
return OVERLAPS;
|
||||
}
|
||||
|
||||
if (insideRectangle == ALL_INSIDE) {
|
||||
//System.err.println(" shape inside rectangle");
|
||||
return WITHIN;
|
||||
}
|
||||
|
||||
if (insideShape) {
|
||||
//System.err.println(" rectangle inside shape");
|
||||
return CONTAINS;
|
||||
}
|
||||
|
||||
//System.err.println(" disjoint");
|
||||
return DISJOINT;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
|
||||
final double topDistance = distanceStyle.computeDistance(planetModel, topPlane, x,y,z, eitherBound);
|
||||
|
|
|
@ -66,6 +66,11 @@ class GeoWorld extends GeoBaseBBox {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean intersects(final GeoShape geoShape) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getBounds(Bounds bounds) {
|
||||
super.getBounds(bounds);
|
||||
|
|
|
@ -0,0 +1,842 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* Check relationship between polygon and GeoShapes of composite polygons. Normally we construct
|
||||
* the composite polygon (when possible) and the complex one.
|
||||
*/
|
||||
public class CompositeGeoPolygonRelationshipsTest {
|
||||
|
||||
@Test
|
||||
public void testGeoCompositePolygon1() {
|
||||
|
||||
//POLYGON ((19.845091 -60.452631, 20.119948 -61.655652, 23.207901 -61.453298, 22.820804 -60.257713, 21 -61,19.845091 -60.452631))
|
||||
GeoPolygon originalConvexPol = buildGeoPolygon(19.84509, -60.452631,
|
||||
20.119948, -61.655652,
|
||||
23.207901, -61.453298,
|
||||
22.820804, -60.257713,
|
||||
21, -61);
|
||||
|
||||
//POLYGON ((19.845091 -60.452631, 21 -61,22.820804 -60.257713,23.207901 -61.453298, 20.119948 -61.655652, 19.845091 -60.452631))
|
||||
GeoPolygon originalConcavePol = buildGeoPolygon(19.84509, -60.452631,
|
||||
21, -61,
|
||||
22.820804, -60.257713,
|
||||
23.207901, -61.453298,
|
||||
20.119948, -61.655652);
|
||||
|
||||
GeoPolygon polConvex = buildGeoPolygon(20.0, -60.4,
|
||||
20.1, -60.4,
|
||||
20.1, -60.3,
|
||||
20.0, -60.3,
|
||||
20.0, -60.3);
|
||||
|
||||
GeoPolygon polConcave = buildConcaveGeoPolygon(20.0, -60.4,
|
||||
20.1, -60.4,
|
||||
20.1, -60.3,
|
||||
20.0, -60.3);
|
||||
|
||||
//convex
|
||||
int rel = originalConvexPol.getRelationship(polConvex);
|
||||
assertEquals(GeoArea.DISJOINT, rel);
|
||||
rel = polConvex.getRelationship(originalConvexPol);
|
||||
assertEquals(GeoArea.DISJOINT, rel);
|
||||
|
||||
|
||||
rel = originalConvexPol.getRelationship(polConcave);
|
||||
assertEquals(GeoArea.CONTAINS, rel);
|
||||
rel = polConcave.getRelationship(originalConvexPol);
|
||||
assertEquals(GeoArea.WITHIN, rel);
|
||||
|
||||
//concave
|
||||
rel = originalConcavePol.getRelationship(polConvex);
|
||||
assertEquals(GeoArea.WITHIN, rel);
|
||||
rel = polConvex.getRelationship(originalConcavePol);
|
||||
assertEquals(GeoArea.CONTAINS, rel);
|
||||
|
||||
rel = originalConcavePol.getRelationship(polConcave);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
rel = polConcave.getRelationship(originalConcavePol);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGeoCompositePolygon2() {
|
||||
|
||||
//POLYGON ((19.845091 -60.452631, 20.119948 -61.655652, 23.207901 -61.453298, 22.820804 -60.257713, 21 -61,19.845091 -60.452631))
|
||||
GeoPolygon originalConvexPol = buildGeoPolygon(19.84509, -60.452631,
|
||||
20.119948, -61.655652,
|
||||
23.207901, -61.453298,
|
||||
22.820804, -60.257713,
|
||||
21, -61);
|
||||
|
||||
//POLYGON ((19.845091 -60.452631, 21 -61,22.820804 -60.257713,23.207901 -61.453298, 20.119948 -61.655652, 19.845091 -60.452631))
|
||||
GeoPolygon originalConcavePol = buildGeoPolygon(19.84509, -60.452631,
|
||||
21, -61,
|
||||
22.820804, -60.257713,
|
||||
23.207901, -61.453298,
|
||||
20.119948, -61.655652);
|
||||
|
||||
//POLYGON ((20.9 -60.8, 21.1 -60.8, 21.1 -60.6, 20.9 -60.6,20.9 -60.8))
|
||||
GeoPolygon polConvex = buildGeoPolygon(20.9, -60.8,
|
||||
21.1, -60.8,
|
||||
21.1, -60.6,
|
||||
20.9, -60.6,
|
||||
20.9, -60.6);
|
||||
|
||||
GeoPolygon polConcave = buildConcaveGeoPolygon(20.9, -60.8,
|
||||
21.1, -60.8,
|
||||
21.1, -60.6,
|
||||
20.9, -60.6);
|
||||
|
||||
//convex
|
||||
int rel = originalConvexPol.getRelationship(polConvex);
|
||||
assertEquals(GeoArea.DISJOINT, rel);
|
||||
rel = polConvex.getRelationship(originalConvexPol);
|
||||
assertEquals(GeoArea.DISJOINT, rel);
|
||||
|
||||
rel = originalConvexPol.getRelationship(polConcave);
|
||||
assertEquals(GeoArea.CONTAINS, rel);
|
||||
rel = polConcave.getRelationship(originalConvexPol);
|
||||
assertEquals(GeoArea.WITHIN, rel);
|
||||
|
||||
//concave
|
||||
rel = originalConcavePol.getRelationship(polConvex);
|
||||
assertEquals(GeoArea.WITHIN, rel);
|
||||
rel = polConvex.getRelationship(originalConcavePol);
|
||||
assertEquals(GeoArea.CONTAINS, rel);
|
||||
|
||||
rel = originalConcavePol.getRelationship(polConcave);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
rel = polConcave.getRelationship(originalConcavePol);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGeoCompositePolygon3() {
|
||||
|
||||
//POLYGON ((19.845091 -60.452631, 20.119948 -61.655652, 23.207901 -61.453298, 22.820804 -60.257713, 21 -61,19.845091 -60.452631))
|
||||
GeoPolygon originalConvexPol = buildGeoPolygon(19.84509, -60.452631,
|
||||
20.119948, -61.655652,
|
||||
23.207901, -61.453298,
|
||||
22.820804, -60.257713,
|
||||
21, -61);
|
||||
|
||||
//POLYGON ((19.845091 -60.452631, 21 -61,22.820804 -60.257713,23.207901 -61.453298, 20.119948 -61.655652, 19.845091 -60.452631))
|
||||
GeoPolygon originalConcavePol = buildGeoPolygon(19.84509, -60.452631,
|
||||
21, -61,
|
||||
22.820804, -60.257713,
|
||||
23.207901, -61.453298,
|
||||
20.119948, -61.655652);
|
||||
|
||||
//POLYGON ((20.9 -61.1, 21.1 -61.1, 21.1 -60.9, 20.9 -60.9,20.9 -61.1))
|
||||
GeoPolygon polConvex = buildGeoPolygon(20.9, -61.1,
|
||||
21.1, -61.1,
|
||||
21.1, -60.9,
|
||||
20.9, -60.9,
|
||||
20.9, -60.9);
|
||||
|
||||
GeoPolygon polConcave = buildConcaveGeoPolygon(20.9, -61.1,
|
||||
21.1, -61.1,
|
||||
21.1, -60.9,
|
||||
20.9, -60.9);
|
||||
|
||||
//convex
|
||||
int rel = originalConvexPol.getRelationship(polConvex);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
rel = polConvex.getRelationship(originalConvexPol);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
|
||||
rel = originalConvexPol.getRelationship(polConcave);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
rel = polConcave.getRelationship(originalConvexPol);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
|
||||
//concave
|
||||
rel = originalConcavePol.getRelationship(polConvex);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
rel = polConvex.getRelationship(originalConcavePol);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
|
||||
rel = originalConcavePol.getRelationship(polConcave);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
rel = polConcave.getRelationship(originalConcavePol);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGeoCompositePolygon4() {
|
||||
|
||||
//POLYGON ((19.845091 -60.452631, 20.119948 -61.655652, 23.207901 -61.453298, 22.820804 -60.257713, 21 -61,19.845091 -60.452631))
|
||||
GeoPolygon originalConvexPol = buildGeoPolygon(19.84509, -60.452631,
|
||||
20.119948, -61.655652,
|
||||
23.207901, -61.453298,
|
||||
22.820804, -60.257713,
|
||||
21, -61);
|
||||
|
||||
//POLYGON ((19.845091 -60.452631, 21 -61,22.820804 -60.257713,23.207901 -61.453298, 20.119948 -61.655652, 19.845091 -60.452631))
|
||||
GeoPolygon originalConcavePol = buildGeoPolygon(19.84509, -60.452631,
|
||||
21, -61,
|
||||
22.820804, -60.257713,
|
||||
23.207901, -61.453298,
|
||||
20.119948, -61.655652);
|
||||
|
||||
//POLYGON ((20.9 -61.4, 21.1 -61.4, 21.1 -61.2, 20.9 -61.2,20.9 -61.4))
|
||||
GeoPolygon polConvex = buildGeoPolygon(20.9, -61.4,
|
||||
21.1, -61.4,
|
||||
21.1, -61.2,
|
||||
20.9, -61.2,
|
||||
20.9, -61.2);
|
||||
|
||||
GeoPolygon polConcave = buildConcaveGeoPolygon(20.9, -61.4,
|
||||
21.1, -61.4,
|
||||
21.1, -61.2,
|
||||
20.9, -61.2);
|
||||
|
||||
//convex
|
||||
int rel = originalConvexPol.getRelationship(polConvex);
|
||||
assertEquals(GeoArea.WITHIN, rel);
|
||||
rel = polConvex.getRelationship(originalConvexPol);
|
||||
assertEquals(GeoArea.CONTAINS, rel);
|
||||
|
||||
rel = originalConvexPol.getRelationship(polConcave);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
rel = polConcave.getRelationship(originalConvexPol);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
|
||||
//concave
|
||||
rel = originalConcavePol.getRelationship(polConvex);
|
||||
assertEquals(GeoArea.DISJOINT, rel);
|
||||
rel = polConvex.getRelationship(originalConcavePol);
|
||||
assertEquals(GeoArea.DISJOINT, rel);
|
||||
|
||||
rel = originalConcavePol.getRelationship(polConcave);
|
||||
assertEquals(GeoArea.CONTAINS, rel);
|
||||
rel = polConcave.getRelationship(originalConcavePol);
|
||||
assertEquals(GeoArea.WITHIN, rel);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGeoCompositePolygon5() {
|
||||
|
||||
//POLYGON ((19.845091 -60.452631, 20.119948 -61.655652, 23.207901 -61.453298, 22.820804 -60.257713, 21 -61,19.845091 -60.452631))
|
||||
GeoPolygon originaConvexlPol = buildGeoPolygon(19.84509, -60.452631,
|
||||
20.119948, -61.655652,
|
||||
23.207901, -61.453298,
|
||||
22.820804, -60.257713,
|
||||
21, -61);
|
||||
|
||||
//POLYGON ((19.845091 -60.452631, 21 -61,22.820804 -60.257713,23.207901 -61.453298, 20.119948 -61.655652, 19.845091 -60.452631))
|
||||
GeoPolygon originalConcavePol = buildGeoPolygon(19.84509, -60.452631,
|
||||
21, -61,
|
||||
22.820804, -60.257713,
|
||||
23.207901, -61.453298,
|
||||
20.119948, -61.655652);
|
||||
|
||||
//POLYGON ((19 -62, 23 -62, 23 -60, 19 -60,19 -62))
|
||||
GeoPolygon polConvex = buildGeoPolygon(19, -62,
|
||||
23, -62,
|
||||
23, -60,
|
||||
19, -60,
|
||||
19, -60);
|
||||
|
||||
GeoPolygon polConcave = buildConcaveGeoPolygon(19, -62,
|
||||
23, -62,
|
||||
23, -60,
|
||||
19, -60);
|
||||
|
||||
//convex
|
||||
int rel = originaConvexlPol.getRelationship(polConvex);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
rel = polConvex.getRelationship(originaConvexlPol);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
|
||||
rel = originaConvexlPol.getRelationship(polConcave);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
rel = polConcave.getRelationship(originaConvexlPol);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
|
||||
//concave
|
||||
rel = originalConcavePol.getRelationship(polConvex);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
rel = polConvex.getRelationship(originalConcavePol);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
|
||||
rel = originalConcavePol.getRelationship(polConcave);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
rel = polConcave.getRelationship(originalConcavePol);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGeoCompositePolygon6() {
|
||||
|
||||
//POLYGON ((19.845091 -60.452631, 20.119948 -61.655652, 23.207901 -61.453298, 22.820804 -60.257713, 21 -61,19.845091 -60.452631))
|
||||
GeoPolygon originalConvexPol = buildGeoPolygon(19.84509, -60.452631,
|
||||
20.119948, -61.655652,
|
||||
23.207901, -61.453298,
|
||||
22.820804, -60.257713,
|
||||
21, -61);
|
||||
|
||||
//POLYGON ((19.845091 -60.452631, 21 -61,22.820804 -60.257713,23.207901 -61.453298, 20.119948 -61.655652, 19.845091 -60.452631))
|
||||
GeoPolygon originalConcavePol = buildGeoPolygon(19.84509, -60.452631,
|
||||
21, -61,
|
||||
22.820804, -60.257713,
|
||||
23.207901, -61.453298,
|
||||
20.119948, -61.655652);
|
||||
|
||||
//POLYGON ((19 -62, 24 -62, 24 -60, 19 -60,19 -62))
|
||||
GeoPolygon polConvex = buildGeoPolygon(19, -62,
|
||||
24, -62,
|
||||
24, -60,
|
||||
19, -60,
|
||||
19, -60);
|
||||
|
||||
GeoPolygon polConcave = buildConcaveGeoPolygon(19, -62,
|
||||
24, -62,
|
||||
24, -60,
|
||||
19, -60);
|
||||
|
||||
//convex
|
||||
int rel = originalConvexPol.getRelationship(polConvex);
|
||||
assertEquals(GeoArea.CONTAINS, rel);
|
||||
rel = polConvex.getRelationship(originalConvexPol);
|
||||
assertEquals(GeoArea.WITHIN, rel);
|
||||
|
||||
rel = originalConvexPol.getRelationship(polConcave);
|
||||
assertEquals(GeoArea.DISJOINT, rel);
|
||||
rel = polConcave.getRelationship(originalConvexPol);
|
||||
assertEquals(GeoArea.DISJOINT, rel);
|
||||
|
||||
//concave
|
||||
rel = originalConcavePol.getRelationship(polConvex);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
rel = polConvex.getRelationship(originalConcavePol);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
|
||||
rel = originalConcavePol.getRelationship(polConcave);
|
||||
assertEquals(GeoArea.WITHIN, rel);
|
||||
rel = polConcave.getRelationship(originalConcavePol);
|
||||
assertEquals(GeoArea.CONTAINS, rel);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void testGeoCompositePolygon7() {
|
||||
|
||||
//POLYGON ((19.845091 -60.452631, 20.119948 -61.655652, 23.207901 -61.453298, 22.820804 -60.257713, 21 -61,19.845091 -60.452631))
|
||||
GeoPolygon originalConvexPol = buildGeoPolygon(19.84509, -60.452631,
|
||||
20.119948, -61.655652,
|
||||
23.207901, -61.453298,
|
||||
22.820804, -60.257713,
|
||||
21, -61);
|
||||
|
||||
//POLYGON ((19.845091 -60.452631, 21 -61,22.820804 -60.257713,23.207901 -61.453298, 20.119948 -61.655652, 19.845091 -60.452631))
|
||||
GeoPolygon originalConcavePol = buildGeoPolygon(19.84509, -60.452631,
|
||||
21, -61,
|
||||
22.820804, -60.257713,
|
||||
23.207901, -61.453298,
|
||||
20.119948, -61.655652);
|
||||
|
||||
//POLYGON ((20.2 -61.4, 20.5 -61.4, 20.5 -60.8, 20.2 -60.8,20.2 -61.4))
|
||||
GeoPolygon polConvex = buildGeoPolygon(20.2, -61.4,
|
||||
20.5, -61.4,
|
||||
20.5, -60.8,
|
||||
20.2, -60.8,
|
||||
20.2, -60.8);
|
||||
|
||||
GeoPolygon polConcave = buildConcaveGeoPolygon(20.2, -61.4,
|
||||
20.5, -61.4,
|
||||
20.5, -60.8,
|
||||
20.2, -60.8);
|
||||
|
||||
//convex
|
||||
int rel = originalConvexPol.getRelationship(polConvex);
|
||||
assertEquals(GeoArea.WITHIN, rel);
|
||||
rel = polConvex.getRelationship(originalConvexPol);
|
||||
assertEquals(GeoArea.CONTAINS, rel);
|
||||
|
||||
rel = originalConvexPol.getRelationship(polConcave);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
rel = polConcave.getRelationship(originalConvexPol);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
|
||||
//concave
|
||||
rel = originalConcavePol.getRelationship(polConvex);
|
||||
assertEquals(GeoArea.DISJOINT, rel);
|
||||
rel = polConvex.getRelationship(originalConvexPol);
|
||||
assertEquals(GeoArea.CONTAINS, rel);
|
||||
|
||||
rel = originalConvexPol.getRelationship(polConcave);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
rel = polConcave.getRelationship(originalConvexPol);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGeoCompositePolygon8() {
|
||||
|
||||
//POLYGON ((19.845091 -60.452631, 20.119948 -61.655652, 23.207901 -61.453298, 22.820804 -60.257713,21 -61, 19.845091 -60.452631))
|
||||
GeoPolygon originalPol = buildGeoPolygon(19.84509, -60.452631,
|
||||
20.119948, -61.655652,
|
||||
23.207901, -61.453298,
|
||||
22.820804, -60.257713,
|
||||
21, -61);
|
||||
|
||||
|
||||
GeoShape shape = getInsideCompositeShape();
|
||||
|
||||
int rel = originalPol.getRelationship(shape);
|
||||
assertEquals(GeoArea.WITHIN, rel);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testGeoPolygonPole1() {
|
||||
//POLYGON((0 80, 45 85 ,90 80,135 85,180 80, -135 85, -90 80, -45 85,0 80))
|
||||
GeoPolygon compositePol= getCompositePolygon();
|
||||
GeoPolygon complexPol= getComplexPolygon();
|
||||
|
||||
//POLYGON ((20.9 -61.4, 21.1 -61.4, 21.1 -61.2, 20.9 -61.2,20.9 -61.4))
|
||||
GeoPolygon polConvex = buildGeoPolygon(20.9, -61.4,
|
||||
21.1, -61.4,
|
||||
21.1, -61.2,
|
||||
20.9, -61.2,
|
||||
20.9, -61.2);
|
||||
|
||||
GeoPolygon polConcave = buildConcaveGeoPolygon(20.9, -61.4,
|
||||
21.1, -61.4,
|
||||
21.1, -61.2,
|
||||
20.9, -61.2);
|
||||
|
||||
int rel = compositePol.getRelationship(polConvex);
|
||||
assertEquals(GeoArea.DISJOINT, rel);
|
||||
rel = polConvex.getRelationship(compositePol);
|
||||
assertEquals(GeoArea.DISJOINT, rel);
|
||||
|
||||
rel = compositePol.getRelationship(polConcave);
|
||||
assertEquals(GeoArea.CONTAINS, rel);
|
||||
rel = polConcave.getRelationship(compositePol);
|
||||
assertEquals(GeoArea.WITHIN, rel);
|
||||
|
||||
rel = complexPol.getRelationship(polConvex);
|
||||
assertEquals(GeoArea.DISJOINT, rel);
|
||||
rel = polConvex.getRelationship(complexPol);
|
||||
assertEquals(GeoArea.DISJOINT, rel);
|
||||
|
||||
rel = complexPol.getRelationship(polConcave);
|
||||
assertEquals(GeoArea.CONTAINS, rel);
|
||||
rel = polConcave.getRelationship(complexPol);
|
||||
assertEquals(GeoArea.WITHIN, rel);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGeoPolygonPole2() {
|
||||
//POLYGON((0 80, 45 85 ,90 80,135 85,180 80, -135 85, -90 80, -45 85,0 80))
|
||||
GeoPolygon compositePol= getCompositePolygon();
|
||||
GeoPolygon complexPol= getComplexPolygon();
|
||||
|
||||
//POLYGON((-1 81, -1 79,1 79,1 81, -1 81))
|
||||
GeoPolygon polConvex = buildGeoPolygon(-1,81,
|
||||
-1,79,
|
||||
1,79,
|
||||
1,81,
|
||||
1,81);
|
||||
|
||||
GeoPolygon polConcave = buildConcaveGeoPolygon(-1,81,
|
||||
-1,79,
|
||||
1,79,
|
||||
1,81);
|
||||
|
||||
int rel = compositePol.getRelationship(polConvex);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
rel = polConvex.getRelationship(compositePol);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
|
||||
rel = compositePol.getRelationship(polConcave);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
rel = polConcave.getRelationship(compositePol);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
|
||||
rel = complexPol.getRelationship(polConvex);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
rel = polConvex.getRelationship(complexPol);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
|
||||
rel = complexPol.getRelationship(polConcave);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
rel = polConcave.getRelationship(complexPol);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGeoPolygonPole3() {
|
||||
//POLYGON((0 80, 45 85 ,90 80,135 85,180 80, -135 85, -90 80, -45 85,0 80))
|
||||
GeoPolygon compositePol= getCompositePolygon();
|
||||
GeoPolygon complexPol= getComplexPolygon();
|
||||
|
||||
//POLYGON((-1 86, -1 84,1 84,1 86, -1 86))
|
||||
GeoPolygon polConvex = buildGeoPolygon(-1,86,
|
||||
-1,84,
|
||||
1,84,
|
||||
1,86,
|
||||
1,86);
|
||||
|
||||
GeoPolygon polConcave = buildConcaveGeoPolygon(-1,86,
|
||||
-1,84,
|
||||
1,84,
|
||||
1,86);
|
||||
|
||||
int rel = compositePol.getRelationship(polConvex);
|
||||
assertEquals(GeoArea.WITHIN, rel);
|
||||
rel = polConvex.getRelationship(compositePol);
|
||||
assertEquals(GeoArea.CONTAINS, rel);
|
||||
|
||||
rel = compositePol.getRelationship(polConcave);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
rel = polConcave.getRelationship(compositePol);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
|
||||
rel = complexPol.getRelationship(polConvex);
|
||||
assertEquals(GeoArea.WITHIN, rel);
|
||||
rel = polConvex.getRelationship(complexPol);
|
||||
assertEquals(GeoArea.CONTAINS, rel);
|
||||
|
||||
rel = complexPol.getRelationship(polConcave);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
rel = polConcave.getRelationship(complexPol);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultiPolygon1() {
|
||||
//MULTIPOLYGON(((-145.790967486 -5.17543698881, -145.790854979 -5.11348060995, -145.853073512 -5.11339421216, -145.853192037 -5.17535061936, -145.790967486 -5.17543698881)),
|
||||
//((-145.8563923 -5.17527125408, -145.856222168 -5.11332154814, -145.918433943 -5.11317773171, -145.918610092 -5.17512738429, -145.8563923 -5.17527125408)))
|
||||
GeoPolygon multiPol= getMultiPolygon();
|
||||
|
||||
//POLYGON((-145.8555 -5.13, -145.8540 -5.13, -145.8540 -5.12, -145.8555 -5.12, -145.8555 -5.13))
|
||||
GeoPolygon polConvex = buildGeoPolygon(-145.8555, -5.13,
|
||||
-145.8540, -5.13,
|
||||
-145.8540, -5.12,
|
||||
-145.8555, -5.12,
|
||||
-145.8555, -5.12);
|
||||
|
||||
GeoPolygon polConcave = buildConcaveGeoPolygon(-145.8555, -5.13,
|
||||
-145.8540, -5.13,
|
||||
-145.8540, -5.12,
|
||||
-145.8555, -5.12);
|
||||
|
||||
int rel = multiPol.getRelationship(polConvex);
|
||||
assertEquals(GeoArea.DISJOINT, rel);
|
||||
rel = polConvex.getRelationship(multiPol);
|
||||
assertEquals(GeoArea.DISJOINT, rel);
|
||||
assertEquals(false,multiPol.intersects(polConvex));
|
||||
assertEquals(false,polConvex.intersects(multiPol));
|
||||
|
||||
rel = multiPol.getRelationship(polConcave);
|
||||
assertEquals(GeoArea.CONTAINS, rel);
|
||||
rel = polConcave.getRelationship(multiPol);
|
||||
assertEquals(GeoArea.WITHIN, rel);
|
||||
assertEquals(false,multiPol.intersects(polConcave));
|
||||
assertEquals(false,polConcave.intersects(multiPol));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultiPolygon2() {
|
||||
//MULTIPOLYGON(((-145.790967486 -5.17543698881, -145.790854979 -5.11348060995, -145.853073512 -5.11339421216, -145.853192037 -5.17535061936, -145.790967486 -5.17543698881)),
|
||||
//((-145.8563923 -5.17527125408, -145.856222168 -5.11332154814, -145.918433943 -5.11317773171, -145.918610092 -5.17512738429, -145.8563923 -5.17527125408)))
|
||||
GeoPolygon multiPol= getMultiPolygon();
|
||||
|
||||
//POLYGON((-145.8555 -5.13, -145.85 -5.13, -145.85 -5.12, -145.8555 -5.12, -145.8555 -5.13))
|
||||
GeoPolygon polConvex = buildGeoPolygon(-145.8555, -5.13,
|
||||
-145.85, -5.13,
|
||||
-145.85, -5.12,
|
||||
-145.8555, -5.12,
|
||||
-145.8555, -5.12);
|
||||
|
||||
GeoPolygon polConcave = buildConcaveGeoPolygon(-145.8555, -5.13,
|
||||
-145.85, -5.13,
|
||||
-145.85, -5.12,
|
||||
-145.8555, -5.12);
|
||||
|
||||
int rel = multiPol.getRelationship(polConvex);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
rel = polConvex.getRelationship(multiPol);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
assertEquals(true,multiPol.intersects(polConvex));
|
||||
assertEquals(true,polConvex.intersects(multiPol));
|
||||
|
||||
rel = multiPol.getRelationship(polConcave);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
rel = polConcave.getRelationship(multiPol);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
assertEquals(true,multiPol.intersects(polConcave));
|
||||
assertEquals(true,polConcave.intersects(multiPol));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultiPolygon3() {
|
||||
//MULTIPOLYGON(((-145.790967486 -5.17543698881, -145.790854979 -5.11348060995, -145.853073512 -5.11339421216, -145.853192037 -5.17535061936, -145.790967486 -5.17543698881)),
|
||||
//((-145.8563923 -5.17527125408, -145.856222168 -5.11332154814, -145.918433943 -5.11317773171, -145.918610092 -5.17512738429, -145.8563923 -5.17527125408)))
|
||||
GeoPolygon multiPol= getMultiPolygon();
|
||||
|
||||
//POLYGON((-146 -5.18, -145.854 -5.18, -145.854 -5.11, -146 -5.11, -146 -5.18))
|
||||
//Case overlapping one of the polygons so intersection is false!
|
||||
GeoPolygon polConvex = buildGeoPolygon(-146, -5.18,
|
||||
-145.854, -5.18,
|
||||
-145.854, -5.11,
|
||||
-146, -5.11,
|
||||
-146, -5.11);
|
||||
|
||||
GeoPolygon polConcave = buildConcaveGeoPolygon(-146, -5.18,
|
||||
-145.854, -5.18,
|
||||
-145.854, -5.11,
|
||||
-146, -5.11);
|
||||
|
||||
int rel = multiPol.getRelationship(polConvex);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
rel = polConvex.getRelationship(multiPol);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
assertEquals(false,multiPol.intersects(polConvex));
|
||||
assertEquals(false,polConvex.intersects(multiPol));
|
||||
|
||||
rel = multiPol.getRelationship(polConcave);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
rel = polConcave.getRelationship(multiPol);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
assertEquals(false,multiPol.intersects(polConcave));
|
||||
assertEquals(false,polConcave.intersects(multiPol));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultiPolygon4() {
|
||||
//MULTIPOLYGON(((-145.790967486 -5.17543698881, -145.790854979 -5.11348060995, -145.853073512 -5.11339421216, -145.853192037 -5.17535061936, -145.790967486 -5.17543698881)),
|
||||
//((-145.8563923 -5.17527125408, -145.856222168 -5.11332154814, -145.918433943 -5.11317773171, -145.918610092 -5.17512738429, -145.8563923 -5.17527125408)))
|
||||
GeoPolygon multiPol= getMultiPolygon();
|
||||
|
||||
//POLYGON((-145.88 -5.13, -145.87 -5.13, -145.87 -5.12, -145.88 -5.12, -145.88 -5.13))
|
||||
GeoPolygon polConvex = buildGeoPolygon(-145.88, -5.13,
|
||||
-145.87, -5.13,
|
||||
-145.87, -5.12,
|
||||
-145.88, -5.12,
|
||||
-145.88, -5.12);
|
||||
|
||||
GeoPolygon polConcave = buildConcaveGeoPolygon(-145.88, -5.13,
|
||||
-145.87, -5.13,
|
||||
-145.87, -5.12,
|
||||
-145.88, -5.12);
|
||||
|
||||
int rel = multiPol.getRelationship(polConvex);
|
||||
assertEquals(GeoArea.WITHIN, rel);
|
||||
rel = polConvex.getRelationship(multiPol);
|
||||
assertEquals(GeoArea.CONTAINS, rel);
|
||||
assertEquals(false,multiPol.intersects(polConvex));
|
||||
assertEquals(false,polConvex.intersects(multiPol));
|
||||
|
||||
rel = multiPol.getRelationship(polConcave);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
rel = polConcave.getRelationship(multiPol);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
assertEquals(false,multiPol.intersects(polConcave));
|
||||
assertEquals(false,polConcave.intersects(multiPol));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultiPolygon5() {
|
||||
//MULTIPOLYGON(((-145.790967486 -5.17543698881, -145.790854979 -5.11348060995, -145.853073512 -5.11339421216, -145.853192037 -5.17535061936, -145.790967486 -5.17543698881)),
|
||||
//((-145.8563923 -5.17527125408, -145.856222168 -5.11332154814, -145.918433943 -5.11317773171, -145.918610092 -5.17512738429, -145.8563923 -5.17527125408)))
|
||||
GeoPolygon multiPol= getMultiPolygon();
|
||||
|
||||
//POLYGON((-146 -5.18, -145 -5.18, -145 -5.11, -146 -5.11, -146 -5.18))
|
||||
GeoPolygon polConvex = buildGeoPolygon(-146, -5.18,
|
||||
-145, -5.18,
|
||||
-145, -5.11,
|
||||
-146, -5.11,
|
||||
-146, -5.11);
|
||||
|
||||
GeoPolygon polConcave = buildConcaveGeoPolygon(-146, -5.18,
|
||||
-145, -5.18,
|
||||
-145, -5.11,
|
||||
-146, -5.11);
|
||||
|
||||
int rel = multiPol.getRelationship(polConvex);
|
||||
assertEquals(GeoArea.CONTAINS, rel);
|
||||
rel = polConvex.getRelationship(multiPol);
|
||||
assertEquals(GeoArea.WITHIN, rel);
|
||||
assertEquals(false,multiPol.intersects(polConvex));
|
||||
|
||||
rel = multiPol.getRelationship(polConcave);
|
||||
assertEquals(GeoArea.DISJOINT, rel);
|
||||
rel = polConcave.getRelationship(multiPol);
|
||||
assertEquals(GeoArea.DISJOINT, rel);
|
||||
assertEquals(false,multiPol.intersects(polConcave));
|
||||
}
|
||||
|
||||
private GeoPolygon buildGeoPolygon(double lon1,double lat1,
|
||||
double lon2,double lat2,
|
||||
double lon3,double lat3,
|
||||
double lon4,double lat4,
|
||||
double lon5,double lat5)
|
||||
{
|
||||
GeoPoint point1 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(lat1), Math.toRadians(lon1));
|
||||
GeoPoint point2 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(lat2), Math.toRadians(lon2));
|
||||
GeoPoint point3 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(lat3), Math.toRadians(lon3));
|
||||
GeoPoint point4 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(lat4), Math.toRadians(lon4));
|
||||
GeoPoint point5 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(lat5), Math.toRadians(lon5));
|
||||
final List<GeoPoint> points = new ArrayList<>();
|
||||
points.add(point1);
|
||||
points.add(point2);
|
||||
points.add(point3);
|
||||
points.add(point4);
|
||||
points.add(point5);
|
||||
return GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points);
|
||||
}
|
||||
|
||||
private GeoPolygon buildConcaveGeoPolygon(double lon1,double lat1,
|
||||
double lon2,double lat2,
|
||||
double lon3,double lat3,
|
||||
double lon4,double lat4)
|
||||
{
|
||||
GeoPoint point1 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(lat1), Math.toRadians(lon1));
|
||||
GeoPoint point2 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(lat2), Math.toRadians(lon2));
|
||||
GeoPoint point3 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(lat3), Math.toRadians(lon3));
|
||||
GeoPoint point4 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(lat4), Math.toRadians(lon4));
|
||||
final List<GeoPoint> points = new ArrayList<>();
|
||||
points.add(point1);
|
||||
points.add(point2);
|
||||
points.add(point3);
|
||||
points.add(point4);
|
||||
return GeoPolygonFactory.makeGeoConcavePolygon(PlanetModel.SPHERE,points);
|
||||
}
|
||||
|
||||
private GeoPolygon getCompositePolygon(){
|
||||
//POLYGON((0 80, 45 85 ,90 80,135 85,180 80, -135 85, -90 80, -45 85,0 80))
|
||||
GeoPoint point1 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(80), Math.toRadians(0));
|
||||
GeoPoint point2 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(85), Math.toRadians(45));
|
||||
GeoPoint point3 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(80), Math.toRadians(90));
|
||||
GeoPoint point4 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(85), Math.toRadians(135));
|
||||
GeoPoint point5 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(80), Math.toRadians(180));
|
||||
GeoPoint point6 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(85), Math.toRadians(-135));
|
||||
GeoPoint point7 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(80), Math.toRadians(-90));
|
||||
GeoPoint point8 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(85), Math.toRadians(-45));
|
||||
final List<GeoPoint> points = new ArrayList<>();
|
||||
points.add(point1);
|
||||
points.add(point2);
|
||||
points.add(point3);
|
||||
points.add(point4);
|
||||
points.add(point5);
|
||||
points.add(point6);
|
||||
points.add(point7);
|
||||
points.add(point8);
|
||||
return GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points);
|
||||
}
|
||||
|
||||
private GeoPolygon getComplexPolygon(){
|
||||
//POLYGON((0 80, 45 85 ,90 80,135 85,180 80, -135 85, -90 80, -45 85,0 80))
|
||||
GeoPoint point1 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(80), Math.toRadians(0));
|
||||
GeoPoint point2 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(85), Math.toRadians(45));
|
||||
GeoPoint point3 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(80), Math.toRadians(90));
|
||||
GeoPoint point4 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(85), Math.toRadians(135));
|
||||
GeoPoint point5 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(80), Math.toRadians(180));
|
||||
GeoPoint point6 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(85), Math.toRadians(-135));
|
||||
GeoPoint point7 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(80), Math.toRadians(-90));
|
||||
GeoPoint point8 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(85), Math.toRadians(-45));
|
||||
final List<GeoPoint> points = new ArrayList<>();
|
||||
points.add(point1);
|
||||
points.add(point2);
|
||||
points.add(point3);
|
||||
points.add(point4);
|
||||
points.add(point5);
|
||||
points.add(point6);
|
||||
points.add(point7);
|
||||
points.add(point8);
|
||||
GeoPolygonFactory.PolygonDescription pd = new GeoPolygonFactory.PolygonDescription(points);
|
||||
return GeoPolygonFactory.makeLargeGeoPolygon(PlanetModel.SPHERE, Collections.singletonList(pd));
|
||||
}
|
||||
|
||||
private GeoPolygon getMultiPolygon(){
|
||||
//MULTIPOLYGON(((-145.790967486 -5.17543698881, -145.790854979 -5.11348060995, -145.853073512 -5.11339421216, -145.853192037 -5.17535061936, -145.790967486 -5.17543698881)),
|
||||
//((-145.8563923 -5.17527125408, -145.856222168 -5.11332154814, -145.918433943 -5.11317773171, -145.918610092 -5.17512738429, -145.8563923 -5.17527125408)))
|
||||
GeoPoint point1 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(-5.17543698881), Math.toRadians(-145.790967486));
|
||||
GeoPoint point2 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(-5.11348060995), Math.toRadians(-145.790854979));
|
||||
GeoPoint point3 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(-5.11339421216), Math.toRadians(-145.853073512));
|
||||
GeoPoint point4 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(-5.17535061936), Math.toRadians(-145.853192037));
|
||||
final List<GeoPoint> points1 = new ArrayList<>();
|
||||
points1.add(point1);
|
||||
points1.add(point2);
|
||||
points1.add(point3);
|
||||
points1.add(point4);
|
||||
GeoPolygonFactory.PolygonDescription pd1 = new GeoPolygonFactory.PolygonDescription(points1);
|
||||
GeoPoint point5 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(-5.17527125408), Math.toRadians(-145.8563923));
|
||||
GeoPoint point6 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(-5.11332154814), Math.toRadians(-145.856222168));
|
||||
GeoPoint point7 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(-5.11317773171), Math.toRadians(-145.918433943));
|
||||
GeoPoint point8 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(-5.17512738429), Math.toRadians(-145.918610092));
|
||||
final List<GeoPoint> points2 = new ArrayList<>();
|
||||
points2.add(point5);
|
||||
points2.add(point6);
|
||||
points2.add(point7);
|
||||
points2.add(point8);
|
||||
GeoPolygonFactory.PolygonDescription pd2 = new GeoPolygonFactory.PolygonDescription(points2);
|
||||
final List<GeoPolygonFactory.PolygonDescription> pds = new ArrayList<>();
|
||||
pds.add(pd1);
|
||||
pds.add(pd2);
|
||||
return GeoPolygonFactory.makeLargeGeoPolygon(PlanetModel.SPHERE, pds);
|
||||
}
|
||||
|
||||
public GeoShape getInsideCompositeShape(){
|
||||
//MULTIPOLYGON(((19.945091 -60.552631, 20.319948 -61.555652, 20.9 -61.5, 20.9 -61, 19.945091 -60.552631)),
|
||||
// ((21.1 -61.5, 23.107901 -61.253298, 22.720804 -60.457713,21.1 -61, 21.1 -61.5)))
|
||||
GeoPoint point1 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(-60.552631), Math.toRadians(19.945091));
|
||||
GeoPoint point2 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(-61.555652), Math.toRadians(20.319948));
|
||||
GeoPoint point3 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(-61.5), Math.toRadians(20.9));
|
||||
GeoPoint point4 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(-61), Math.toRadians(20.9));
|
||||
final List<GeoPoint> points1 = new ArrayList<>();
|
||||
points1.add(point1);
|
||||
points1.add(point2);
|
||||
points1.add(point3);
|
||||
points1.add(point4);
|
||||
GeoPoint point5 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(-61.5), Math.toRadians(21.1));
|
||||
GeoPoint point6 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(-61.253298), Math.toRadians(23.107901));
|
||||
GeoPoint point7 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(-60.457713), Math.toRadians(22.720804));
|
||||
GeoPoint point8 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(-61), Math.toRadians(21.1));
|
||||
final List<GeoPoint> points2 = new ArrayList<>();
|
||||
points2.add(point5);
|
||||
points2.add(point6);
|
||||
points2.add(point7);
|
||||
points2.add(point8);
|
||||
GeoPolygon p1 = GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points1);
|
||||
GeoPolygon p2 = GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points2);
|
||||
GeoCompositeMembershipShape compositeMembershipShape = new GeoCompositeMembershipShape();
|
||||
compositeMembershipShape.addShape(p1);
|
||||
compositeMembershipShape.addShape(p2);
|
||||
return compositeMembershipShape;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,944 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.lucene.util.LuceneTestCase;
|
||||
|
||||
import static com.carrotsearch.randomizedtesting.RandomizedTest.randomDouble;
|
||||
|
||||
/**
|
||||
* Class for generating random Geo3dShapes. They can be generated under
|
||||
* given constraints which are expressed as a shape and a relationship.
|
||||
*
|
||||
* note that convexity for polygons is defined as polygons that contains
|
||||
* antipodal points, otherwise they are convex. Internally they can be
|
||||
* created using GeoConvexPolygons and GeoConcavePolygons.
|
||||
*
|
||||
*/
|
||||
public class RandomGeoShapeGenerator extends LuceneTestCase {
|
||||
|
||||
/* Max num of iterations to find right shape under given constrains */
|
||||
final private static int MAX_SHAPE_ITERATIONS = 50;
|
||||
/* Max num of iterations to find right point under given constrains */
|
||||
final private static int MAX_POINT_ITERATIONS = 1000;
|
||||
|
||||
/* Supported shapes */
|
||||
final protected static int CONVEX_POLYGON = 0;
|
||||
final protected static int CONVEX_POLYGON_WITH_HOLES = 1;
|
||||
final protected static int CONCAVE_POLYGON = 2;
|
||||
final protected static int CONCAVE_POLYGON_WITH_HOLES = 3;
|
||||
final protected static int COMPLEX_POLYGON = 4;
|
||||
final protected static int CIRCLE = 5;
|
||||
final protected static int RECTANGLE = 6;
|
||||
final protected static int PATH = 7;
|
||||
final protected static int COLLECTION = 8;
|
||||
|
||||
/* Helper shapes for generating constraints whch are just three sided polygons */
|
||||
final protected static int CONVEX_SIMPLE_POLYGON = 500;
|
||||
final protected static int CONCAVE_SIMPLE_POLYGON = 501;
|
||||
|
||||
|
||||
/**
|
||||
* Method that returns empty Constraints object..
|
||||
*
|
||||
* @return an empty Constraints object
|
||||
*/
|
||||
public Constraints getEmptyConstraint(){
|
||||
return new Constraints();
|
||||
}
|
||||
|
||||
/**
|
||||
* Method that returns a random generated a random Shape code from all
|
||||
* supported shapes.
|
||||
*
|
||||
* @return a random generated shape code
|
||||
*/
|
||||
public int randomShapeType(){
|
||||
return random().nextInt(9);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method that returns a random generated a random Shape code from all
|
||||
* convex supported shapes.
|
||||
*
|
||||
* @return a random generated convex shape code
|
||||
*/
|
||||
public int randomConvexShapeType(){
|
||||
int shapeType = randomShapeType();
|
||||
while (isConcave(shapeType)){
|
||||
shapeType = randomShapeType();
|
||||
}
|
||||
return shapeType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method that returns a random generated a random Shape code from all
|
||||
* concave supported shapes.
|
||||
*
|
||||
* @return a random generated concave shape code
|
||||
*/
|
||||
public int randomConcaveShapeType(){
|
||||
int shapeType = randomShapeType();
|
||||
while (!isConcave(shapeType)){
|
||||
shapeType = randomShapeType();
|
||||
}
|
||||
return shapeType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method that returns a random generated GeoAreaShape code from all
|
||||
* supported GeoAreaShapes.
|
||||
*
|
||||
* We are removing Collections because it is difficult to create shapes
|
||||
* with properties in some cases.
|
||||
*
|
||||
* @return a random generated polygon code
|
||||
*/
|
||||
public int randomGeoAreaShapeType(){
|
||||
return random().nextInt(8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a shape code represents a concave shape
|
||||
*
|
||||
* @return true if the shape represented by the code is concave
|
||||
*/
|
||||
public boolean isConcave(int shapeType){
|
||||
return (shapeType == CONCAVE_POLYGON);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method that returns a random generated Planet model from the supported
|
||||
* Planet models. currently SPHERE and WGS84
|
||||
*
|
||||
* @return a random generated Planet model
|
||||
*/
|
||||
public PlanetModel randomPlanetModel() {
|
||||
final int shapeType = random().nextInt(2);
|
||||
switch (shapeType) {
|
||||
case 0: {
|
||||
return PlanetModel.SPHERE;
|
||||
}
|
||||
case 1: {
|
||||
return PlanetModel.WGS84;
|
||||
}
|
||||
default:
|
||||
throw new IllegalStateException("Unexpected planet model");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method that returns a random generated GeoPoint under given constraints. Returns
|
||||
* NULL if it cannot find a point under the given constraints.
|
||||
*
|
||||
* @param planetModel The planet model.
|
||||
* @param constraints The given constraints.
|
||||
* @return The random generated GeoPoint.
|
||||
*/
|
||||
public GeoPoint randomGeoPoint(PlanetModel planetModel, Constraints constraints) {
|
||||
int iterations = 0;
|
||||
while (iterations < MAX_POINT_ITERATIONS) {
|
||||
double lat = randomDouble();
|
||||
if (Math.PI/2 - Math.abs(lat) <0){
|
||||
continue;
|
||||
}
|
||||
double lon = randomDouble();
|
||||
if (Math.PI - Math.abs(lat) <0){
|
||||
continue;
|
||||
}
|
||||
iterations++;
|
||||
GeoPoint point = new GeoPoint(planetModel, lat, lon);
|
||||
if (constraints.isWithin(point)) {
|
||||
return point;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method that returns a random generated GeoAreaShape.
|
||||
*
|
||||
* @param shapeType The GeoAreaShape code.
|
||||
* @param planetModel The planet model.
|
||||
* @return The random generated GeoAreaShape.
|
||||
*/
|
||||
public GeoAreaShape randomGeoAreaShape(int shapeType, PlanetModel planetModel){
|
||||
GeoAreaShape geoAreaShape = null;
|
||||
while (geoAreaShape == null){
|
||||
geoAreaShape = randomGeoAreaShape(shapeType,planetModel,new Constraints());
|
||||
}
|
||||
return geoAreaShape;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method that returns a random generated GeoAreaShape under given constraints. Returns
|
||||
* NULL if it cannot build the GeoAreaShape under the given constraints.
|
||||
*
|
||||
* @param shapeType The GeoAreaShape code.
|
||||
* @param planetModel The planet model.
|
||||
* @param constraints The given constraints.
|
||||
* @return The random generated GeoAreaShape.
|
||||
*/
|
||||
public GeoAreaShape randomGeoAreaShape(int shapeType, PlanetModel planetModel, Constraints constraints){
|
||||
return (GeoAreaShape)randomGeoShape(shapeType, planetModel, constraints);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method that returns a random generated GeoShape.
|
||||
*
|
||||
* @param shapeType The shape code.
|
||||
* @param planetModel The planet model.
|
||||
* @return The random generated GeoShape.
|
||||
*/
|
||||
public GeoShape randomGeoShape(int shapeType, PlanetModel planetModel){
|
||||
GeoShape geoShape = null;
|
||||
while (geoShape == null){
|
||||
geoShape = randomGeoShape(shapeType,planetModel,new Constraints());
|
||||
}
|
||||
return geoShape;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method that returns a random generated GeoShape under given constraints. Returns
|
||||
* NULL if it cannot build the GeoShape under the given constraints.
|
||||
*
|
||||
* @param shapeType The polygon code.
|
||||
* @param planetModel The planet model.
|
||||
* @param constraints The given constraints.
|
||||
* @return The random generated GeoShape.
|
||||
*/
|
||||
public GeoShape randomGeoShape(int shapeType, PlanetModel planetModel, Constraints constraints){
|
||||
switch (shapeType) {
|
||||
case CONVEX_POLYGON: {
|
||||
return convexPolygon(planetModel, constraints);
|
||||
}
|
||||
case CONVEX_POLYGON_WITH_HOLES: {
|
||||
return convexPolygonWithHoles(planetModel, constraints);
|
||||
}
|
||||
case CONCAVE_POLYGON: {
|
||||
return concavePolygon(planetModel, constraints);
|
||||
}
|
||||
case CONCAVE_POLYGON_WITH_HOLES: {
|
||||
return concavePolygonWithHoles(planetModel, constraints);
|
||||
}
|
||||
case COMPLEX_POLYGON: {
|
||||
return complexPolygon(planetModel, constraints);
|
||||
}
|
||||
case CIRCLE: {
|
||||
return circle(planetModel, constraints);
|
||||
}
|
||||
case RECTANGLE: {
|
||||
return rectangle(planetModel, constraints);
|
||||
}
|
||||
case PATH: {
|
||||
return path(planetModel, constraints);
|
||||
}
|
||||
case COLLECTION: {
|
||||
return collection(planetModel, constraints);
|
||||
}
|
||||
case CONVEX_SIMPLE_POLYGON: {
|
||||
return simpleConvexPolygon(planetModel, constraints);
|
||||
}
|
||||
case CONCAVE_SIMPLE_POLYGON: {
|
||||
return concaveSimplePolygon(planetModel, constraints);
|
||||
}
|
||||
default:
|
||||
throw new IllegalStateException("Unexpected shape type");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method that returns a random generated a GeoCircle under given constraints. Returns
|
||||
* NULL if it cannot build the GeoCircle under the given constraints.
|
||||
*
|
||||
* @param planetModel The planet model.
|
||||
* @param constraints The given constraints.
|
||||
* @return The random generated GeoCircle.
|
||||
*/
|
||||
private GeoCircle circle(PlanetModel planetModel , Constraints constraints) {
|
||||
int iterations=0;
|
||||
while (iterations < MAX_SHAPE_ITERATIONS) {
|
||||
iterations++;
|
||||
final GeoPoint center = randomGeoPoint(planetModel, constraints);
|
||||
if (center == null){
|
||||
continue;
|
||||
}
|
||||
final double radius = randomCutoffAngle();
|
||||
try {
|
||||
|
||||
GeoCircle circle = GeoCircleFactory.makeGeoCircle(planetModel, center.getLatitude(), center.getLongitude(), radius);
|
||||
if (!constraints.valid(circle)) {
|
||||
continue;
|
||||
}
|
||||
return circle;
|
||||
} catch (IllegalArgumentException e) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method that returns a random generated a GeoBBox under given constraints. Returns
|
||||
* NULL if it cannot build the GeoBBox under the given constraints.
|
||||
*
|
||||
* @param planetModel The planet model.
|
||||
* @param constraints The given constraints.
|
||||
* @return The random generated GeoBBox.
|
||||
*/
|
||||
private GeoBBox rectangle(PlanetModel planetModel, Constraints constraints) {
|
||||
|
||||
int iterations = 0;
|
||||
while (iterations < MAX_SHAPE_ITERATIONS) {
|
||||
iterations++;
|
||||
final GeoPoint point1 = randomGeoPoint(planetModel, constraints);
|
||||
if (point1 == null){
|
||||
continue;
|
||||
}
|
||||
final GeoPoint point2 = randomGeoPoint(planetModel, constraints);
|
||||
if (point2 == null){
|
||||
continue;
|
||||
}
|
||||
|
||||
double minLat = Math.min(point1.getLatitude(), point2.getLatitude());
|
||||
double maxLat = Math.max(point1.getLatitude(), point2.getLatitude());
|
||||
double minLon = Math.min(point1.getLongitude(), point2.getLongitude());
|
||||
double maxLon = Math.max(point1.getLongitude(), point2.getLongitude());
|
||||
|
||||
try {
|
||||
GeoBBox bbox = GeoBBoxFactory.makeGeoBBox(planetModel, maxLat, minLat, minLon, maxLon);
|
||||
if (!constraints.valid(bbox)) {
|
||||
continue;
|
||||
}
|
||||
return bbox;
|
||||
} catch (IllegalArgumentException e) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method that returns a random generated a GeoPath under given constraints. Returns
|
||||
* NULL if it cannot build the GeoPath under the given constraints.
|
||||
*
|
||||
* @param planetModel The planet model.
|
||||
* @param constraints The given constraints.
|
||||
* @return The random generated GeoPath.
|
||||
*/
|
||||
private GeoPath path(PlanetModel planetModel, Constraints constraints) {
|
||||
int iterations = 0;
|
||||
while (iterations < MAX_SHAPE_ITERATIONS) {
|
||||
iterations++;
|
||||
int vertexCount = random().nextInt(2) + 2;
|
||||
List<GeoPoint> geoPoints = points(vertexCount, planetModel, constraints);
|
||||
double width =randomCutoffAngle();
|
||||
try {
|
||||
GeoPath path = GeoPathFactory.makeGeoPath(planetModel, width, geoPoints.toArray(new GeoPoint[geoPoints.size()]));
|
||||
if (!constraints.valid(path)) {
|
||||
continue;
|
||||
}
|
||||
return path;
|
||||
} catch (IllegalArgumentException e) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method that returns a random generated a GeoCompositeMembershipShape under given constraints. Returns
|
||||
* NULL if it cannot build the GGeoCompositeMembershipShape under the given constraints.
|
||||
*
|
||||
* @param planetModel The planet model.
|
||||
* @param constraints The given constraints.
|
||||
* @return The random generated GeoCompositeMembershipShape.
|
||||
*/
|
||||
private GeoCompositeAreaShape collection(PlanetModel planetModel, Constraints constraints) {
|
||||
int iterations = 0;
|
||||
while (iterations < MAX_SHAPE_ITERATIONS) {
|
||||
iterations++;
|
||||
int numberShapes = random().nextInt(3) + 2;
|
||||
GeoCompositeAreaShape collection = new GeoCompositeAreaShape();
|
||||
for(int i=0; i<numberShapes;i++){
|
||||
GeoPolygon member = convexPolygon(planetModel, constraints);
|
||||
if (member != null){
|
||||
collection.addShape(member);
|
||||
}
|
||||
}
|
||||
if (collection.shapes.size() ==0){
|
||||
continue;
|
||||
}
|
||||
return collection;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method that returns a random generated a convex GeoPolygon under given constraints. Returns
|
||||
* NULL if it cannot build the GePolygon under the given constraints.
|
||||
*
|
||||
* @param planetModel The planet model.
|
||||
* @param constraints The given constraints.
|
||||
* @return The random generated GeoPolygon.
|
||||
*/
|
||||
private GeoPolygon convexPolygon(PlanetModel planetModel, Constraints constraints) {
|
||||
int vertexCount = random().nextInt(4) + 3;
|
||||
int iterations = 0;
|
||||
while (iterations < MAX_SHAPE_ITERATIONS) {
|
||||
iterations++;
|
||||
List<GeoPoint> geoPoints = points(vertexCount,planetModel, constraints);
|
||||
List<GeoPoint> orderedGeoPoints = orderPoints(geoPoints);
|
||||
try {
|
||||
GeoPolygon polygon = GeoPolygonFactory.makeGeoPolygon(planetModel, orderedGeoPoints);
|
||||
if (!constraints.valid(polygon) || isConcave(planetModel, polygon)) {
|
||||
continue;
|
||||
}
|
||||
return polygon;
|
||||
} catch (IllegalArgumentException e) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method that returns a random generated a convex GeoPolygon with holes under given constraints. Returns
|
||||
* NULL if it cannot build the GeoPolygon with holes under the given constraints.
|
||||
*
|
||||
* @param planetModel The planet model.
|
||||
* @param constraints The given constraints.
|
||||
* @return The random generated GeoPolygon.
|
||||
*/
|
||||
private GeoPolygon convexPolygonWithHoles(PlanetModel planetModel, Constraints constraints) {
|
||||
int vertexCount = random().nextInt(4) + 3;
|
||||
int iterations = 0;
|
||||
while (iterations < MAX_SHAPE_ITERATIONS) {
|
||||
iterations++;
|
||||
List<GeoPoint> geoPoints = points(vertexCount,planetModel, constraints);
|
||||
List<GeoPoint> orderedGeoPoints = orderPoints(geoPoints);
|
||||
try {
|
||||
GeoPolygon polygon = GeoPolygonFactory.makeGeoPolygon(planetModel, orderedGeoPoints);
|
||||
//polygon should comply with all constraints except disjoint as we have holes
|
||||
Constraints polygonConstraints = new Constraints();
|
||||
polygonConstraints.putAll(constraints.getContains());
|
||||
polygonConstraints.putAll(constraints.getWithin());
|
||||
polygonConstraints.putAll(constraints.getDisjoint());
|
||||
if (!polygonConstraints.valid(polygon) || isConcave(planetModel, polygon)){
|
||||
continue;
|
||||
}
|
||||
//hole must overlap with polygon and comply with any CONTAINS constraint.
|
||||
Constraints holeConstraints = new Constraints();
|
||||
holeConstraints.putAll(constraints.getContains());
|
||||
holeConstraints.put(polygon,GeoArea.OVERLAPS);
|
||||
//Points must be with in the polygon and must comply
|
||||
// CONTAINS and DISJOINT constraints
|
||||
Constraints pointsConstraints = new Constraints();
|
||||
pointsConstraints.put(polygon,GeoArea.WITHIN);
|
||||
pointsConstraints.putAll(constraints.getContains());
|
||||
pointsConstraints.putAll(constraints.getDisjoint());
|
||||
List<GeoPolygon> holes = concavePolygonHoles(planetModel, holeConstraints, pointsConstraints);
|
||||
//we should have at least one hole
|
||||
if (holes.size() == 0){
|
||||
continue;
|
||||
}
|
||||
polygon = GeoPolygonFactory.makeGeoPolygon(planetModel,orderedGeoPoints,holes);
|
||||
if (!constraints.valid(polygon) || isConcave(planetModel, polygon)){
|
||||
continue;
|
||||
}
|
||||
return polygon;
|
||||
} catch (IllegalArgumentException e) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method that returns a random list if concave GeoPolygons under given constraints. Method
|
||||
* use to generate convex holes. Note that constraints for points and holes are different,
|
||||
*
|
||||
* @param planetModel The planet model.
|
||||
* @param holeConstraints The given constraints that a hole must comply.
|
||||
* @param pointConstraints The given constraints that a point must comply.
|
||||
* @return The random generated GeoPolygon.
|
||||
*/
|
||||
private List<GeoPolygon> concavePolygonHoles(PlanetModel planetModel,
|
||||
Constraints holeConstraints,
|
||||
Constraints pointConstraints) {
|
||||
int iterations =0;
|
||||
int holesCount = random().nextInt(3) + 1;
|
||||
List<GeoPolygon> holes = new ArrayList<>();
|
||||
while (iterations < MAX_SHAPE_ITERATIONS) {
|
||||
iterations++;
|
||||
int vertexCount = random().nextInt(3) + 3;
|
||||
List<GeoPoint> geoPoints = points(vertexCount, planetModel, pointConstraints);
|
||||
geoPoints = orderPoints(geoPoints);
|
||||
Collections.reverse(geoPoints);
|
||||
try {
|
||||
GeoPolygon hole = GeoPolygonFactory.makeGeoPolygon(planetModel, geoPoints);
|
||||
if (!holeConstraints.valid(hole) || isConvex(planetModel, hole)) {
|
||||
continue;
|
||||
}
|
||||
holes.add(hole);
|
||||
if (holes.size() == holesCount){
|
||||
return holes;
|
||||
}
|
||||
pointConstraints.put(hole, GeoArea.DISJOINT);
|
||||
} catch (IllegalArgumentException e) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return holes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method that returns a random generated a concave GeoPolygon under given constraints. Returns
|
||||
* NULL if it cannot build the concave GeoPolygon under the given constraints.
|
||||
*
|
||||
* @param planetModel The planet model.
|
||||
* @param constraints The given constraints.
|
||||
* @return The random generated GeoPolygon.
|
||||
*/
|
||||
private GeoPolygon concavePolygon(PlanetModel planetModel, Constraints constraints) {
|
||||
|
||||
int vertexCount = random().nextInt(4) + 3;
|
||||
int iterations = 0;
|
||||
while (iterations < MAX_SHAPE_ITERATIONS) {
|
||||
iterations++;
|
||||
List<GeoPoint> geoPoints = points(vertexCount,planetModel, constraints);
|
||||
List<GeoPoint> orderedGeoPoints = orderPoints(geoPoints);
|
||||
Collections.reverse(orderedGeoPoints);
|
||||
try {
|
||||
GeoPolygon polygon = GeoPolygonFactory.makeGeoPolygon(planetModel, orderedGeoPoints);
|
||||
if (!constraints.valid(polygon) || isConvex(planetModel, polygon)) {
|
||||
continue;
|
||||
}
|
||||
return polygon;
|
||||
} catch (IllegalArgumentException e) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method that returns a random generated a concave GeoPolygon with holes under given constraints. Returns
|
||||
* NULL if it cannot build the GeoPolygon under the given constraints. Note that the final GeoPolygon is
|
||||
* convex as the hole wraps the convex GeoPolygon.
|
||||
*
|
||||
* @param planetModel The planet model.
|
||||
* @param constraints The given constraints.
|
||||
* @return The random generated GeoPolygon.
|
||||
*/
|
||||
private GeoPolygon concavePolygonWithHoles(PlanetModel planetModel, Constraints constraints) {
|
||||
int vertexCount = random().nextInt(4) + 3;
|
||||
int iterations = 0;
|
||||
while (iterations < MAX_SHAPE_ITERATIONS) {
|
||||
iterations++;
|
||||
//we first build the hole. We consider all constraints except
|
||||
// disjoint as we have a hole
|
||||
Constraints holeConstraints = new Constraints();
|
||||
holeConstraints.putAll(constraints.getContains());
|
||||
holeConstraints.putAll(constraints.getWithin());
|
||||
holeConstraints.putAll(constraints.getOverlaps());
|
||||
GeoPolygon hole = convexPolygon(planetModel, holeConstraints);
|
||||
if (hole == null){
|
||||
continue;
|
||||
}
|
||||
// Now we get points for polygon. Must we with in the hole
|
||||
// and we add contain constraints
|
||||
Constraints pointConstraints = new Constraints();
|
||||
pointConstraints.put(hole, GeoArea.WITHIN);
|
||||
pointConstraints.putAll(constraints.getContains());
|
||||
List<GeoPoint> geoPoints = points(vertexCount,planetModel, pointConstraints);
|
||||
List<GeoPoint> orderedGeoPoints = orderPoints(geoPoints);
|
||||
Collections.reverse(orderedGeoPoints);
|
||||
try {
|
||||
GeoPolygon polygon = GeoPolygonFactory.makeGeoPolygon(planetModel, orderedGeoPoints, Collections.singletonList(hole));
|
||||
//final polygon must be convex
|
||||
if (!constraints.valid(polygon) || isConcave(planetModel,polygon)) {
|
||||
continue;
|
||||
}
|
||||
return polygon;
|
||||
} catch (IllegalArgumentException e) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method that returns a random generated complex GeoPolygon under given constraints. Returns
|
||||
* NULL if it cannot build the complex GeoPolygon under the given constraints.
|
||||
*
|
||||
* @param planetModel The planet model.
|
||||
* @param constraints The given constraints.
|
||||
* @return The random generated GeoPolygon.
|
||||
*/
|
||||
private GeoPolygon complexPolygon(PlanetModel planetModel, Constraints constraints) {
|
||||
int polygonsCount =random().nextInt(2) + 1;
|
||||
int iterations = 0;
|
||||
while (iterations < MAX_SHAPE_ITERATIONS) {
|
||||
iterations++;
|
||||
List<GeoPolygonFactory.PolygonDescription> polDescription = new ArrayList<>();
|
||||
while(polDescription.size() < polygonsCount){
|
||||
int vertexCount = random().nextInt(14) + 3;
|
||||
List<GeoPoint> geoPoints = points(vertexCount,planetModel, constraints);
|
||||
orderPoints(geoPoints);
|
||||
polDescription.add(new GeoPolygonFactory.PolygonDescription(geoPoints));
|
||||
}
|
||||
try {
|
||||
GeoPolygon polygon = GeoPolygonFactory.makeLargeGeoPolygon(planetModel,polDescription);
|
||||
if (!constraints.valid(polygon)) {
|
||||
continue;
|
||||
}
|
||||
return polygon;
|
||||
} catch (IllegalArgumentException e) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method that returns a random generated a concave square GeoPolygon under given constraints. Returns
|
||||
* NULL if it cannot build the concave GeoPolygon under the given constraints. This shape is an utility
|
||||
* to build constraints.
|
||||
*
|
||||
* @param planetModel The planet model.
|
||||
* @param constraints The given constraints.
|
||||
* @return The random generated GeoPolygon.
|
||||
*/
|
||||
private GeoPolygon simpleConvexPolygon(PlanetModel planetModel, Constraints constraints) {
|
||||
int iterations = 0;
|
||||
while (iterations < MAX_SHAPE_ITERATIONS) {
|
||||
iterations++;
|
||||
List<GeoPoint> points = points(3,planetModel,constraints);
|
||||
points = orderPoints(points);
|
||||
try {
|
||||
GeoPolygon polygon = GeoPolygonFactory.makeGeoConvexPolygon(planetModel, points);
|
||||
if(!constraints.valid(polygon) || isConcave(planetModel,polygon)){
|
||||
continue;
|
||||
}
|
||||
return polygon;
|
||||
} catch (IllegalArgumentException e) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method that returns a random generated a convex square GeoPolygon under given constraints. Returns
|
||||
* NULL if it cannot build the convex GeoPolygon under the given constraints. This shape is an utility
|
||||
* to build constraints.
|
||||
*
|
||||
* @param planetModel The planet model.
|
||||
* @param constraints The given constraints.
|
||||
* @return The random generated GeoPolygon.
|
||||
*/
|
||||
private GeoPolygon concaveSimplePolygon(PlanetModel planetModel, Constraints constraints) {
|
||||
int iterations = 0;
|
||||
while (iterations < MAX_SHAPE_ITERATIONS) {
|
||||
iterations++;
|
||||
List<GeoPoint> points = points(3, planetModel, constraints);
|
||||
points = orderPoints(points);
|
||||
Collections.reverse(points);
|
||||
try {
|
||||
GeoPolygon polygon = GeoPolygonFactory.makeGeoConcavePolygon(planetModel, points);
|
||||
if(!constraints.valid(polygon) || isConvex(planetModel, polygon)){
|
||||
continue;
|
||||
}
|
||||
return polygon;
|
||||
} catch (IllegalArgumentException e) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method that returns a random list of generated GeoPoints under given constraints. If it cannot
|
||||
* find a point it will add a point that might not comply with the constraints.
|
||||
*
|
||||
* @param count The number of points
|
||||
* @param planetModel The planet model.
|
||||
* @param constraints The given constraints.
|
||||
* @return The random generated List of GeoPoints.
|
||||
*/
|
||||
private List<GeoPoint> points(int count, PlanetModel planetModel, Constraints constraints){
|
||||
List<GeoPoint> geoPoints = new ArrayList<>(count);
|
||||
for(int i= 0; i< count; i++) {
|
||||
GeoPoint point = randomGeoPoint(planetModel, constraints);
|
||||
if (point == null){
|
||||
point = randomGeoPoint(planetModel, new Constraints());
|
||||
}
|
||||
geoPoints.add(point);
|
||||
}
|
||||
return geoPoints;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a GeoPolygon is pure concave. Note that our definition for concavity is that the polygon
|
||||
* contains antipodal points.
|
||||
*
|
||||
* @param planetModel The planet model.
|
||||
* @param shape The polygon to check.
|
||||
* @return True if the polygon contains antipodal points.
|
||||
*/
|
||||
private boolean isConcave(PlanetModel planetModel, GeoPolygon shape){
|
||||
return (shape.isWithin(planetModel.NORTH_POLE) && shape.isWithin(planetModel.SOUTH_POLE))||
|
||||
(shape.isWithin(planetModel.MAX_X_POLE) && shape.isWithin(planetModel.MIN_X_POLE)) ||
|
||||
(shape.isWithin(planetModel.MAX_Y_POLE) && shape.isWithin(planetModel.MIN_Y_POLE));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a GeoPolygon is pure convex. Note that our definition for convexity is that the polygon
|
||||
* does not contain antipodal points.
|
||||
*
|
||||
* @param planetModel The planet model.
|
||||
* @param shape The polygon to check.
|
||||
* @return True if the polygon dies not contains antipodal points.
|
||||
*/
|
||||
private boolean isConvex(PlanetModel planetModel, GeoPolygon shape){
|
||||
return !isConcave(planetModel,shape);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a random number between 0 and PI.
|
||||
*
|
||||
* @return the cutoff angle.
|
||||
*/
|
||||
private double randomCutoffAngle() {
|
||||
while(true) {
|
||||
double radius = randomDouble();
|
||||
if (radius <0 || radius > Math.PI){
|
||||
continue;
|
||||
}
|
||||
return radius;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method that orders a lit of points anti-clock-wise to prevent crossing edges.
|
||||
*
|
||||
* @param originalPoints The points to order.
|
||||
* @return The list of ordered points anti-clockwise.
|
||||
*/
|
||||
private List<GeoPoint> orderPoints(List<GeoPoint> originalPoints){
|
||||
List<GeoPoint> points = new ArrayList<>(originalPoints.size());
|
||||
points.addAll(originalPoints); //make a copy
|
||||
GeoPoint lPoint = getPointLefLon(points);
|
||||
points.remove(lPoint);
|
||||
GeoPoint rPoint = getPointRigthLon(points);
|
||||
points.remove(rPoint);
|
||||
List<GeoPoint> APoints = getPointsBelowAndSort(points, lPoint);
|
||||
List<GeoPoint> BPoints = getPointsAboveAndsort(points, lPoint);
|
||||
List<GeoPoint> result = new ArrayList<>();
|
||||
result.add(lPoint);
|
||||
result.addAll(APoints);
|
||||
result.add(rPoint);
|
||||
result.addAll(BPoints);
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<GeoPoint> getPointsAboveAndsort(List<GeoPoint> points,GeoPoint lPoint) {
|
||||
List<GeoPoint> BPoints = new ArrayList<>();
|
||||
for (GeoPoint point : points){
|
||||
if(point.getLatitude() > lPoint.getLatitude()){
|
||||
BPoints.add(point);
|
||||
}
|
||||
}
|
||||
Collections.sort(BPoints, new Comparator<GeoPoint>() {
|
||||
public int compare(GeoPoint idx1, GeoPoint idx2) {
|
||||
return Double.compare(idx1.getLongitude(), idx2.getLongitude());
|
||||
}
|
||||
});
|
||||
return BPoints;
|
||||
}
|
||||
|
||||
private List<GeoPoint> getPointsBelowAndSort(List<GeoPoint> points,GeoPoint lPoint) {
|
||||
List<GeoPoint> APoints = new ArrayList<>();
|
||||
for (GeoPoint point : points){
|
||||
if(point.getLatitude() < lPoint.getLatitude()){
|
||||
APoints.add(point);
|
||||
}
|
||||
}
|
||||
Collections.sort(APoints, new Comparator<GeoPoint>() {
|
||||
public int compare(GeoPoint idx1, GeoPoint idx2) {
|
||||
return Double.compare(idx1.getLongitude(), idx2.getLongitude());
|
||||
}
|
||||
});
|
||||
return APoints;
|
||||
}
|
||||
|
||||
private GeoPoint getPointLefLon(List<GeoPoint> points) {
|
||||
GeoPoint lPoint = null;
|
||||
for (GeoPoint point : points){
|
||||
if(lPoint == null ){
|
||||
lPoint = point;
|
||||
}
|
||||
else{
|
||||
if (lPoint.getLongitude() > point.getLongitude()){
|
||||
lPoint = point;
|
||||
}
|
||||
}
|
||||
}
|
||||
return lPoint;
|
||||
}
|
||||
|
||||
private GeoPoint getPointRigthLon(List<GeoPoint> points) {
|
||||
GeoPoint rPoint = null;
|
||||
for (GeoPoint point : points){
|
||||
if(rPoint == null ){
|
||||
rPoint = point;
|
||||
}
|
||||
else{
|
||||
if (rPoint.getLongitude() < point.getLongitude()){
|
||||
rPoint = point;
|
||||
}
|
||||
}
|
||||
}
|
||||
return rPoint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Class that holds the constraints that are given to
|
||||
* build shapes. It consists in a list of GeoAreaShapes
|
||||
* and relationships the new shape needs to satisfy.
|
||||
*/
|
||||
class Constraints extends HashMap<GeoAreaShape, Integer>{
|
||||
|
||||
/**
|
||||
* Check if the shape is valid under the constraints.
|
||||
*
|
||||
* @param shape The shape to check
|
||||
* @return true if the shape satisfy the constraints, else false.
|
||||
*/
|
||||
public boolean valid(GeoShape shape) {
|
||||
if (shape == null){
|
||||
return false;
|
||||
}
|
||||
for (GeoAreaShape constraint : keySet()) {
|
||||
if (constraint.getRelationship(shape) != get(constraint)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a point is Within the constraints.
|
||||
*
|
||||
* @param point The point to check
|
||||
* @return true if the point satisfy the constraints, else false.
|
||||
*/
|
||||
public boolean isWithin(GeoPoint point) {
|
||||
for (GeoShape constraint : keySet()) {
|
||||
if (!(validPoint(point, constraint, get(constraint)))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a point is Within one constraint given by a shape and a relationship.
|
||||
*
|
||||
* @param point The point to check
|
||||
* @param shape The shape of the constraint
|
||||
* @param relationship The relationship of the constraint.
|
||||
* @return true if the point satisfy the constraint, else false.
|
||||
*/
|
||||
private boolean validPoint(GeoPoint point, GeoShape shape, int relationship) {
|
||||
//For GeoCompositeMembershipShape we only consider the first shape to help
|
||||
// converging
|
||||
if (relationship == GeoArea.WITHIN && shape instanceof GeoCompositeMembershipShape) {
|
||||
shape = (((GeoCompositeMembershipShape) shape).shapes.get(0));
|
||||
}
|
||||
switch (relationship) {
|
||||
case GeoArea.DISJOINT:
|
||||
return !shape.isWithin(point);
|
||||
case GeoArea.OVERLAPS:
|
||||
return true;
|
||||
case GeoArea.CONTAINS:
|
||||
return !shape.isWithin(point);
|
||||
case GeoArea.WITHIN:
|
||||
return shape.isWithin(point);
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect the CONTAINS constraints in the object
|
||||
*
|
||||
* @return the CONTAINS constraints.
|
||||
*/
|
||||
public Constraints getContains(){
|
||||
return getConstraintsOfType(GeoArea.CONTAINS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect the WITHIN constraints in the object
|
||||
*
|
||||
* @return the WITHIN constraints.
|
||||
*/
|
||||
public Constraints getWithin(){
|
||||
return getConstraintsOfType(GeoArea.WITHIN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect the OVERLAPS constraints in the object
|
||||
*
|
||||
* @return the OVERLAPS constraints.
|
||||
*/
|
||||
public Constraints getOverlaps(){
|
||||
return getConstraintsOfType(GeoArea.OVERLAPS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect the DISJOINT constraints in the object
|
||||
*
|
||||
* @return the DISJOINT constraints.
|
||||
*/
|
||||
public Constraints getDisjoint(){
|
||||
return getConstraintsOfType(GeoArea.DISJOINT);
|
||||
}
|
||||
|
||||
private Constraints getConstraintsOfType(int type){
|
||||
Constraints constraints = new Constraints();
|
||||
for (GeoAreaShape constraint : keySet()) {
|
||||
if (type == get(constraint)) {
|
||||
constraints.put(constraint, type);
|
||||
}
|
||||
}
|
||||
return constraints;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,240 @@
|
|||
package org.apache.lucene.spatial3d.geom;
|
||||
|
||||
import com.carrotsearch.randomizedtesting.annotations.Repeat;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Random test to check relationship between GeoAreaShapes and GeoShapes.
|
||||
*/
|
||||
public class RandomGeoShapeRelationshipTest extends RandomGeoShapeGenerator {
|
||||
|
||||
|
||||
/**
|
||||
* Test for WITHIN points. We build a WITHIN shape with respect the geoAreaShape
|
||||
* and create a point WITHIN the shape. The resulting shape should be WITHIN
|
||||
* the original shape.
|
||||
*
|
||||
*/
|
||||
@Test
|
||||
@Repeat(iterations = 5)
|
||||
public void testRandomPointWithin() {
|
||||
int referenceShapeType = CONVEX_POLYGON;
|
||||
PlanetModel planetModel = randomPlanetModel();
|
||||
int shapeType = randomShapeType();
|
||||
GeoAreaShape shape = null;
|
||||
GeoPoint point = null;
|
||||
while (point == null) {
|
||||
shape = randomGeoAreaShape(shapeType, planetModel);
|
||||
Constraints constraints = getEmptyConstraint();
|
||||
constraints.put(shape, GeoArea.WITHIN);
|
||||
GeoAreaShape reference = randomGeoAreaShape(referenceShapeType, planetModel, constraints);
|
||||
if (reference != null) {
|
||||
constraints = new Constraints();
|
||||
constraints.put(reference, GeoArea.WITHIN);
|
||||
point = randomGeoPoint(planetModel, constraints);
|
||||
}
|
||||
}
|
||||
assertTrue(shape.isWithin(point));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for NOT WITHIN points. We build a DIJOINT shape with respect the geoAreaShape
|
||||
* and create a point WITHIN that shape. The resulting shape should not be WITHIN
|
||||
* the original shape.
|
||||
*
|
||||
*/
|
||||
@Repeat(iterations = 5)
|
||||
public void testRandomPointNotWithin() {
|
||||
int referenceShapeType = CONVEX_POLYGON;
|
||||
PlanetModel planetModel = randomPlanetModel();
|
||||
int shapeType = randomShapeType();
|
||||
GeoAreaShape shape = null;
|
||||
GeoPoint point = null;
|
||||
while (point == null) {
|
||||
shape = randomGeoAreaShape(shapeType, planetModel);
|
||||
Constraints constraints = getEmptyConstraint();
|
||||
constraints.put(shape, GeoArea.DISJOINT);
|
||||
GeoAreaShape reference = randomGeoAreaShape(referenceShapeType, planetModel, constraints);
|
||||
if (reference != null) {
|
||||
constraints = new Constraints();
|
||||
constraints.put(reference, GeoArea.WITHIN);
|
||||
point = randomGeoPoint(planetModel, constraints);
|
||||
}
|
||||
}
|
||||
assertFalse(shape.isWithin(point));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for disjoint shapes. We build a DISJOINT shape with respect the geoAreaShape
|
||||
* and create shapes WITHIN that shapes. The resulting shape should be DISJOINT
|
||||
* to the geoAreaShape.
|
||||
*
|
||||
* Note that both shapes cannot be concave.
|
||||
*/
|
||||
@Test
|
||||
@Repeat(iterations = 5)
|
||||
public void testRandomDisjoint() {
|
||||
int referenceShapeType = CONVEX_SIMPLE_POLYGON;
|
||||
PlanetModel planetModel = randomPlanetModel();
|
||||
int geoAreaShapeType = randomGeoAreaShapeType();
|
||||
int shapeType =randomConvexShapeType();
|
||||
|
||||
GeoShape shape = null;
|
||||
GeoAreaShape geoAreaShape = null;
|
||||
while (shape == null) {
|
||||
geoAreaShape = randomGeoAreaShape(geoAreaShapeType, planetModel);
|
||||
Constraints constraints = new Constraints();
|
||||
constraints.put(geoAreaShape, GeoArea.DISJOINT);
|
||||
GeoAreaShape reference = randomGeoAreaShape(referenceShapeType, planetModel, constraints);
|
||||
if (reference != null) {
|
||||
constraints = getEmptyConstraint();
|
||||
constraints.put(reference, GeoArea.WITHIN);
|
||||
shape = randomGeoShape(shapeType, planetModel, constraints);
|
||||
}
|
||||
}
|
||||
int rel = geoAreaShape.getRelationship(shape);
|
||||
assertEquals(GeoArea.DISJOINT, rel);
|
||||
if (shape instanceof GeoArea) {
|
||||
rel = ((GeoArea)shape).getRelationship(geoAreaShape);
|
||||
assertEquals(GeoArea.DISJOINT, rel);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for within shapes. We build a shape WITHIN the geoAreaShape and create
|
||||
* shapes WITHIN that shape. The resulting shape should be WITHIN
|
||||
* to the geoAreaShape.
|
||||
*
|
||||
* Note that if the geoAreaShape is not concave the other shape must be not concave.
|
||||
*/
|
||||
@Test
|
||||
@Repeat(iterations = 5)
|
||||
public void testRandomWithIn() {
|
||||
PlanetModel planetModel = randomPlanetModel();
|
||||
int geoAreaShapeType = randomGeoAreaShapeType();
|
||||
int shapeType =randomShapeType();
|
||||
int referenceShapeType = CONVEX_SIMPLE_POLYGON;
|
||||
if (!isConcave(geoAreaShapeType)){
|
||||
shapeType =randomConvexShapeType();
|
||||
}
|
||||
if(isConcave(shapeType)){//both concave
|
||||
referenceShapeType = CONCAVE_SIMPLE_POLYGON;
|
||||
}
|
||||
GeoShape shape = null;
|
||||
GeoAreaShape geoAreaShape = null;
|
||||
while (shape == null) {
|
||||
geoAreaShape = randomGeoAreaShape(geoAreaShapeType, planetModel);
|
||||
Constraints constraints = new Constraints();
|
||||
constraints.put(geoAreaShape, GeoArea.WITHIN);
|
||||
GeoAreaShape reference = randomGeoAreaShape(referenceShapeType, planetModel, constraints);
|
||||
if (reference != null) {
|
||||
constraints = new Constraints();
|
||||
constraints.put(reference, GeoArea.WITHIN);
|
||||
shape = randomGeoShape(shapeType, planetModel, constraints);
|
||||
}
|
||||
}
|
||||
int rel = geoAreaShape.getRelationship(shape);
|
||||
assertEquals(GeoArea.WITHIN, rel);
|
||||
if (shape instanceof GeoArea) {
|
||||
rel = ((GeoArea)shape).getRelationship(geoAreaShape);
|
||||
assertEquals(GeoArea.CONTAINS, rel);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test for contains shapes. We build a shape containing the geoAreaShape and create
|
||||
* shapes WITHIN that shape. The resulting shape should CONTAIN
|
||||
* the geoAreaShape.
|
||||
*
|
||||
* Note that if the geoAreaShape is concave the other shape must be concave.
|
||||
* If shape is concave, the shape for reference should be concave as well.
|
||||
*
|
||||
*/
|
||||
@Test
|
||||
@Repeat(iterations = 1)
|
||||
public void testRandomContains() {
|
||||
int referenceShapeType = CONVEX_SIMPLE_POLYGON;
|
||||
PlanetModel planetModel = randomPlanetModel();
|
||||
int geoAreaShapeType = randomGeoAreaShapeType();
|
||||
while (geoAreaShapeType == COLLECTION){
|
||||
geoAreaShapeType = randomGeoAreaShapeType();
|
||||
}
|
||||
int shapeType = randomShapeType();
|
||||
if (isConcave(geoAreaShapeType)){
|
||||
shapeType = randomConcaveShapeType();
|
||||
}
|
||||
if (isConcave(shapeType)){
|
||||
referenceShapeType = CONCAVE_SIMPLE_POLYGON;
|
||||
}
|
||||
GeoShape shape = null;
|
||||
GeoAreaShape geoAreaShape = null;
|
||||
while (shape == null) {
|
||||
geoAreaShape = randomGeoAreaShape(geoAreaShapeType, planetModel);
|
||||
Constraints constraints = getEmptyConstraint();
|
||||
constraints.put(geoAreaShape, GeoArea.CONTAINS);
|
||||
GeoPolygon reference =(GeoPolygon)randomGeoAreaShape(referenceShapeType, planetModel, constraints);
|
||||
if (reference != null) {
|
||||
constraints = getEmptyConstraint();
|
||||
constraints.put(reference, GeoArea.CONTAINS);
|
||||
shape = randomGeoShape(shapeType, planetModel, constraints);
|
||||
}
|
||||
}
|
||||
int rel = geoAreaShape.getRelationship(shape);
|
||||
assertEquals(GeoArea.CONTAINS, rel);
|
||||
if (shape instanceof GeoArea) {
|
||||
rel = ((GeoArea)shape).getRelationship(geoAreaShape);
|
||||
assertEquals(GeoArea.WITHIN, rel);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for overlapping shapes. We build a shape that contains part of the
|
||||
* geoAreaShape, is disjoint to other part and contains a disjoint shape. We create
|
||||
* shapes according the criteria. The resulting shape should OVERLAP
|
||||
* the geoAreaShape.
|
||||
*/
|
||||
@Test
|
||||
@Repeat(iterations = 5)
|
||||
public void testRandomOverlaps() {
|
||||
PlanetModel planetModel = randomPlanetModel();
|
||||
int geoAreaShapeType = randomGeoAreaShapeType();
|
||||
int shapeType = randomShapeType();
|
||||
|
||||
GeoShape shape = null;
|
||||
GeoAreaShape geoAreaShape = null;
|
||||
while (shape == null) {
|
||||
geoAreaShape = randomGeoAreaShape(geoAreaShapeType, planetModel);
|
||||
Constraints constraints = getEmptyConstraint();
|
||||
constraints.put(geoAreaShape,GeoArea.WITHIN);
|
||||
GeoAreaShape reference1 = randomGeoAreaShape(CONVEX_SIMPLE_POLYGON, planetModel, constraints);
|
||||
if (reference1 == null){
|
||||
continue;
|
||||
}
|
||||
constraints = getEmptyConstraint();
|
||||
constraints.put(geoAreaShape, GeoArea.WITHIN);
|
||||
constraints.put(reference1, GeoArea.DISJOINT);
|
||||
GeoAreaShape reference2 = randomGeoAreaShape(CONVEX_SIMPLE_POLYGON, planetModel, constraints);
|
||||
if (reference2 == null){
|
||||
continue;
|
||||
}
|
||||
constraints = getEmptyConstraint();
|
||||
constraints.put(geoAreaShape, GeoArea.DISJOINT);
|
||||
GeoAreaShape reference3 = randomGeoAreaShape(CONVEX_SIMPLE_POLYGON, planetModel, constraints);
|
||||
if (reference3 != null) {
|
||||
constraints = new Constraints();
|
||||
constraints.put(reference1, GeoArea.DISJOINT);
|
||||
constraints.put(reference2, GeoArea.CONTAINS);
|
||||
constraints.put(reference3, GeoArea.CONTAINS);
|
||||
shape = randomGeoShape(shapeType, planetModel, constraints);
|
||||
}
|
||||
}
|
||||
int rel = geoAreaShape.getRelationship(shape);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
if (shape instanceof GeoArea) {
|
||||
rel = ((GeoArea)shape).getRelationship(geoAreaShape);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,837 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* Check relationship between polygon and GeoShapes of basic polygons. Normally we construct
|
||||
* the convex, concave counterpart and the convex polygon as a complex polygon.
|
||||
*/
|
||||
public class SimpleGeoPolygonRelationshipsTest {
|
||||
|
||||
/**
|
||||
* Test with two shapes with no crossing edges and no points in common in convex case.
|
||||
*/
|
||||
@Test
|
||||
public void testGeoSimplePolygon1() {
|
||||
|
||||
//POLYGON ((19.845091 -60.452631, 20.119948 -61.655652, 23.207901 -61.453298, 22.820804 -60.257713, 19.845091 -60.452631)) disjoint
|
||||
GeoPolygon originalConvexPol = buildConvexGeoPolygon(19.84509, -60.452631,
|
||||
20.119948, -61.655652,
|
||||
23.207901, -61.453298,
|
||||
22.820804, -60.257713);
|
||||
|
||||
GeoPolygon originalConcavePol = buildConcaveGeoPolygon(19.84509, -60.452631,
|
||||
20.119948, -61.655652,
|
||||
23.207901, -61.453298,
|
||||
22.820804, -60.257713);
|
||||
|
||||
GeoPolygon originalComplexPol = buildComplexGeoPolygon(19.84509, -60.452631,
|
||||
20.119948, -61.655652,
|
||||
23.207901, -61.453298,
|
||||
22.820804, -60.257713);
|
||||
|
||||
GeoPolygon polConvex = buildConvexGeoPolygon(20.0, -60.4,
|
||||
20.1, -60.4,
|
||||
20.1, -60.3,
|
||||
20.0, -60.3);
|
||||
|
||||
GeoPolygon polConcave = buildConcaveGeoPolygon(20.0, -60.4,
|
||||
20.1, -60.4,
|
||||
20.1, -60.3,
|
||||
20.0, -60.3);
|
||||
|
||||
|
||||
//Convex
|
||||
int rel = originalConvexPol.getRelationship(polConvex);
|
||||
assertEquals(GeoArea.DISJOINT, rel);
|
||||
rel = polConvex.getRelationship(originalConvexPol);
|
||||
assertEquals(GeoArea.DISJOINT, rel);
|
||||
|
||||
rel = originalConvexPol.getRelationship(polConcave);
|
||||
assertEquals(GeoArea.CONTAINS, rel);
|
||||
rel = polConcave.getRelationship(originalConvexPol);
|
||||
assertEquals(GeoArea.WITHIN, rel);//Check
|
||||
|
||||
//Concave
|
||||
rel = originalConcavePol.getRelationship(polConvex);
|
||||
assertEquals(GeoArea.WITHIN, rel);
|
||||
rel = polConvex.getRelationship(originalConcavePol);
|
||||
assertEquals(GeoArea.CONTAINS, rel);
|
||||
|
||||
rel = originalConcavePol.getRelationship(polConcave);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
rel = polConcave.getRelationship(originalConcavePol);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
|
||||
//Complex
|
||||
rel = originalComplexPol.getRelationship(polConvex);
|
||||
assertEquals(GeoArea.DISJOINT, rel);
|
||||
rel = polConvex.getRelationship(originalComplexPol);
|
||||
assertEquals(GeoArea.DISJOINT, rel);
|
||||
|
||||
rel = originalComplexPol.getRelationship(polConcave);
|
||||
assertEquals(GeoArea.CONTAINS, rel);
|
||||
rel = polConcave.getRelationship(originalComplexPol);
|
||||
assertEquals(GeoArea.WITHIN, rel);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test with two shapes with crossing edges and some points inside in convex case.
|
||||
*/
|
||||
@Test
|
||||
public void testGeoSimplePolygon2() {
|
||||
|
||||
//POLYGON ((19.845091 -60.452631, 20.119948 -61.655652, 23.207901 -61.453298, 22.820804 -60.257713, 19.845091 -60.452631)) disjoint
|
||||
GeoPolygon originalConvexPol = buildConvexGeoPolygon(19.84509, -60.452631,
|
||||
20.119948, -61.655652,
|
||||
23.207901, -61.453298,
|
||||
22.820804, -60.257713);
|
||||
|
||||
GeoPolygon originalConcavePol = buildConcaveGeoPolygon(19.84509, -60.452631,
|
||||
20.119948, -61.655652,
|
||||
23.207901, -61.453298,
|
||||
22.820804, -60.257713);
|
||||
|
||||
GeoPolygon originalComplexPol = buildComplexGeoPolygon(19.84509, -60.452631,
|
||||
20.119948, -61.655652,
|
||||
23.207901, -61.453298,
|
||||
22.820804, -60.257713);
|
||||
|
||||
//POLYGON ((20.0 -60.4, 23.1 -60.4, 23.1 -60.3, 20.0 -60.3,20.0 -60.4))
|
||||
GeoPolygon polConvex = buildConvexGeoPolygon(20.0, -60.4,
|
||||
23.1, -60.4,
|
||||
23.1, -60.3,
|
||||
20.0, -60.3);
|
||||
|
||||
GeoPolygon polConcave = buildConcaveGeoPolygon(20.0, -60.4,
|
||||
23.1, -60.4,
|
||||
23.1, -60.3,
|
||||
20.0, -60.3);
|
||||
|
||||
//Convex
|
||||
int rel = originalConvexPol.getRelationship(polConvex);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
rel = polConvex.getRelationship(originalConvexPol);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
|
||||
rel = originalConvexPol.getRelationship(polConcave);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
rel = polConcave.getRelationship(originalConvexPol);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
|
||||
//Concave
|
||||
rel = originalConcavePol.getRelationship(polConcave);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
rel = polConcave.getRelationship(originalConcavePol);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
|
||||
|
||||
rel = originalConcavePol.getRelationship(polConvex);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
rel = polConvex.getRelationship(originalConcavePol);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
|
||||
//Complex
|
||||
rel = originalComplexPol.getRelationship(polConcave);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
rel = polConcave.getRelationship(originalComplexPol);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
|
||||
|
||||
rel = originalComplexPol.getRelationship(polConvex);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
rel = polConvex.getRelationship(originalComplexPol);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test with two shapes with no crossing edges and all points inside in convex case.
|
||||
*/
|
||||
@Test
|
||||
public void testGeoSimplePolygon3() {
|
||||
|
||||
//POLYGON ((19.845091 -60.452631, 20.119948 -61.655652, 23.207901 -61.453298, 22.820804 -60.257713, 19.845091 -60.452631)) disjoint
|
||||
GeoPolygon originalConvexPol = buildConvexGeoPolygon(19.84509, -60.452631,
|
||||
20.119948, -61.655652,
|
||||
23.207901, -61.453298,
|
||||
22.820804, -60.257713);
|
||||
|
||||
GeoPolygon originalConcavePol = buildConcaveGeoPolygon(19.84509, -60.452631,
|
||||
20.119948, -61.655652,
|
||||
23.207901, -61.453298,
|
||||
22.820804, -60.257713);
|
||||
|
||||
GeoPolygon originalComplexPol = buildComplexGeoPolygon(19.84509, -60.452631,
|
||||
20.119948, -61.655652,
|
||||
23.207901, -61.453298,
|
||||
22.820804, -60.257713);
|
||||
|
||||
//POLYGON ((20.0 -61.1, 20.1 -61.1, 20.1 -60.5, 20.0 -60.5,20.0 -61.1))
|
||||
GeoPolygon polConvex = buildConvexGeoPolygon(20.0, -61.1,
|
||||
20.1, -61.1,
|
||||
20.1, -60.5,
|
||||
20.0, -60.5);
|
||||
|
||||
GeoPolygon polConcave = buildConcaveGeoPolygon(20.0, -61.1,
|
||||
20.1, -61.1,
|
||||
20.1, -60.5,
|
||||
20.0, -60.5);
|
||||
|
||||
//Convex
|
||||
int rel = originalConvexPol.getRelationship(polConvex);
|
||||
assertEquals(GeoArea.WITHIN, rel);
|
||||
rel = polConvex.getRelationship(originalConvexPol);
|
||||
assertEquals(GeoArea.CONTAINS, rel);
|
||||
|
||||
rel = originalConvexPol.getRelationship(polConcave);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
rel = polConcave.getRelationship(originalConvexPol);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
|
||||
//Concave
|
||||
rel = originalConcavePol.getRelationship(polConcave);
|
||||
assertEquals(GeoArea.CONTAINS, rel);
|
||||
rel = polConcave.getRelationship(originalConcavePol);
|
||||
assertEquals(GeoArea.WITHIN, rel);//check
|
||||
|
||||
rel = originalConcavePol.getRelationship(polConvex);
|
||||
assertEquals(GeoArea.DISJOINT, rel);
|
||||
rel = polConvex.getRelationship(originalConcavePol);
|
||||
assertEquals(GeoArea.DISJOINT, rel);
|
||||
|
||||
//Complex
|
||||
rel = originalComplexPol.getRelationship(polConvex);
|
||||
assertEquals(GeoArea.WITHIN, rel);
|
||||
rel = polConvex.getRelationship(originalComplexPol);
|
||||
assertEquals(GeoArea.CONTAINS, rel);
|
||||
|
||||
rel = originalComplexPol.getRelationship(polConcave);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
rel = polConcave.getRelationship(originalComplexPol);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test with two shapes with crossing edges and no points inside in convex case.
|
||||
*/
|
||||
@Test
|
||||
public void testGeoSimplePolygon4() {
|
||||
//POLYGON ((19.845091 -60.452631, 20.119948 -61.655652, 23.207901 -61.453298, 22.820804 -60.257713, 19.845091 -60.452631)) disjoint
|
||||
GeoPolygon originalConvexPol = buildConvexGeoPolygon(19.84509, -60.452631,
|
||||
20.119948, -61.655652,
|
||||
23.207901, -61.453298,
|
||||
22.820804, -60.257713);
|
||||
|
||||
GeoPolygon originalConcavePol = buildConcaveGeoPolygon(19.84509, -60.452631,
|
||||
20.119948, -61.655652,
|
||||
23.207901, -61.453298,
|
||||
22.820804, -60.257713);
|
||||
|
||||
GeoPolygon originalComplexPol = buildComplexGeoPolygon(19.84509, -60.452631,
|
||||
20.119948, -61.655652,
|
||||
23.207901, -61.453298,
|
||||
22.820804, -60.257713);
|
||||
|
||||
//POLYGON ((20.0 -62.4, 20.1 -62.4, 20.1 -60.3, 20.0 -60.3,20.0 -62.4)) intersects no points inside
|
||||
GeoPolygon polConvex = buildConvexGeoPolygon(20.0, -62.4,
|
||||
20.1, -62.4,
|
||||
20.1, -60.3,
|
||||
20.0, -60.3);
|
||||
|
||||
GeoPolygon polConcave = buildConcaveGeoPolygon(20.0, -62.4,
|
||||
20.1, -62.4,
|
||||
20.1, -60.3,
|
||||
20.0, -60.3);
|
||||
|
||||
//Convex
|
||||
int rel = originalConvexPol.getRelationship(polConvex);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
rel = polConvex.getRelationship(originalConvexPol);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
|
||||
rel = originalConvexPol.getRelationship(polConcave);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
rel = polConcave.getRelationship(originalConvexPol);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
|
||||
//concave
|
||||
rel = originalConcavePol.getRelationship(polConcave);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
rel = polConcave.getRelationship(originalConcavePol);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
|
||||
rel = originalConcavePol.getRelationship(polConvex);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
rel = polConvex.getRelationship(originalConcavePol);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
|
||||
//Complex
|
||||
rel = originalComplexPol.getRelationship(polConvex);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
rel = polConvex.getRelationship(originalComplexPol);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
|
||||
rel = originalComplexPol.getRelationship(polConcave);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
rel = polConcave.getRelationship(originalComplexPol);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test with two shapes with no crossing edges and polygon in hole in convex case.
|
||||
*/
|
||||
@Test
|
||||
public void testGeoSimplePolygonWithHole1() {
|
||||
//POLYGON((-135 -31, -135 -30, -137 -30, -137 -31, -135 -31),(-135.5 -30.7, -135.5 -30.4, -136.5 -30.4, -136.5 -30.7, -135.5 -30.7))
|
||||
GeoPolygon hole = buildConcaveGeoPolygon(-135.5, -30.7,
|
||||
-135.5, -30.4,
|
||||
-136.5, -30.4,
|
||||
-136.5, -30.7);
|
||||
GeoPolygon originalConvexPol = buildConvexGeoPolygonWithHole(-135, -31,
|
||||
-135, -30,
|
||||
-137, -30,
|
||||
-137, -31, hole);
|
||||
|
||||
GeoPolygon holeInv = buildConvexGeoPolygon(-135, -31,
|
||||
-135, -30,
|
||||
-137, -30,
|
||||
-137, -31);
|
||||
|
||||
GeoPolygon originalConvexPolInv = buildConcaveGeoPolygonWithHole(-135.5, -30.7,
|
||||
-135.5, -30.4,
|
||||
-136.5, -30.4,
|
||||
-136.5, -30.7, holeInv);
|
||||
|
||||
//POLYGON((-135.7 -30.6, -135.7 -30.45, -136 -30.45, -136 -30.6, -135.7 -30.6)) in the hole
|
||||
GeoPolygon polConvex = buildConvexGeoPolygon(-135.7, -30.6,
|
||||
-135.7, -30.45,
|
||||
-136, -30.45,
|
||||
-136, -30.6);
|
||||
|
||||
GeoPolygon polConcave = buildConcaveGeoPolygon(-135.7, -30.6,
|
||||
-135.7, -30.45,
|
||||
-136, -30.45,
|
||||
-136, -30.6);
|
||||
|
||||
int rel = originalConvexPol.getRelationship(polConvex);
|
||||
assertEquals(GeoArea.DISJOINT, rel);
|
||||
rel = polConvex.getRelationship(originalConvexPol);
|
||||
assertEquals(GeoArea.DISJOINT, rel);
|
||||
|
||||
rel = originalConvexPol.getRelationship(polConcave);
|
||||
assertEquals(GeoArea.CONTAINS, rel);
|
||||
rel = polConcave.getRelationship(originalConvexPol);
|
||||
assertEquals(GeoArea.WITHIN, rel);
|
||||
|
||||
rel = originalConvexPolInv.getRelationship(polConvex);
|
||||
assertEquals(GeoArea.DISJOINT, rel);
|
||||
rel = polConvex.getRelationship(originalConvexPolInv);
|
||||
assertEquals(GeoArea.DISJOINT, rel);
|
||||
|
||||
rel = originalConvexPolInv.getRelationship(polConcave);
|
||||
assertEquals(GeoArea.CONTAINS, rel);
|
||||
rel = polConcave.getRelationship(originalConvexPolInv);
|
||||
assertEquals(GeoArea.WITHIN, rel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test with two shapes with crossing edges in hole and some points inside in convex case.
|
||||
*/
|
||||
@Test
|
||||
public void testGeoSimplePolygonWithHole2() {
|
||||
//POLYGON((-135 -31, -135 -30, -137 -30, -137 -31, -135 -31),(-135.5 -30.7, -135.5 -30.4, -136.5 -30.4, -136.5 -30.7, -135.5 -30.7))
|
||||
GeoPolygon hole = buildConcaveGeoPolygon(-135.5, -30.7,
|
||||
-135.5, -30.4,
|
||||
-136.5, -30.4,
|
||||
-136.5, -30.7);
|
||||
GeoPolygon originalConvexPol = buildConvexGeoPolygonWithHole(-135, -31,
|
||||
-135, -30,
|
||||
-137, -30,
|
||||
-137, -31, hole);
|
||||
|
||||
GeoPolygon holeInv = buildConvexGeoPolygon(-135, -31,
|
||||
-135, -30,
|
||||
-137, -30,
|
||||
-137, -31);
|
||||
|
||||
GeoPolygon originalConvexPolInv = buildConcaveGeoPolygonWithHole(-135.5, -30.7,
|
||||
-135.5, -30.4,
|
||||
-136.5, -30.4,
|
||||
-136.5, -30.7, holeInv);
|
||||
|
||||
//POLYGON((-135.5 -31.2, -135.5 -30.8, -136 -30.8, -136 -31.2, -135.5 -31.2)) intersects the hole
|
||||
GeoPolygon polConvex = buildConvexGeoPolygon(-135.5, -30.2,
|
||||
-135.5, -30.8,
|
||||
-136, -30.8,
|
||||
-136, -30.2);
|
||||
|
||||
GeoPolygon polConcave = buildConcaveGeoPolygon(-135.5, -30.2,
|
||||
-135.5, -30.8,
|
||||
-136, -30.8,
|
||||
-136, -30.2);
|
||||
|
||||
int rel = originalConvexPol.getRelationship(polConvex);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
rel = polConvex.getRelationship(originalConvexPol);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
|
||||
rel = originalConvexPol.getRelationship(polConcave);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
rel = polConcave.getRelationship(originalConvexPol);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
|
||||
rel = originalConvexPolInv.getRelationship(polConvex);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
rel = polConvex.getRelationship(originalConvexPolInv);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
|
||||
rel = originalConvexPolInv.getRelationship(polConcave);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
rel = polConcave.getRelationship(originalConvexPolInv);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test with two shapes with crossing edges and some points inside in convex case.
|
||||
*/
|
||||
@Test
|
||||
public void testGeoSimplePolygonWithHole3() {
|
||||
//POLYGON((-135 -31, -135 -30, -137 -30, -137 -31, -135 -31),(-135.5 -30.7, -135.5 -30.4, -136.5 -30.4, -136.5 -30.7, -135.5 -30.7))
|
||||
GeoPolygon hole = buildConcaveGeoPolygon(-135.5, -30.7,
|
||||
-135.5, -30.4,
|
||||
-136.5, -30.4,
|
||||
-136.5, -30.7);
|
||||
GeoPolygon originalConvexPol = buildConvexGeoPolygonWithHole(-135, -31,
|
||||
-135, -30,
|
||||
-137, -30,
|
||||
-137, -31, hole);
|
||||
|
||||
GeoPolygon holeInv = buildConvexGeoPolygon(-135, -31,
|
||||
-135, -30,
|
||||
-137, -30,
|
||||
-137, -31);
|
||||
|
||||
GeoPolygon originalConvexPolInv = buildConcaveGeoPolygonWithHole(-135.5, -30.7,
|
||||
-135.5, -30.4,
|
||||
-136.5, -30.4,
|
||||
-136.5, -30.7, holeInv);
|
||||
|
||||
//POLYGON((-135.2 -30.8, -135.2 -30.2, -136.8 -30.2, -136.8 -30.8, -135.2 -30.8)) inside the polygon covering the hole
|
||||
GeoPolygon polConvex = buildConvexGeoPolygon(-135.2, -30.8,
|
||||
-135.2, -30.3,
|
||||
-136.8, -30.2,
|
||||
-136.8, -30.8);
|
||||
|
||||
GeoPolygon polConcave = buildConcaveGeoPolygon(-135.2, -30.8,
|
||||
-135.2, -30.3,
|
||||
-136.8, -30.2,
|
||||
-136.8, -30.8);
|
||||
|
||||
int rel = originalConvexPol.getRelationship(polConvex);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
rel = polConvex.getRelationship(originalConvexPol);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
|
||||
rel = originalConvexPol.getRelationship(polConcave);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
rel = polConcave.getRelationship(originalConvexPol);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
|
||||
rel = originalConvexPolInv.getRelationship(polConvex);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
rel = polConvex.getRelationship(originalConvexPolInv);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
|
||||
rel = originalConvexPolInv.getRelationship(polConcave);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
rel = polConcave.getRelationship(originalConvexPolInv);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test with two shapes with no crossing edges and all points inside in convex case.
|
||||
*/
|
||||
@Test
|
||||
public void testGeoSimplePolygonWithHole4() {
|
||||
//POLYGON((-135 -31, -135 -30, -137 -30, -137 -31, -135 -31),(-135.5 -30.7, -135.5 -30.4, -136.5 -30.4, -136.5 -30.7, -135.5 -30.7))
|
||||
GeoPolygon hole = buildConcaveGeoPolygon(-135.5, -30.7,
|
||||
-135.5, -30.4,
|
||||
-136.5, -30.4,
|
||||
-136.5, -30.7);
|
||||
GeoPolygon originalConvexPol = buildConvexGeoPolygonWithHole(-135, -31,
|
||||
-135, -30,
|
||||
-137, -30,
|
||||
-137, -31, hole);
|
||||
|
||||
GeoPolygon holeInv = buildConvexGeoPolygon(-135, -31,
|
||||
-135, -30,
|
||||
-137, -30,
|
||||
-137, -31);
|
||||
|
||||
GeoPolygon originalConvexPolInv = buildConcaveGeoPolygonWithHole(-135.5, -30.7,
|
||||
-135.5, -30.4,
|
||||
-136.5, -30.4,
|
||||
-136.5, -30.7, holeInv);
|
||||
|
||||
// POLYGON((-135.7 -30.3, -135.7 -30.2, -136 -30.2, -136 -30.3, -135.7 -30.3))inside the polygon
|
||||
GeoPolygon polConvex = buildConvexGeoPolygon(-135.7, -30.3,
|
||||
-135.7, -30.2,
|
||||
-136, -30.2,
|
||||
-136, -30.3);
|
||||
|
||||
GeoPolygon polConcave = buildConcaveGeoPolygon(-135.7, -30.3,
|
||||
-135.7, -30.2,
|
||||
-136, -30.2,
|
||||
-136, -30.3);
|
||||
|
||||
int rel = originalConvexPol.getRelationship(polConvex);
|
||||
assertEquals(GeoArea.WITHIN, rel);
|
||||
rel = polConvex.getRelationship(originalConvexPol);
|
||||
assertEquals(GeoArea.CONTAINS, rel);
|
||||
|
||||
rel = originalConvexPol.getRelationship(polConcave);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
rel = polConcave.getRelationship(originalConvexPol);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
|
||||
rel = originalConvexPolInv.getRelationship(polConvex);
|
||||
assertEquals(GeoArea.WITHIN, rel);
|
||||
rel = polConvex.getRelationship(originalConvexPolInv);
|
||||
assertEquals(GeoArea.CONTAINS, rel);
|
||||
|
||||
rel = originalConvexPolInv.getRelationship(polConcave);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
rel = polConcave.getRelationship(originalConvexPolInv);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGeoSimplePolygonWithCircle() {
|
||||
//POLYGON ((19.845091 -60.452631, 20.119948 -61.655652, 23.207901 -61.453298, 22.820804 -60.257713, 19.845091 -60.452631)) disjoint
|
||||
GeoPolygon originalConvexPol = buildConvexGeoPolygon(19.84509, -60.452631,
|
||||
20.119948, -61.655652,
|
||||
23.207901, -61.453298,
|
||||
22.820804, -60.257713);
|
||||
|
||||
GeoPolygon originalConcavePol = buildConcaveGeoPolygon(19.84509, -60.452631,
|
||||
20.119948, -61.655652,
|
||||
23.207901, -61.453298,
|
||||
22.820804, -60.257713);
|
||||
|
||||
GeoPolygon originalComplexPol = buildComplexGeoPolygon(19.84509, -60.452631,
|
||||
20.119948, -61.655652,
|
||||
23.207901, -61.453298,
|
||||
22.820804, -60.257713);
|
||||
|
||||
GeoCircle outCircle = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, Math.toRadians(-70), Math.toRadians(23), Math.toRadians(1));
|
||||
int rel = originalConvexPol.getRelationship(outCircle);
|
||||
assertEquals(GeoArea.DISJOINT, rel);
|
||||
rel = originalConcavePol.getRelationship(outCircle);
|
||||
assertEquals(GeoArea.WITHIN, rel);
|
||||
rel = originalComplexPol.getRelationship(outCircle);
|
||||
assertEquals(GeoArea.DISJOINT, rel);
|
||||
|
||||
GeoCircle overlapCircle = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, Math.toRadians(-61.5), Math.toRadians(20), Math.toRadians(1));
|
||||
rel = originalConvexPol.getRelationship(overlapCircle);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
rel = originalConcavePol.getRelationship(overlapCircle);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
rel = originalComplexPol.getRelationship(overlapCircle);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
|
||||
GeoCircle inCircle = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, Math.toRadians(-61), Math.toRadians(21), Math.toRadians(0.1));
|
||||
rel = originalConvexPol.getRelationship(inCircle);
|
||||
assertEquals(GeoArea.WITHIN, rel);
|
||||
rel = originalConcavePol.getRelationship(inCircle);
|
||||
assertEquals(GeoArea.DISJOINT, rel);
|
||||
rel = originalComplexPol.getRelationship(inCircle);
|
||||
assertEquals(GeoArea.WITHIN, rel);
|
||||
|
||||
GeoCircle onCircle = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, Math.toRadians(-61), Math.toRadians(21), Math.toRadians(10.));
|
||||
rel = originalConvexPol.getRelationship(onCircle);
|
||||
assertEquals(GeoArea.CONTAINS, rel);
|
||||
rel = originalConcavePol.getRelationship(onCircle);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
rel = originalComplexPol.getRelationship(onCircle);
|
||||
assertEquals(GeoArea.CONTAINS, rel);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGeoSimplePolygonWithBBox() {
|
||||
//POLYGON ((19.845091 -60.452631, 20.119948 -61.655652, 23.207901 -61.453298, 22.820804 -60.257713, 19.845091 -60.452631)) disjoint
|
||||
GeoPolygon originalConvexPol = buildConvexGeoPolygon(19.84509, -60.452631,
|
||||
20.119948, -61.655652,
|
||||
23.207901, -61.453298,
|
||||
22.820804, -60.257713);
|
||||
|
||||
GeoPolygon originalConcavePol = buildConcaveGeoPolygon(19.84509, -60.452631,
|
||||
20.119948, -61.655652,
|
||||
23.207901, -61.453298,
|
||||
22.820804, -60.257713);
|
||||
|
||||
GeoPolygon originalComplexPol = buildComplexGeoPolygon(19.84509, -60.452631,
|
||||
20.119948, -61.655652,
|
||||
23.207901, -61.453298,
|
||||
22.820804, -60.257713);
|
||||
|
||||
GeoBBox outRectangle = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, Math.toRadians(-69),
|
||||
Math.toRadians(-70),
|
||||
Math.toRadians(22),
|
||||
Math.toRadians(23));
|
||||
int rel = originalConvexPol.getRelationship(outRectangle);
|
||||
assertEquals(GeoArea.DISJOINT, rel);
|
||||
rel = outRectangle.getRelationship(originalConvexPol);
|
||||
assertEquals(GeoArea.DISJOINT, rel);
|
||||
rel = originalConcavePol.getRelationship(outRectangle);
|
||||
assertEquals(GeoArea.WITHIN, rel);
|
||||
rel = originalComplexPol.getRelationship(outRectangle);
|
||||
assertEquals(GeoArea.DISJOINT, rel);
|
||||
|
||||
GeoBBox overlapRectangle = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, Math.toRadians(-61),
|
||||
Math.toRadians(-62),
|
||||
Math.toRadians(22),
|
||||
Math.toRadians(23));
|
||||
rel = originalConvexPol.getRelationship(overlapRectangle);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
rel = overlapRectangle.getRelationship(originalConvexPol);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
rel = originalConcavePol.getRelationship(overlapRectangle);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
rel = originalComplexPol.getRelationship(overlapRectangle);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
|
||||
GeoBBox inRectangle = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, Math.toRadians(-61),
|
||||
Math.toRadians(-61.1),
|
||||
Math.toRadians(22.5),
|
||||
Math.toRadians(23));
|
||||
rel = originalConvexPol.getRelationship(inRectangle);
|
||||
assertEquals(GeoArea.WITHIN, rel);
|
||||
rel = inRectangle.getRelationship(originalConvexPol);
|
||||
assertEquals(GeoArea.CONTAINS, rel);
|
||||
rel = originalConcavePol.getRelationship(inRectangle);
|
||||
assertEquals(GeoArea.DISJOINT, rel);
|
||||
rel = originalComplexPol.getRelationship(inRectangle);
|
||||
assertEquals(GeoArea.WITHIN, rel);
|
||||
|
||||
GeoBBox onRectangle = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, Math.toRadians(-59),
|
||||
Math.toRadians(-64.1),
|
||||
Math.toRadians(18.5),
|
||||
Math.toRadians(27));
|
||||
rel = originalConvexPol.getRelationship(onRectangle);
|
||||
assertEquals(GeoArea.CONTAINS, rel);
|
||||
rel = onRectangle.getRelationship(originalConvexPol);
|
||||
assertEquals(GeoArea.WITHIN, rel);
|
||||
rel = originalConcavePol.getRelationship(onRectangle);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
rel = originalComplexPol.getRelationship(onRectangle);
|
||||
assertEquals(GeoArea.CONTAINS, rel);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGeoSimplePolygonWithComposite() {
|
||||
GeoShape shape = getCompositeShape();
|
||||
|
||||
//POLYGON((-145.8555 -5.13, -145.8540 -5.13, -145.8540 -5.12, -145.8555 -5.12, -145.8555 -5.13))
|
||||
GeoPolygon polConvex = buildConvexGeoPolygon(-145.8555, -5.13,
|
||||
-145.8540, -5.13,
|
||||
-145.8540, -5.12,
|
||||
-145.8555, -5.12);
|
||||
|
||||
GeoPolygon polConcave = buildConcaveGeoPolygon(-145.8555, -5.13,
|
||||
-145.8540, -5.13,
|
||||
-145.8540, -5.12,
|
||||
-145.8555, -5.12);
|
||||
|
||||
int rel = polConvex.getRelationship(shape);
|
||||
assertEquals(GeoArea.DISJOINT, rel);
|
||||
rel = polConcave.getRelationship(shape);
|
||||
assertEquals(GeoArea.WITHIN, rel);
|
||||
|
||||
//POLYGON((-145.8555 -5.13, -145.85 -5.13, -145.85 -5.12, -145.8555 -5.12, -145.8555 -5.13))
|
||||
polConvex = buildConvexGeoPolygon(-145.8555, -5.13,
|
||||
-145.85, -5.13,
|
||||
-145.85, -5.12,
|
||||
-145.8555, -5.12);
|
||||
|
||||
polConcave = buildConcaveGeoPolygon(-145.8555, -5.13,
|
||||
-145.85, -5.13,
|
||||
-145.85, -5.12,
|
||||
-145.8555, -5.12);
|
||||
|
||||
rel = polConvex.getRelationship(shape);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
rel = polConcave.getRelationship(shape);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
|
||||
//POLYGON((-146 -5.18, -145.854 -5.18, -145.854 -5.11, -146 -5.11, -146 -5.18))
|
||||
//Case overlaping on of the shapes
|
||||
polConvex = buildConvexGeoPolygon(-146, -5.18,
|
||||
-145.854, -5.18,
|
||||
-145.854, -5.11,
|
||||
-146, -5.11);
|
||||
|
||||
polConcave = buildConcaveGeoPolygon(-146, -5.18,
|
||||
-145.854, -5.18,
|
||||
-145.854, -5.11,
|
||||
-146, -5.11);
|
||||
|
||||
rel = polConvex.getRelationship(shape);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
rel = polConcave.getRelationship(shape);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
|
||||
//POLYGON((-145.88 -5.13, -145.87 -5.13, -145.87 -5.12, -145.88 -5.12, -145.88 -5.13))
|
||||
polConvex = buildConvexGeoPolygon(-145.88, -5.13,
|
||||
-145.87, -5.13,
|
||||
-145.87, -5.12,
|
||||
-145.88, -5.12);
|
||||
|
||||
polConcave = buildConcaveGeoPolygon(-145.88, -5.13,
|
||||
-145.87, -5.13,
|
||||
-145.87, -5.12,
|
||||
-145.88, -5.12);
|
||||
|
||||
rel = polConvex.getRelationship(shape);
|
||||
assertEquals(GeoArea.CONTAINS, rel);
|
||||
rel = polConcave.getRelationship(shape);
|
||||
assertEquals(GeoArea.OVERLAPS, rel);
|
||||
}
|
||||
|
||||
private GeoPolygon buildConvexGeoPolygon(double lon1, double lat1,
|
||||
double lon2, double lat2,
|
||||
double lon3, double lat3,
|
||||
double lon4, double lat4) {
|
||||
GeoPoint point1 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(lat1), Math.toRadians(lon1));
|
||||
GeoPoint point2 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(lat2), Math.toRadians(lon2));
|
||||
GeoPoint point3 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(lat3), Math.toRadians(lon3));
|
||||
GeoPoint point4 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(lat4), Math.toRadians(lon4));
|
||||
final List<GeoPoint> points = new ArrayList<>();
|
||||
points.add(point1);
|
||||
points.add(point2);
|
||||
points.add(point3);
|
||||
points.add(point4);
|
||||
return GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points);
|
||||
}
|
||||
|
||||
private GeoPolygon buildConcaveGeoPolygon(double lon1, double lat1,
|
||||
double lon2, double lat2,
|
||||
double lon3, double lat3,
|
||||
double lon4, double lat4) {
|
||||
GeoPoint point1 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(lat1), Math.toRadians(lon1));
|
||||
GeoPoint point2 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(lat2), Math.toRadians(lon2));
|
||||
GeoPoint point3 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(lat3), Math.toRadians(lon3));
|
||||
GeoPoint point4 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(lat4), Math.toRadians(lon4));
|
||||
final List<GeoPoint> points = new ArrayList<>();
|
||||
points.add(point1);
|
||||
points.add(point2);
|
||||
points.add(point3);
|
||||
points.add(point4);
|
||||
return GeoPolygonFactory.makeGeoConcavePolygon(PlanetModel.SPHERE, points);
|
||||
}
|
||||
|
||||
private GeoPolygon buildComplexGeoPolygon(double lon1, double lat1,
|
||||
double lon2, double lat2,
|
||||
double lon3, double lat3,
|
||||
double lon4, double lat4) {
|
||||
GeoPoint point1 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(lat1), Math.toRadians(lon1));
|
||||
GeoPoint point2 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(lat2), Math.toRadians(lon2));
|
||||
GeoPoint point3 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(lat3), Math.toRadians(lon3));
|
||||
GeoPoint point4 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(lat4), Math.toRadians(lon4));
|
||||
final List<GeoPoint> points = new ArrayList<>();
|
||||
points.add(point1);
|
||||
points.add(point2);
|
||||
points.add(point3);
|
||||
points.add(point4);
|
||||
GeoPolygonFactory.PolygonDescription pd = new GeoPolygonFactory.PolygonDescription(points);
|
||||
return GeoPolygonFactory.makeLargeGeoPolygon(PlanetModel.SPHERE, Collections.singletonList(pd));
|
||||
}
|
||||
|
||||
private GeoPolygon buildConvexGeoPolygonWithHole(double lon1, double lat1,
|
||||
double lon2, double lat2,
|
||||
double lon3, double lat3,
|
||||
double lon4, double lat4,
|
||||
GeoPolygon hole) {
|
||||
GeoPoint point1 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(lat1), Math.toRadians(lon1));
|
||||
GeoPoint point2 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(lat2), Math.toRadians(lon2));
|
||||
GeoPoint point3 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(lat3), Math.toRadians(lon3));
|
||||
GeoPoint point4 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(lat4), Math.toRadians(lon4));
|
||||
final List<GeoPoint> points = new ArrayList<>();
|
||||
points.add(point1);
|
||||
points.add(point2);
|
||||
points.add(point3);
|
||||
points.add(point4);
|
||||
//return new GeoConvexPolygon(PlanetModel.SPHERE,points, Collections.singletonList(hole));
|
||||
return GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points, Collections.singletonList(hole));
|
||||
}
|
||||
|
||||
private GeoPolygon buildConcaveGeoPolygonWithHole(double lon1, double lat1,
|
||||
double lon2, double lat2,
|
||||
double lon3, double lat3,
|
||||
double lon4, double lat4,
|
||||
GeoPolygon hole) {
|
||||
GeoPoint point1 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(lat1), Math.toRadians(lon1));
|
||||
GeoPoint point2 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(lat2), Math.toRadians(lon2));
|
||||
GeoPoint point3 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(lat3), Math.toRadians(lon3));
|
||||
GeoPoint point4 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(lat4), Math.toRadians(lon4));
|
||||
final List<GeoPoint> points = new ArrayList<>();
|
||||
points.add(point1);
|
||||
points.add(point2);
|
||||
points.add(point3);
|
||||
points.add(point4);
|
||||
return GeoPolygonFactory.makeGeoConcavePolygon(PlanetModel.SPHERE, points, Collections.singletonList(hole));
|
||||
}
|
||||
|
||||
private GeoShape getCompositeShape(){
|
||||
//MULTIPOLYGON(((-145.790967486 -5.17543698881, -145.790854979 -5.11348060995, -145.853073512 -5.11339421216, -145.853192037 -5.17535061936, -145.790967486 -5.17543698881)),
|
||||
//((-145.8563923 -5.17527125408, -145.856222168 -5.11332154814, -145.918433943 -5.11317773171, -145.918610092 -5.17512738429, -145.8563923 -5.17527125408)))
|
||||
GeoPoint point1 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(-5.17543698881), Math.toRadians(-145.790967486));
|
||||
GeoPoint point2 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(-5.11348060995), Math.toRadians(-145.790854979));
|
||||
GeoPoint point3 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(-5.11339421216), Math.toRadians(-145.853073512));
|
||||
GeoPoint point4 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(-5.17535061936), Math.toRadians(-145.853192037));
|
||||
final List<GeoPoint> points1 = new ArrayList<>();
|
||||
points1.add(point1);
|
||||
points1.add(point2);
|
||||
points1.add(point3);
|
||||
points1.add(point4);
|
||||
GeoPolygon pol1 = GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE,points1);
|
||||
GeoPoint point5 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(-5.17527125408), Math.toRadians(-145.8563923));
|
||||
GeoPoint point6 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(-5.11332154814), Math.toRadians(-145.856222168));
|
||||
GeoPoint point7 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(-5.11317773171), Math.toRadians(-145.918433943));
|
||||
GeoPoint point8 = new GeoPoint(PlanetModel.SPHERE, Math.toRadians(-5.17512738429), Math.toRadians(-145.918610092));
|
||||
final List<GeoPoint> points2 = new ArrayList<>();
|
||||
points2.add(point5);
|
||||
points2.add(point6);
|
||||
points2.add(point7);
|
||||
points2.add(point8);
|
||||
GeoPolygon pol2 = GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points2);
|
||||
GeoCompositeMembershipShape composite = new GeoCompositeMembershipShape();
|
||||
composite.addShape(pol1);
|
||||
composite.addShape(pol2);
|
||||
return composite;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue