private IBox CreateSearchBox([NotNull] IPnt point)
        {
            double e = SearchDistance;

            return(GeomUtils.CreateBox(point.X - e, point.Y - e,
                                       point.X + e, point.Y + e));
        }
Exemple #2
0
        private static void GetClosePart([NotNull] SegmentProxy neighbor,
                                         [NotNull] IPnt near,
                                         double searchDistanceSquared, bool is3D,
                                         out double min, out double max)
        {
            IList <double[]> limits;
            Pnt  p   = Pnt.Create(near);
            bool cut = SegmentUtils.CutCurveCircle(neighbor, p, searchDistanceSquared, is3D,
                                                   out limits);

            if (cut == false || limits.Count == 0)
            {
                min = SegmentUtils.GetClosestPointFraction(neighbor, p, is3D);
                max = min;
            }
            else
            {
                min = double.MaxValue;
                max = double.MinValue;
                foreach (double[] limit in limits)
                {
                    foreach (double d in limit)
                    {
                        min = Math.Min(d, min);
                        max = Math.Max(d, max);
                    }
                }
            }

            min = Math.Max(min, 0);
            max = Math.Max(max, 0);
            min = Math.Min(min, 1);
            max = Math.Min(max, 1);
        }
        private int ReportZDiffersCoincidentEdge(
            [NotNull] IPnt point,
            double zTolerance, double deltaZ,
            [NotNull] ISpatialReference spatialReference,
            params IFeature[] features)
        {
            bool sameFeature = features.Length == 1;

            string format =
                sameFeature
                                        ? LocalizableStrings
                .VertexCoincidenceChecker_ZDifference_CoincidentEdge_SameFeature
                                        : LocalizableStrings
                .VertexCoincidenceChecker_ZDifference_CoincidentEdge_DifferentFeature;
            string code = sameFeature
                                              ? Code.ZDifference_CoincidentEdge_SameFeature
                                              : Code.ZDifference_CoincidentEdge_DifferentFeature;

            string description = string.Format(format,
                                               _formatComparisonFunction(Math.Abs(deltaZ), ">",
                                                                         zTolerance, "N2"));

            return(_errorReporting.Report(description,
                                          CreateErrorGeometry(point, spatialReference),
                                          Codes[code],
                                          GetAffectedComponent(features),
                                          new object[] { Math.Abs(deltaZ) },
                                          features.Cast <IRow>().ToArray()));
        }
            private int InitPlaneOffsets(bool reportErrors,
                                         [CanBeNull] IFeature involvedFeature)
            {
                const int noError = 0;

                if (_minOffset <= 0 && _maxOffset >= 0)
                {
                    return(noError);
                }

                Plane3D plane      = Plane;
                var     unitNormal = UnitNormal;

                // double nf = plane.Nf;

                _minOffset = 0;
                _maxOffset = 0;
                var segmentsCount = 0;

                foreach (SegmentProxy segment in SegmentsPlane.Segments)
                {
                    segmentsCount++;
                    IPnt point = segment.GetStart(true);
                    // double f = normal.X * point.X + normal.Y * point.Y + normal.Z * point[2] + nf;
                    double distanceSigned =
                        plane.GetDistanceSigned(point.X, point.Y, point[2]);
                    double offset = Math.Abs(distanceSigned);

                    if (distanceSigned > 0 == unitNormal[2] > 0
                        )                 // oriented same as normal
                    {
                        _maxOffset = Math.Max(offset, _maxOffset);
                    }
                    else
                    {
                        _minOffset = Math.Min(-offset, _minOffset);
                    }
                }

                var coplanarityTolerance = GeomUtils.AdjustCoplanarityTolerance(
                    plane, _parent.CoplanarityTolerance,
                    _parent._zSrTolerance, _parent._xySrTolerance);

                double maxOffset = Math.Max(Math.Abs(_maxOffset), Math.Abs(_minOffset));

                _coplanar = maxOffset < coplanarityTolerance;

                if (_coplanar || !reportErrors || involvedFeature == null)
                {
                    return(noError);
                }

                IMultiPatch errorGeometry =
                    SegmentUtils.CreateMultiPatch(SegmentsPlane.Segments);

                return(_parent.ReportNonCoplanarFace(segmentsCount, maxOffset,
                                                     errorGeometry, involvedFeature));
            }
        private static IPoint CreateErrorGeometry(
            [NotNull] IPnt point,
            [NotNull] ISpatialReference spatialReference)
        {
            IPoint result = new PointClass();

            result.PutCoords(point.X, point.Y);
            result.Z = point[2];
            result.SpatialReference = spatialReference;

            return(result);
        }
            public double GetPointDistance([NotNull] IPnt vertex)
            {
                Pnt difference = Point - vertex;

                double distance2D;

                if (MathUtils.AreSignificantDigitsEqual(Point.X, vertex.X))
                {
                    distance2D = MathUtils.AreSignificantDigitsEqual(Point.Y, vertex.Y)
                                                             ? 0
                                                             : Math.Abs(difference.Y);
                }
                else if (MathUtils.AreSignificantDigitsEqual(Point.Y, vertex.Y))
                {
                    distance2D = MathUtils.AreSignificantDigitsEqual(Point.X, vertex.X)
                                                             ? 0
                                                             : Math.Abs(difference.X);
                }
                else
                {
                    // both differences are significant
                    double distanceSquared = difference.X * difference.X +
                                             difference.Y * difference.Y;

                    if (As3D)
                    {
                        if (!MathUtils.AreSignificantDigitsEqual(Point[2], vertex[2]))
                        {
                            distanceSquared += difference[2] * difference[2];
                        }
                    }

                    return(Math.Sqrt(distanceSquared));
                }

                if (As3D)
                {
                    double distanceSquared = distance2D * distance2D;

                    if (!MathUtils.AreSignificantDigitsEqual(Point[2], vertex[2]))
                    {
                        distanceSquared += difference[2] * difference[2];
                    }

                    return(Math.Sqrt(distanceSquared));
                }

                return(distance2D);
            }
            public override IPnt GetNearestEdgePoint(out bool isVertex)
            {
                double fraction = Fraction;

                if (fraction < 0 || fraction > 1)
                {
                    isVertex = true;
                    return(GetNearestVertex());
                }

                isVertex = fraction <= 0 || fraction >= 1;
                IPnt edgePoint = _segmentProxy.GetPointAt(fraction, as3D: true);

                return(edgePoint);
            }
        private bool IsCoincident([NotNull] PlaneHelper planeHelper,
                                  [NotNull] Pnt point,
                                  double xyTolerance)
        {
            double near  = Math.Max(xyTolerance, PointCoincidence);
            double near2 = near * near;

            double nearEdge2 = 0;

            if (EdgeCoincidence > 0)
            {
                double nearEdge = Math.Max(xyTolerance, EdgeCoincidence);
                nearEdge2 = nearEdge * nearEdge;
            }

            const bool as3D = true;

            foreach (SegmentProxy segment in planeHelper.GetSegments())
            {
                if (segment.GetStart(as3D).Dist2(point) < near2)
                {
                    return(true);
                }

                if (EdgeCoincidence > 0)
                {
                    double fraction =
                        SegmentUtils.GetClosestPointFraction(segment, point, as3D);
                    if (fraction >= 0 && fraction <= 1)
                    {
                        IPnt edgePoint = segment.GetPointAt(fraction, as3D);

                        if (point.Dist2(edgePoint) < nearEdge2)
                        {
                            return(true);
                        }
                    }
                }
            }

            return(false);
        }
