Returns true if polygon_a is disjoint from polyline_b.
351248
private static boolean polygonDisjointPolyline_(Polygon polygon_a,
			Polyline polyline_b, double tolerance,
			ProgressTracker progress_tracker) {
		// Quick rasterize test to see whether the the geometries are disjoint,
		// or if one is contained in the other.
		int relation = tryRasterizedContainsOrDisjoint_(polygon_a, polyline_b,
				tolerance, true);

		if (relation == Relation.disjoint)
			return true;

		if (relation == Relation.contains || relation == Relation.intersects)
			return false;

		return polygonDisjointMultiPath_(polygon_a, polyline_b, tolerance,
				progress_tracker);
	}
1024782
private static boolean multiPointDisjointMultiPoint_(
			MultiPoint multipoint_a, MultiPoint multipoint_b, double tolerance,
			ProgressTracker progress_tracker) {
		return !multiPointIntersectsMultiPoint_(multipoint_a, multipoint_b,
				tolerance, progress_tracker);
	}
73763
private static boolean polygonOverlapsPolygon_(Polygon polygon_a,
			Polygon polygon_b, double tolerance,
			ProgressTracker progress_tracker) {
		// Quick rasterize test to see whether the the geometries are disjoint,
		// or if one is contained in the other.
		int relation = tryRasterizedContainsOrDisjoint_(polygon_a, polygon_b,
				tolerance, false);

		if (relation == Relation.disjoint || relation == Relation.contains
				|| relation == Relation.within)
			return false;

		return polygonOverlapsPolygonImpl_(polygon_a, polygon_b, tolerance,
				progress_tracker);
	}
1170054
private static boolean polylineContainsMultiPoint_(Polyline polyline_a,
			MultiPoint multipoint_b, double tolerance,
			ProgressTracker progress_tracker) {
		Envelope2D env_a = new Envelope2D(), env_b = new Envelope2D();
		polyline_a.queryEnvelope2D(env_a);
		multipoint_b.queryEnvelope2D(env_b);

		if (!envelopeInfContainsEnvelope_(env_a, env_b, tolerance))
			return false;

		// Quick rasterize test to see whether the the geometries are disjoint.
		if (tryRasterizedContainsOrDisjoint_(polyline_a, multipoint_b,
				tolerance, false) == Relation.disjoint)
			return false;

		if (!linearPathIntersectsMultiPoint_(polyline_a, multipoint_b,
				tolerance, true))
			return false;

		MultiPoint boundary_a = (MultiPoint) (polyline_a.getBoundary());
		return !multiPointIntersectsMultiPoint_(boundary_a, multipoint_b,
				tolerance, progress_tracker);
	}
1125795
public static boolean disjoint(Geometry geometry1, Geometry geometry2,
			SpatialReference spatialReference) {
		OperatorDisjoint op = (OperatorDisjoint) factory
				.getOperator(Operator.Type.Disjoint);
		boolean result = op.execute(geometry1, geometry2, spatialReference,
				null);
		return result;
	}
995765
boolean areMiddlePointsClose( Point2D_F64 p0 , Point2D_F64 p1 , Point2D_F64 p2 , Point2D_F64 p3 ) {
		UtilLine2D_F64.convert(p0,p3,line);

		// (computed expected length of a square) * (fractional tolerance)
		double tol1 = p0.distance(p1)*distanceTol;

		// see if inner points are close to the line
		if(Distance2D_F64.distance(line, p1) > tol1 )
			return false;

		double tol2 = p2.distance(p3)*distanceTol;

		if( Distance2D_F64.distance(lineB, p2) > tol2 )
			return false;

		//------------ Now see if the line defined by one side of a square is close to the closest point on the same
		//             side on the other square
		UtilLine2D_F64.convert(p0,p1,line);
		if(Distance2D_F64.distance(line, p2) > tol2 )
			return false;

		UtilLine2D_F64.convert(p3,p2,line);
		if(Distance2D_F64.distance(line, p1) > tol1 )
			return false;

		return true;
	}
946640
private static boolean polygonDisjointPoint_(Polygon polygon_a,
			Point point_b, double tolerance, ProgressTracker progress_tracker) {
		PolygonUtils.PiPResult result = PolygonUtils.isPointInPolygon2D(
				polygon_a, point_b, tolerance);

		if (result == PolygonUtils.PiPResult.PiPOutside)
			return true;

		return false;
	}