Exemple #9
0
        private static void GetClosePart([NotNull] SegmentProxy neighbor,
                                         [NotNull] IIndexedSegments geom,
                                         [NotNull] SegmentPart segPart,
                                         double searchDistanceSquared, bool is3D,
                                         out double min, out double max)
        {
            SegmentProxy part = geom.GetSegment(segPart.PartIndex, segPart.SegmentIndex);
            IPnt         start = part.GetPointAt(segPart.MinFraction);
            double       minStart, maxStart;

            GetClosePart(neighbor, start, searchDistanceSquared, is3D, out minStart,
                         out maxStart);

            IPnt   end = part.GetPointAt(segPart.MaxFraction);
            double minEnd, maxEnd;

            GetClosePart(neighbor, end, searchDistanceSquared, is3D, out minEnd, out maxEnd);

            min = Math.Min(minStart, minEnd);
            max = Math.Max(maxStart, maxEnd);
        }
        private int ReportNearbyEdgeNotPassingThroughVertex(
            [NotNull] IPnt point,
            double edgeTolerance,
            double edgeDistance,
            [NotNull] ISpatialReference spatialReference,
            params IFeature[] features)
        {
            bool sameFeature = features.Length == 1;

            string format =
                sameFeature
                                        ? LocalizableStrings
                .VertexCoincidenceChecker_NearbyEdgeNotPassingThroughVertex_SameFeature
                                        : LocalizableStrings
                .VertexCoincidenceChecker_NearbyEdgeNotPassingThroughVertex_DifferentFeature;
            string code = sameFeature
                                              ? Code.NearbyEdgeNotPassingThroughVertex_SameFeature
                                              : Code.NearbyEdgeNotPassingThroughVertex_DifferentFeature;

            string description = string.Format(format,
                                               FormatComparison(edgeDistance, edgeTolerance));

            if (ReportCoordinates)
            {
                description = description +
                              string.Format(
                    LocalizableStrings
                    .VertexCoincidenceChecker_NearbyEdgeNotPassingThroughVertex_ReportCoordinatesSuffix,
                    point.X, point.Y);
            }

            return(_errorReporting.Report(description,
                                          CreateErrorGeometry(point, spatialReference),
                                          Codes[code],
                                          GetAffectedComponent(features),
                                          new object[] { edgeDistance },
                                          features.Cast <IRow>().ToArray()));
        }
        private int CheckCoincidenceSameFeature(
            [NotNull] IPnt point,
            [NotNull] IFeature feature,
            [NotNull] IEnumerable <Proximity> proximities,
            double pointTolerance,
            double edgeTolerance,
            [NotNull] ISpatialReference spatialReference)
        {
            double closestEdgeDistance = double.MaxValue;
            double closestEdgeDeltaZ   = 0;

            double?zCoincidenceTolerance = null;

            foreach (Proximity proximity in proximities)
            {
                if (pointTolerance > 0)
                {
                    IPnt   nearestVertex  = proximity.GetNearestVertex();
                    double vertexDistance = proximity.GetPointDistance(nearestVertex);

                    if (vertexDistance < pointTolerance)
                    {
                        if (Math.Abs(vertexDistance) < double.Epsilon)
                        {
                            // probably the same vertex (can't be sure though!)
                        }
                        else if (vertexDistance > CoincidenceTolerance)
                        {
                            // not coincident
                            return(ReportNearbyVertexNotCoincident(point, nearestVertex,
                                                                   pointTolerance,
                                                                   vertexDistance, spatialReference,
                                                                   feature));
                        }

                        if (CheckZ)
                        {
                            double deltaZ = nearestVertex[2] - proximity.Point[2];
                            zCoincidenceTolerance = zCoincidenceTolerance ??
                                                    GetZCoincidenceTolerance(new[] { feature });
                            if (IsInvalidDeltaZ(deltaZ, zCoincidenceTolerance.Value))
                            {
                                return(ReportZDiffersCoincidentVertex(
                                           point, zCoincidenceTolerance.Value,
                                           deltaZ,
                                           spatialReference, feature));
                            }
                        }
                    }
                }

                if (edgeTolerance > 0)
                {
                    bool   isVertex;
                    IPnt   nearestEdgePoint = proximity.GetNearestEdgePoint(out isVertex);
                    double edgeDistance     = proximity.GetPointDistance(nearestEdgePoint);

                    if (edgeDistance < edgeTolerance)
                    {
                        if (!isVertex && edgeDistance < closestEdgeDistance)
                        {
                            closestEdgeDistance = edgeDistance;
                            if (CheckZ)
                            {
                                closestEdgeDeltaZ = nearestEdgePoint[2] - proximity.Point[2];
                            }
                        }
                    }
                }
            }

            if (closestEdgeDistance < edgeTolerance)
            {
                // there is a nearby edge within the edge tolerance

                if (RequireVertexOnNearbyEdge)
                {
                    // and that is never allowed (without a coincident vertex)
                    return(ReportNoVertexOnNearbyEdge(point, edgeTolerance,
                                                      closestEdgeDistance,
                                                      spatialReference, feature));
                }

                if (closestEdgeDistance > CoincidenceTolerance)
                {
                    // the nearby edge does not pass through the vertex
                    return(ReportNearbyEdgeNotPassingThroughVertex(
                               point, edgeTolerance, closestEdgeDistance,
                               spatialReference, feature));
                }

                if (CheckZ)
                {
                    zCoincidenceTolerance = zCoincidenceTolerance ??
                                            GetZCoincidenceTolerance(new[] { feature });

                    if (IsInvalidDeltaZ(closestEdgeDeltaZ, zCoincidenceTolerance.Value))
                    {
                        return(ReportZDiffersCoincidentEdge(point, zCoincidenceTolerance.Value,
                                                            closestEdgeDeltaZ,
                                                            spatialReference, feature));
                    }
                }
            }

            return(_noError);
        }
        private int CheckCoincidenceDifferentFeatures(
            [NotNull] IPnt point,
            [NotNull] IFeature feature,
            [NotNull] IFeature nearFeature,
            [NotNull] IEnumerable <Proximity> proximities,
            double pointTolerance,
            double edgeTolerance,
            [NotNull] ISpatialReference spatialReference)
        {
            double closestPointDistance = double.MaxValue;
            double closestEdgeDistance  = double.MaxValue;
            double closestEdgeDeltaZ    = 0;

            double epsilon =
                MathUtils.GetDoubleSignificanceEpsilon(Math.Max(Math.Abs(point.X),
                                                                Math.Abs(point.Y)));
            Pnt closestPoint = null;

            foreach (Proximity proximity in proximities)
            {
                if (pointTolerance > 0)
                {
                    Pnt    nearestVertex  = proximity.GetNearestVertex();
                    double vertexDistance = proximity.GetPointDistance(nearestVertex);

                    if (MathUtils.IsWithinTolerance(vertexDistance, pointTolerance, epsilon))
                    {
                        closestPointDistance = Math.Min(vertexDistance, closestPointDistance);
                        closestPoint         = nearestVertex;

                        if (MathUtils.IsWithinTolerance(closestPointDistance, CoincidenceTolerance,
                                                        epsilon))
                        {
                            // there is at least one close enough point on the near feature

                            if (CheckZ)
                            {
                                // ReSharper disable once ConvertToConstant.Local
                                double deltaZ = nearestVertex[2] - proximity.Point[2];
                                double zCoincidenceTolerance =
                                    GetZCoincidenceTolerance(new[] { feature, nearFeature });

                                // get delta Z (also if is3D = false !!!!)
                                if (IsInvalidDeltaZ(deltaZ, zCoincidenceTolerance))
                                {
                                    return(ReportZDiffersCoincidentVertex(
                                               point, zCoincidenceTolerance,
                                               deltaZ,
                                               spatialReference, feature, nearFeature));
                                }
                            }

                            return(_noError);
                        }
                    }
                }

                if (edgeTolerance > 0)
                {
                    bool   isVertex;
                    IPnt   nearestEdgePoint = proximity.GetNearestEdgePoint(out isVertex);
                    double edgeDistance     = proximity.GetPointDistance(nearestEdgePoint);

                    if (!isVertex && edgeDistance < closestEdgeDistance)
                    {
                        closestEdgeDistance = edgeDistance;

                        if (CheckZ)
                        {
                            closestEdgeDeltaZ = nearestEdgePoint[2] - proximity.Point[2];
                        }
                    }
                }
            }

            if (MathUtils.IsWithinTolerance(closestPointDistance, pointTolerance, epsilon) &&
                !MathUtils.IsWithinTolerance(closestPointDistance, CoincidenceTolerance,
                                             epsilon))
            {
                Assert.NotNull(closestPoint);
                return(ReportNearbyVertexNotCoincident(point, closestPoint,
                                                       pointTolerance,
                                                       closestPointDistance,
                                                       spatialReference,
                                                       feature, nearFeature));
            }

            if (MathUtils.IsWithinTolerance(closestEdgeDistance, edgeTolerance, epsilon))
            {
                // there is a nearby edge within the edge tolerance

                if (RequireVertexOnNearbyEdge)
                {
                    // and that is never allowed (without a coincident vertex)

                    // the nearby edge does not have a vertex
                    return(ReportNoVertexOnNearbyEdge(point,
                                                      edgeTolerance, closestEdgeDistance,
                                                      spatialReference, feature, nearFeature));
                }

                if (!MathUtils.IsWithinTolerance(closestEdgeDistance, CoincidenceTolerance,
                                                 epsilon))
                {
                    // the nearby edge does not pass through the vertex
                    return(ReportNearbyEdgeNotPassingThroughVertex(point, edgeTolerance,
                                                                   closestEdgeDistance,
                                                                   spatialReference, feature,
                                                                   nearFeature));
                }

                if (CheckZ)
                {
                    double zCoincidenceTolerance =
                        GetZCoincidenceTolerance(new[] { feature, nearFeature });
                    if (IsInvalidDeltaZ(closestEdgeDeltaZ, zCoincidenceTolerance))
                    {
                        return(ReportZDiffersCoincidentEdge(point, zCoincidenceTolerance,
                                                            closestEdgeDeltaZ,
                                                            spatialReference, feature,
                                                            nearFeature));
                    }
                }

                // the closest edge on the near feature is near enough
                return(_noError);
            }

            return(_noError);
        }