648132
private static boolean polygonEqualsPolygon_(Polygon polygon_a,
			Polygon polygon_b, double tolerance,
			ProgressTracker progress_tracker) {
		Envelope2D env_a = new Envelope2D(), env_b = new Envelope2D();
		polygon_a.queryEnvelope2D(env_a);
		polygon_b.queryEnvelope2D(env_b);

		// Quick envelope rejection test for false equality.
		if (!envelopeEqualsEnvelope_(env_a, env_b, tolerance, progress_tracker))
			return false;

		// Quick rasterize test to see whether the the geometries are disjoint,
		// or if one is contained in the other.
		int relation = tryRasterizedContainsOrDisjoint_(polygon_a, polygon_b,
				tolerance, false);

		if (relation == Relation.disjoint || relation == Relation.contains
				|| relation == Relation.within)
			return false;

		// Quick point equality check for true equality. This just checks if all
		// the points in each ring are the same (within a tolerance) and in the
		// same order
		if (multiPathExactlyEqualsMultiPath_(polygon_a, polygon_b, tolerance,
				progress_tracker))
			return true;

		double length_a = polygon_a.calculateLength2D();
		double length_b = polygon_b.calculateLength2D();
		int max_vertices = Math.max(polygon_a.getPointCount(),
				polygon_b.getPointCount());

		if (Math.abs(length_a - length_b) > max_vertices * 4.0 * tolerance)
			return false;

		return linearPathEqualsLinearPath_(polygon_a, polygon_b, tolerance, true);
	}
58083
private static boolean polygonOverlapsEnvelope_(Polygon polygon_a,
			Envelope envelope_b, double tolerance,
			ProgressTracker progress_tracker) {
		// Quick rasterize test to see whether the the geometries are disjoint,
		// or if one is contained in the other.
		int relation = tryRasterizedContainsOrDisjoint_(polygon_a, envelope_b,
				tolerance, false);

		if (relation == Relation.disjoint || relation == Relation.contains
				|| relation == Relation.within)
			return false;

		Envelope2D env_a = new Envelope2D(), env_b = new Envelope2D();
		polygon_a.queryEnvelope2D(env_a);
		envelope_b.queryEnvelope2D(env_b);

		if (envelopeInfContainsEnvelope_(env_b, env_a, tolerance))
			return false;

		if (env_b.getWidth() <= tolerance || env_b.getHeight() <= tolerance)
			return false; // has no interior

		Polygon polygon_b = new Polygon();
		polygon_b.addEnvelope(envelope_b, false);
		return polygonOverlapsPolygonImpl_(polygon_a, polygon_b, tolerance,
				progress_tracker);
	}
1306972
private static boolean polygonContainsPolygon_(Polygon polygon_a,
			Polygon polygon_b, double tolerance,
			ProgressTracker progress_tracker) {
		Envelope2D env_a = new Envelope2D(), env_b = new Envelope2D();
		polygon_a.queryEnvelope2D(env_a);
		polygon_b.queryEnvelope2D(env_b);

		// Quick envelope rejection test for false equality.
		if (!envelopeInfContainsEnvelope_(env_a, env_b, tolerance))
			return false;

		// Quick rasterize test to see whether the the geometries are disjoint,
		// or if one is contained in the other.
		int relation = tryRasterizedContainsOrDisjoint_(polygon_a, polygon_b,
				tolerance, false);

		if (relation == Relation.disjoint || relation == Relation.within)
			return false;

		if (relation == Relation.contains)
			return true;

		return polygonContainsPolygonImpl_(polygon_a, polygon_b, tolerance,
				progress_tracker);
	}
655465
private static boolean polylineRelatePoint_(Polyline polyline_a,
			Point point_b, double tolerance, int relation,
			ProgressTracker progress_tracker) {
		switch (relation) {
		case Relation.disjoint:
			return polylineDisjointPoint_(polyline_a, point_b, tolerance,
					progress_tracker);

		case Relation.contains:
			return polylineContainsPoint_(polyline_a, point_b, tolerance,
					progress_tracker);

		case Relation.touches:
			return polylineTouchesPoint_(polyline_a, point_b, tolerance,
					progress_tracker);

		default:
			break; // warning fix
		}

		return false;
	}
721390
public boolean almostParallel(SquareNode a , int sideA , SquareNode b , int sideB ) {
		double selected = acuteAngle(a,sideA,b,sideB);

		if( selected > parallelThreshold )
			return false;

		// see if the two sides are about parallel too
//		double left = acuteAngle(a,add(sideA,-1),b,add(sideB,1));
//		double right = acuteAngle(a,add(sideA,1),b,add(sideB,-1));
//
//		if( left > selected+parallelThreshold || right > selected+parallelThreshold )
//			return false;


//		if( selected >  acuteAngle(a,sideA,b,add(sideB,1)) || selected >  acuteAngle(a,sideA,b,add(sideB,-1)) )
//			return false;
//
//		if( selected >  acuteAngle(a,add(sideA,1),b,sideB) || selected >  acuteAngle(a,add(sideA,-1),b,sideB) )
//			return false;

		return true;
	}
1204512
private static boolean polygonDisjointEnvelope_(Polygon polygon_a,
			Envelope envelope_b, double tolerance,
			ProgressTracker progress_tracker) {
		// Quick rasterize test to see whether the the geometries are disjoint,
		// or if one is contained in the other.
		int relation = tryRasterizedContainsOrDisjoint_(polygon_a, envelope_b,
				tolerance, false);

		if (relation == Relation.disjoint)
			return true;

		if (relation == Relation.contains || relation == Relation.within)
			return false;

		Envelope2D env_a = new Envelope2D(), env_b = new Envelope2D();
		polygon_a.queryEnvelope2D(env_a);
		envelope_b.queryEnvelope2D(env_b);

		if (envelopeInfContainsEnvelope_(env_b, env_a, tolerance))
			return false;

		PolygonUtils.PiPResult pipres;
		Point2D pt_b = new Point2D();
		env_b.queryLowerLeft(pt_b);
		pipres = PolygonUtils.isPointInPolygon2D(polygon_a, pt_b, tolerance);
		if (pipres != PolygonUtils.PiPResult.PiPOutside)
			return false;

		env_b.queryLowerRight(pt_b);
		pipres = PolygonUtils.isPointInPolygon2D(polygon_a, pt_b, tolerance);
		if (pipres != PolygonUtils.PiPResult.PiPOutside)
			return false;

		env_b.queryUpperRight(pt_b);
		pipres = PolygonUtils.isPointInPolygon2D(polygon_a, pt_b, tolerance);
		if (pipres != PolygonUtils.PiPResult.PiPOutside)
			return false;

		env_b.queryUpperLeft(pt_b);
		pipres = PolygonUtils.isPointInPolygon2D(polygon_a, pt_b, tolerance);
		if (pipres != PolygonUtils.PiPResult.PiPOutside)
			return false;

		MultiPathImpl mimpl_a = (MultiPathImpl) polygon_a._getImpl();
		AttributeStreamOfDbl pos = (AttributeStreamOfDbl) (mimpl_a
				.getAttributeStreamRef(VertexDescription.Semantics.POSITION));

		Envelope2D env_b_inflated = new Envelope2D();
		env_b_inflated.setCoords(env_b);
		env_b_inflated.inflate(tolerance, tolerance);
		for (int ptIndex = 0, n = mimpl_a.getPointCount(); ptIndex < n; ptIndex++) {
			double x = pos.read(2 * ptIndex);
			double y = pos.read(2 * ptIndex + 1);
			if (env_b_inflated.contains(x, y))
				return false;
		}

		return !linearPathIntersectsEnvelope_(polygon_a, env_b, tolerance,
				progress_tracker);
	}
424615
private static boolean polygonTouchesEnvelope_(Polygon polygon_a,
			Envelope envelope_b, double tolerance,
			ProgressTracker progress_tracker) {
		// Quick rasterize test to see whether the the geometries are disjoint,
		// or if one is contained in the other.
		int relation = tryRasterizedContainsOrDisjoint_(polygon_a, envelope_b,
				tolerance, false);

		if (relation == Relation.disjoint || relation == Relation.contains
				|| relation == Relation.within)
			return false;

		Envelope2D env_a = new Envelope2D(), env_b = new Envelope2D();
		polygon_a.queryEnvelope2D(env_a);
		envelope_b.queryEnvelope2D(env_b);

		if (envelopeInfContainsEnvelope_(env_b, env_a, tolerance))
			return false;

		if (env_b.getWidth() <= tolerance && env_b.getHeight() <= tolerance) {// treat
																				// as
																				// point
			Point2D pt_b = envelope_b.getCenterXY();
			return polygonTouchesPointImpl_(polygon_a, pt_b, tolerance,
					progress_tracker);
		}

		if (env_b.getWidth() <= tolerance || env_b.getHeight() <= tolerance) {// treat
																				// as
																				// polyline
			Polyline polyline_b = new Polyline();
			Point p = new Point();
			envelope_b.queryCornerByVal(0, p);
			polyline_b.startPath(p);
			envelope_b.queryCornerByVal(2, p);
			polyline_b.lineTo(p);
			return polygonTouchesPolylineImpl_(polygon_a, polyline_b,
					tolerance, progress_tracker);
		}

		// treat as polygon
		Polygon polygon_b = new Polygon();
		polygon_b.addEnvelope(envelope_b, false);
		return polygonTouchesPolygonImpl_(polygon_a, polygon_b, tolerance,
				progress_tracker);
	}