Exemple #13
0
        private static double GetDistanceToCurve(
            [NotNull] IPoint point,
            [NotNull] IFeature neighbourFeature,
            [NotNull] IPoint nearestPoint,
            double maxNeededDistance,
            out bool onRightSide)
        {
            var neighborCurve = (ICurve)neighbourFeature.Shape;

            if (UseQueryPointAndDistance)
            {
                const bool asRatio   = false;
                double     along     = 0;
                double     distance  = 0;
                var        rightSide = false;

                // TLMQA-292 (EBG - BB): most time spent here (> 90%)
                neighborCurve.QueryPointAndDistance(esriSegmentExtension.esriNoExtension,
                                                    point, asRatio, nearestPoint,
                                                    ref along, ref distance, ref rightSide);
                onRightSide = rightSide;
                return(distance);
            }

            {
                double       nearestDistance    = maxNeededDistance * 1.01;
                bool?        nearestOnRightSide = null;
                SegmentProxy nearestSegment     = null;
                double       nearestFraction    = 0;

                double x;
                double y;
                point.QueryCoords(out x, out y);
                Pnt qaPoint = new Pnt2D(x, y);
                foreach (SegmentProxy segmentProxy in
                         EnumSegments(qaPoint, neighbourFeature, maxNeededDistance))
                {
                    bool?  onSegmentRightSide;
                    double alongFraction;
                    double offset = GetOffset(qaPoint, segmentProxy,
                                              out alongFraction, out onSegmentRightSide);
                    if (offset <= nearestDistance)
                    {
                        if (!onSegmentRightSide.HasValue && !nearestOnRightSide.HasValue &&
                            nearestSegment != null)
                        {
                            nearestOnRightSide = GetOnRightSide(
                                nearestSegment, nearestFraction, segmentProxy, alongFraction,
                                neighborCurve);
                        }
                        else if (offset < nearestDistance)
                        {
                            nearestOnRightSide = onSegmentRightSide;
                        }

                        nearestDistance = offset;
                        nearestSegment  = segmentProxy;
                        nearestFraction = alongFraction;
                    }
                }

                if (nearestSegment != null)
                {
                    double f = Math.Min(1, Math.Max(0, nearestFraction));
                    IPnt   p = nearestSegment.GetPointAt(f, as3D: true);
                    nearestPoint.PutCoords(p.X, p.Y);
                    nearestPoint.Z = p[2];

                    if (!nearestOnRightSide.HasValue)
                    {
                        // Extend segment lineary to determine right side
                        Pnt s = nearestSegment.GetStart(as3D: false);
                        Pnt e = nearestSegment.GetEnd(as3D: false);

                        if (nearestFraction >= 1)
                        {
                            nearestOnRightSide = (e - s).VectorProduct(e - qaPoint) > 0;
                        }
                        else if (nearestFraction <= 0)
                        {
                            nearestOnRightSide = (e - s).VectorProduct(s - qaPoint) > 0;
                        }
                    }
                }

                onRightSide = nearestOnRightSide ?? false;
                return(nearestDistance);
            }
        }
Exemple #14
0
        protected override int ExecuteCore(IRow row, int tableIndex)
        {
            int errorCount = 0;
            var feature    = row as IFeature;

            if (feature == null)
            {
                return(errorCount);
            }

            var geometryCollection = feature.Shape as IGeometryCollection;

            if (geometryCollection == null)
            {
                return(errorCount);
            }

            SegmentsPlaneProvider segmentsPlaneProvider = GetPlaneProvider(feature);
            SegmentsPlane         segmentsPlane;

            while ((segmentsPlane = segmentsPlaneProvider.ReadPlane()) != null)
            {
                Plane3D plane;
                try
                {
                    plane = segmentsPlane.Plane;
                }
                catch (Exception e)
                {
                    errorCount += ReportInvalidPlane(
                        $"Unable to determine plane: {e.Message}", segmentsPlane,
                        feature);
                    continue;
                }

                if (!plane.IsDefined)
                {
                    errorCount += ReportInvalidPlane(
                        "The segments of this face are collinear and do not define a valid plane",
                        segmentsPlane, feature);
                    continue;
                }

                double coplanarityTolerance = GeomUtils.AdjustCoplanarityTolerance(plane,
                                                                                   _coplanarityTolerance,
                                                                                   _zResolution,
                                                                                   _xyResolution);

                double maxOffset     = -1;
                int    segmentsCount = 0;
                foreach (SegmentProxy segment in segmentsPlane.Segments)
                {
                    segmentsCount++;

                    IPnt point = segment.GetStart(true);
                    //double f = normal.X * point.X + normal.Y * point.Y +
                    //           normalZ * point[2] + nf;

                    // double offset = Math.Abs(f);
                    double offset = plane.GetDistanceAbs(point.X, point.Y, point[2]);

                    if (offset <= coplanarityTolerance)
                    {
                        continue;
                    }

                    maxOffset = Math.Max(offset, maxOffset);
                }

                if (segmentsCount < 3)
                {
                    // TODO no need to check here once the plane is undefined in this case --> REMOVE
                    const string description =
                        "The segments of this face are collinear and do not define a valid plane";
                    IGeometry errorGeometry = GetErrorGeometry(feature.Shape.GeometryType,
                                                               segmentsPlane.Segments);
                    errorCount += ReportError(description, errorGeometry,
                                              Codes[Code.FaceDoesNotDefineValidPlane],
                                              null,
                                              row);
                    continue;
                }

                if (maxOffset > 0)
                {
                    string comparison = FormatLengthComparison(
                        maxOffset, ">", _coplanarityTolerance,
                        feature.Shape.SpatialReference);
                    string description =
                        $"Face with {segmentsCount} segments is not planar, max. offset = {comparison}";
                    IGeometry errorGeometry = GetErrorGeometry(feature.Shape.GeometryType,
                                                               segmentsPlane.Segments);
                    errorCount += ReportError(description, errorGeometry,
                                              Codes[Code.FaceNotCoplanar],
                                              TestUtils.GetShapeFieldName(feature),
                                              InvolvedRowUtils.GetInvolvedRows(row),
                                              new object[] { maxOffset });
                }
            }

            return(errorCount);
        }