236960
static boolean polylineRelatePolyline_(Polyline polyline_a,
			Polyline polyline_b, double tolerance, String scl,
			ProgressTracker progress_tracker) {
		RelationalOperationsMatrix relOps = new RelationalOperationsMatrix();
		relOps.resetMatrix_();
		relOps.setPredicates_(scl);
		relOps.setLineLinePredicates_();

		Envelope2D env_a = new Envelope2D(), env_b = new Envelope2D();
		polyline_a.queryEnvelope2D(env_a);
		polyline_b.queryEnvelope2D(env_b);

		boolean bRelationKnown = false;
		boolean b_disjoint = RelationalOperations.envelopeDisjointEnvelope_(
				env_a, env_b, tolerance, progress_tracker);

		if (b_disjoint) {
			relOps.lineLineDisjointPredicates_(polyline_a, polyline_b);
			bRelationKnown = true;
		}

		if (!bRelationKnown) {
			// Quick rasterize test to see whether the the geometries are
			// disjoint, or if one is contained in the other.
			int relation = RelationalOperations
					.tryRasterizedContainsOrDisjoint_(polyline_a, polyline_b,
							tolerance, false);

			if (relation == RelationalOperations.Relation.disjoint) {
				relOps.lineLineDisjointPredicates_(polyline_a, polyline_b);
				bRelationKnown = true;
			}
		}

		if (!bRelationKnown) {
			EditShape edit_shape = new EditShape();
			int geom_a = edit_shape.addGeometry(polyline_a);
			int geom_b = edit_shape.addGeometry(polyline_b);
			relOps.setEditShapeCrackAndCluster_(edit_shape, tolerance,
					progress_tracker);
			relOps.m_cluster_index_a = relOps.m_topo_graph
					.createUserIndexForClusters();
			relOps.m_cluster_index_b = relOps.m_topo_graph
					.createUserIndexForClusters();
			markClusterEndPoints_(geom_a, relOps.m_topo_graph,
					relOps.m_cluster_index_a);
			markClusterEndPoints_(geom_b, relOps.m_topo_graph,
					relOps.m_cluster_index_b);
			relOps.computeMatrixTopoGraphHalfEdges_(geom_a, geom_b);
			relOps.m_topo_graph
					.deleteUserIndexForClusters(relOps.m_cluster_index_a);
			relOps.m_topo_graph
					.deleteUserIndexForClusters(relOps.m_cluster_index_b);
			relOps.m_topo_graph.removeShape();
		}

		boolean bRelation = relationCompare_(relOps.m_matrix, relOps.m_scl);
		return bRelation;
	}
756415
private static boolean polygonDisjointMultiPath_(Polygon polygon_a,
			MultiPath multipath_b, double tolerance,
			ProgressTracker progress_tracker) {
        Point2D pt_a, pt_b;
        Envelope2D env_a_inf = new Envelope2D(), env_b_inf = new Envelope2D();

        MultiPathImpl multi_path_impl_a = (MultiPathImpl)polygon_a._getImpl();
        MultiPathImpl multi_path_impl_b = (MultiPathImpl)multipath_b._getImpl();

        PairwiseIntersectorImpl intersector = new PairwiseIntersectorImpl(multi_path_impl_a, multi_path_impl_b, tolerance, true);

        if (!intersector.next())
            return true; // no rings intersect

        boolean b_intersects = linearPathIntersectsLinearPath_(polygon_a, multipath_b, tolerance);

        if (b_intersects)
            return false;

        Polygon pa = null;
        Polygon p_polygon_a = polygon_a;

        Polygon pb = null;
        Polygon p_polygon_b = null;

        if (multipath_b.getType().value() == Geometry.GeometryType.Polygon)
            p_polygon_b = (Polygon)multipath_b;

        boolean b_checked_polygon_a_quad_tree = false;
        boolean b_checked_polygon_b_quad_tree = false;

        do
        {
            int path_a = intersector.getRedElement();
            int path_b = intersector.getBlueElement();

            pt_b = multipath_b.getXY(multipath_b.getPathStart(path_b));
            env_a_inf.setCoords(intersector.getRedEnvelope());
            env_a_inf.inflate(tolerance, tolerance);

            if (env_a_inf.contains(pt_b))
            {
                PolygonUtils.PiPResult result = PolygonUtils.isPointInPolygon2D(p_polygon_a, pt_b, 0.0);

                if (result != PolygonUtils.PiPResult.PiPOutside)
                    return false;
            }

            if (multipath_b.getType().value() == Geometry.GeometryType.Polygon)
            {
                pt_a = polygon_a.getXY(polygon_a.getPathStart(path_a));
                env_b_inf.setCoords(intersector.getBlueEnvelope());
                env_b_inf.inflate(tolerance, tolerance);

                if (env_b_inf.contains(pt_a))
                {
                    PolygonUtils.PiPResult result = PolygonUtils.isPointInPolygon2D(p_polygon_b, pt_a, 0.0);

                    if (result != PolygonUtils.PiPResult.PiPOutside)
                        return false;
                }
            }

            if (!b_checked_polygon_a_quad_tree) {
                if (PointInPolygonHelper.quadTreeWillHelp(polygon_a, multipath_b.getPathCount() - 1) && (multi_path_impl_a._getAccelerators() == null || multi_path_impl_a._getAccelerators().getQuadTree() == null)) {
                    pa = new Polygon();
                    polygon_a.copyTo(pa);
                    ((MultiPathImpl) pa._getImpl())._buildQuadTreeAccelerator(Geometry.GeometryAccelerationDegree.enumMedium);
                    p_polygon_a = pa;
                } else {
                    p_polygon_a = polygon_a;
                }

                b_checked_polygon_a_quad_tree = true;
            }

            if (multipath_b.getType().value() == Geometry.GeometryType.Polygon)
            {
                if (!b_checked_polygon_b_quad_tree) {
                    Polygon polygon_b = (Polygon) multipath_b;
                    if (PointInPolygonHelper.quadTreeWillHelp(polygon_b, polygon_a.getPathCount() - 1) && (multi_path_impl_b._getAccelerators() == null || multi_path_impl_b._getAccelerators().getQuadTree() == null)) {
                        pb = new Polygon();
                        polygon_b.copyTo(pb);
                        ((MultiPathImpl) pb._getImpl())._buildQuadTreeAccelerator(Geometry.GeometryAccelerationDegree.enumMedium);
                        p_polygon_b = pb;
                    } else {
                        p_polygon_b = (Polygon) multipath_b;
                    }

                    b_checked_polygon_b_quad_tree = true;
                }
            }

        } while (intersector.next());

        return true;
	}
1345720
static boolean polygonRelateMultiPoint_(Polygon polygon_a,
			MultiPoint multipoint_b, double tolerance, String scl,
			ProgressTracker progress_tracker) {
		RelationalOperationsMatrix relOps = new RelationalOperationsMatrix();
		relOps.resetMatrix_();
		relOps.setPredicates_(scl);
		relOps.setAreaPointPredicates_();

		Envelope2D env_a = new Envelope2D(), env_b = new Envelope2D();
		polygon_a.queryEnvelope2D(env_a);
		multipoint_b.queryEnvelope2D(env_b);

		boolean bRelationKnown = false;
		boolean b_disjoint = RelationalOperations.envelopeDisjointEnvelope_(
				env_a, env_b, tolerance, progress_tracker);

		if (b_disjoint) {
			relOps.areaPointDisjointPredicates_(polygon_a);
			bRelationKnown = true;
		}

		if (!bRelationKnown) {
			// Quick rasterize test to see whether the the geometries are
			// disjoint, or if one is contained in the other.
			int relation = RelationalOperations
					.tryRasterizedContainsOrDisjoint_(polygon_a, multipoint_b,
							tolerance, false);

			if (relation == RelationalOperations.Relation.disjoint) {
				relOps.areaPointDisjointPredicates_(polygon_a);
				bRelationKnown = true;
			} else if (relation == RelationalOperations.Relation.contains) {
				relOps.areaPointContainsPredicates_(polygon_a);
				bRelationKnown = true;
			}
		}

		if (!bRelationKnown) {
			EditShape edit_shape = new EditShape();
			int geom_a = edit_shape.addGeometry(polygon_a);
			int geom_b = edit_shape.addGeometry(multipoint_b);
			relOps.setEditShapeCrackAndCluster_(edit_shape, tolerance,
					progress_tracker);
			relOps.computeMatrixTopoGraphClusters_(geom_a, geom_b);
			relOps.m_topo_graph.removeShape();
		}

		boolean bRelation = relationCompare_(relOps.m_matrix, relOps.m_scl);
		return bRelation;
	}