Exemple #15
0
        public IList <IRow> Search([NotNull] ITable table,
                                   int tableIndex,
                                   [NotNull] IQueryFilter queryFilter,
                                   [NotNull] QueryFilterHelper filterHelper,
                                   [CanBeNull] IGeometry cacheGeometry)
        {
            var       spatialFilter  = (ISpatialFilter)queryFilter;
            IGeometry filterGeometry = spatialFilter.Geometry;

            IList <IRow> result = new List <IRow>();

            // TODO explain network queries
            bool repeatCachedRows = filterHelper.ForNetwork;

            // filterHelper.PointSearchOnlyWithinTile
            if (filterHelper.ForNetwork)
            {
                var filterPoint = filterGeometry as IPoint;
                if (filterPoint != null)
                {
                    // search only if the point is within the tile box
                    // (or left/below of test run box)

                    double x;
                    double y;
                    filterPoint.QueryCoords(out x, out y);

                    Pnt  tileMin    = CurrentTileBox.Min;
                    Pnt  tileMax    = CurrentTileBox.Max;
                    IPnt testRunMin = _testRunBox.Min;

                    if ((x <= tileMin.X && x > testRunMin.X) || x > tileMax.X ||
                        (y <= tileMin.Y && y > testRunMin.Y) || y > tileMax.Y)
                    {
                        // outside of tile box, return empty list
                        return(result);
                    }
                }
            }

            List <BoxTree <CachedRow> .TileEntry> searchList = SearchList(filterGeometry,
                                                                          tableIndex);

            if (searchList == null || searchList.Count == 0)
            {
                return(result);
            }

            var cacheGeometryOverlapsLeftTile   = false;
            var cacheGeometryOverlapsBottomTile = false;

            if (!repeatCachedRows)
            {
                if (cacheGeometry != null)
                {
                    cacheGeometry.QueryEnvelope(_envelopeTemplate);
                }
                else
                {
                    filterGeometry.QueryEnvelope(_envelopeTemplate);
                }

                double xmin;
                double ymin;
                double xmax;
                double ymax;
                _envelopeTemplate.QueryCoords(out xmin, out ymin, out xmax, out ymax);

                cacheGeometryOverlapsLeftTile = xmin <CurrentTileBox.Min.X &&
                                                      xmin> _testRunBox.Min.X;

                // https://issuetracker02.eggits.net/browse/COM-85
                // observed (CtLu):
                // - filter geometry ymin = 220532.967
                // - filter geometry ymax = 220557.78500
                // - tile ymin            = 220557.78534
                // --> filter geometry is completely outside of tile boundaries!!!
                // --> causes incorrect error in QaContainsOther
                cacheGeometryOverlapsBottomTile = ymin <CurrentTileBox.Min.Y &&
                                                        ymin> _testRunBox.Min.Y;
            }

            IGeometryEngine engine = _container.GeometryEngine;

            engine.SetSourceGeometry(filterGeometry);

            IList <ContainerTest> tests = _testsPerTable[table];
            int indexTest = tests.IndexOf(filterHelper.ContainerTest);

            IList <BaseRow> ignoredRows = IgnoredRowsByTableAndTest[tableIndex][indexTest];

            foreach (BoxTree <CachedRow> .TileEntry entry in searchList)
            {
                CachedRow cachedRow = Assert.NotNull(entry.Value, "cachedRow");

                // This causes problems for QaIsCoveredByOther. However
                // IsCoveredByOther is not a network test, but still requires cached features
                // to be returned repeatedly
                if (cacheGeometryOverlapsLeftTile && !cachedRow.IsFirstOccurrenceX)
                {
                    // only if *not for network*:
                    // the filter geometry overlaps the left border of the tile, but
                    // not the left border of the test run box AND the cached row
                    // was already returned previously --> skip it
                    continue;
                }

                if (cacheGeometryOverlapsBottomTile && !cachedRow.IsFirstOccurrenceY)
                {
                    // only if *not for network*:
                    // the filter geometry overlaps the bottom border of the tile, but
                    // not the bottom border of the test run box AND the cached row
                    // was already returned previously --> skip it
                    continue;
                }

                if (ignoredRows != null && ignoredRows.Contains(entry.Value))
                {
                    continue;
                }

                IFeature targetFeature = cachedRow.Feature;

                if (targetFeature.OID < filterHelper.MinimumOID)
                {
                    continue;
                }

                engine.SetTargetGeometry(cachedRow.Geometry);

                // Remark: if most of the rows fullfill helper.Check,
                // it is better to check the geometric relation first
                var matchesConstraint = false;
                if (filterHelper.AttributeFirst)
                {
                    if (!filterHelper.MatchesConstraint(targetFeature))
                    {
                        continue;
                    }

                    matchesConstraint = true;
                }

                if (engine.EvaluateRelation(spatialFilter))
                {
                    if (matchesConstraint || filterHelper.MatchesConstraint(targetFeature))
                    {
                        result.Add(targetFeature);
                    }
                }
            }

            return(result);
        }