private bool IsCoincidentWithNeighborBorder(
            [NotNull] BorderConnection borderConnection,
            [NotNull] IFeature neighborFeature, int neighborLineClassIndex,
            int neighborBorderClassIndex)
        {
            ITable neighborBorderClass = InvolvedTables[neighborBorderClassIndex];

            ISpatialFilter spatialFilter = _filters[neighborBorderClassIndex];

            spatialFilter.Geometry = borderConnection.Point;

            BorderMatchCondition neighborBorderMatchCondition =
                GetBorderMatchCondition(neighborLineClassIndex);

            foreach (IRow borderRow in Search(neighborBorderClass,
                                              spatialFilter,
                                              _filterHelpers[neighborBorderClassIndex]))
            {
                if (neighborBorderMatchCondition.IsFulfilled(neighborFeature,
                                                             neighborLineClassIndex,
                                                             borderRow,
                                                             neighborBorderClassIndex))
                {
                    return(true);
                }
            }

            return(false);
        }
Example #2
0
        public void AddConnection(int row, int col, BorderConnection connection)
        {
            Connections[row, col] |= connection;
            var newConnection = Connections[row, col];
            var ch            = ConnectionToChar(newConnection);

            SetChar(row, col, ch);
        }
 private ICollection <AttributeConstraintViolation> GetAttributeConstraintViolations(
     [NotNull] BorderConnection borderConnection,
     [NotNull] IFeature neighborFeature,
     int neighborClassIndex)
 {
     return(EdgeMatchUtils.GetAttributeConstraintViolations(
                borderConnection.Feature, borderConnection.ClassIndex,
                neighborFeature, neighborClassIndex,
                _borderingPointAttributeConstraint,
                _borderPointEqualFieldValuesCondition,
                ReportIndividualAttributeConstraintViolations).ToList());
 }
 private bool AreBordersCoincident(
     [NotNull] BorderConnection borderConnection,
     [NotNull] BorderConnection neighborBorderConnection)
 {
     return(IsCoincidentWithNeighborBorder(borderConnection,
                                           neighborBorderConnection.Feature,
                                           neighborBorderConnection.ClassIndex,
                                           neighborBorderConnection.BorderClassIndex) &&
            IsCoincidentWithNeighborBorder(neighborBorderConnection,
                                           borderConnection.Feature,
                                           borderConnection.ClassIndex,
                                           borderConnection.BorderClassIndex));
 }
Example #5
0
 public TableWriter(StringBuilder innerBuilder, Size tableSize, TextTableCharset charset)
 {
     InnerBuilder = innerBuilder;
     TableSize    = tableSize;
     Charset      = charset;
     // Use InnerBuilder.Clear() for .NET 4.0+
     InnerBuilder.Length   = 0;
     InnerBuilder.Capacity = tableSize.Height * (tableSize.Width + 1);
     for (var i = 0; i < tableSize.Height; i++)
     {
         for (var j = 0; j < tableSize.Width; j++)
         {
             InnerBuilder.Append(' ');
         }
         InnerBuilder.Append('\n');
     }
     Connections = new BorderConnection[tableSize.Height, tableSize.Width];
 }
Example #6
0
        private char ConnectionToChar(BorderConnection connection)
        {
            switch (connection)
            {
            case BorderConnection.None: return(Charset.None);

            case BorderConnection.Up: return(Charset.Vertical);

            case BorderConnection.Down: return(Charset.Vertical);

            case BorderConnection.Left: return(Charset.Horizontal);

            case BorderConnection.Right: return(Charset.Horizontal);

            case BorderConnection.Vertical: return(Charset.Vertical);

            case BorderConnection.Horizontal: return(Charset.Horizontal);

            case BorderConnection.Cross: return(Charset.Cross);

            case BorderConnection.CornerUpLeft: return(Charset.CornerUpLeft);

            case BorderConnection.CornerUpRight: return(Charset.CornerUpRight);

            case BorderConnection.CornerDownLeft: return(Charset.CornerDownLeft);

            case BorderConnection.CornerDownRight: return(Charset.CornerDownRight);

            case BorderConnection.VerticalLeft: return(Charset.VerticalLeft);

            case BorderConnection.VerticalRight: return(Charset.VerticalRight);

            case BorderConnection.HorizontalUp: return(Charset.HorizontalUp);

            case BorderConnection.HorizontalDown: return(Charset.HorizontalDown);

            default:
                throw new ArgumentOutOfRangeException(nameof(connection), connection, null);
            }
        }
        private int CheckBorderPoint([NotNull] IFeature pointFeature, int pointClassIndex,
                                     int borderClassIndex,
                                     [NotNull] IEnumerable <int> neighborPointClassIndexes,
                                     int neighborBorderClassIndex)
        {
            // determine if the feature ends on the border
            var point = (IPoint)pointFeature.Shape;

            if (point.IsEmpty)
            {
                return(NoError);
            }

            if (IsOutsideCurrentTile(point))
            {
                return(NoError);
            }

            EnsureBorderingLineMatchCondition();
            EnsureBorderingLineAttributeConstraint();
            EnsureBorderingLineEqualFieldValuesCondition();

            BorderConnection borderConnection = GetBorderConnection(point, pointFeature,
                                                                    pointClassIndex,
                                                                    borderClassIndex);

            if (borderConnection == null)
            {
                // point does not touch border
                return(NoError);
            }

            return(CheckBorderConnection(borderConnection,
                                         neighborPointClassIndexes, neighborBorderClassIndex,
                                         _borderingPointMatchCondition));
        }
        private int ReportDisjointNeighborPointErrors(
            [NotNull] ICollection <AttributeConstraintViolation> constraintViolations,
            [NotNull] BorderConnection borderConnection,
            [NotNull] BorderConnection neighborBorderConnection,
            bool areBordersCoincident,
            double pointDistance)
        {
            IMultipoint errorGeometry = GeometryFactory.CreateMultipoint(
                GeometryFactory.Clone(borderConnection.Point),
                GeometryFactory.Clone(neighborBorderConnection.Point));

            string baseDescription = string.Format(
                LocalizableStrings.QaEdgeMatchBorderingPoints_NoMatch_CandidateExists,
                FormatLength(pointDistance, _spatialReference).Trim());

            IssueCode issueCode;
            string    description;

            if (constraintViolations.Count == 0)
            {
                if (areBordersCoincident)
                {
                    issueCode   = Codes[Code.NoMatch_CandidateExists_ConstraintsFulfilled];
                    description = baseDescription;
                }
                else
                {
                    issueCode =
                        Codes[
                            Code.NoMatch_CandidateExists_BordersNotCoincident_ConstraintsFulfilled];
                    description =
                        $"{baseDescription} {LocalizableStrings.QaEdgeMatchBorderingPoints_BordersNotCoincident}";
                }

                return(ReportError(description, errorGeometry,
                                   issueCode, null,
                                   borderConnection.Feature,
                                   neighborBorderConnection.Feature));
            }

            var errorCount = 0;

            foreach (AttributeConstraintViolation constraintViolation in constraintViolations)
            {
                if (areBordersCoincident)
                {
                    issueCode   = Codes[Code.NoMatch_CandidateExists_ConstraintsNotFulfilled];
                    description = $"{baseDescription} {constraintViolation.Description}.";
                }
                else
                {
                    issueCode =
                        Codes[
                            Code
                            .NoMatch_CandidateExists_BordersNotCoincident_ConstraintsNotFulfilled];

                    // description has final period
                    description =
                        $"{baseDescription} {LocalizableStrings.QaEdgeMatchBorderingPoints_BordersNotCoincident} {constraintViolation.Description}.";
                }

                errorCount += ReportError(description, errorGeometry,
                                          issueCode, constraintViolation.AffectedComponents,
                                          new[] { constraintViolation.TextValue },
                                          borderConnection.Feature,
                                          neighborBorderConnection.Feature);
            }

            return(errorCount);
        }
        private int CheckBorderConnection(
            [NotNull] BorderConnection borderConnection,
            [NotNull] IEnumerable <int> neighborPointClassIndexes,
            int neighborBorderClassIndex,
            [NotNull] PointMatchCondition borderingPointMatchCondition)
        {
            double coincidenceTolerance = GetCoincidenceTolerance(borderConnection.ClassIndex);

            var anyNeighborFound = false;

            var errorCount = 0;

            foreach (int neighborPointClassIndex in neighborPointClassIndexes)
            {
                foreach (IRow neighborRow in SearchNeighborRows(borderConnection.Point,
                                                                neighborPointClassIndex))
                {
                    if (WasReportedInOppositeDirection(borderConnection.Feature,
                                                       borderConnection.ClassIndex,
                                                       neighborRow,
                                                       neighborPointClassIndex))
                    {
                        return(NoError);
                    }

                    if (!borderingPointMatchCondition.IsFulfilled(borderConnection.Feature,
                                                                  borderConnection.ClassIndex,
                                                                  neighborRow,
                                                                  neighborPointClassIndex))
                    {
                        continue;
                    }

                    var neighborFeature = (IFeature)neighborRow;
                    var neighborPoint   = (IPoint)neighborFeature.Shape;

                    double pointDistance = GeometryUtils.GetPointDistance(borderConnection.Point,
                                                                          neighborPoint);

                    if (pointDistance > _searchDistance)
                    {
                        // the point is outside the search distance
                        continue;
                    }

                    // determine if the neighbor point is connected to it's border
                    BorderConnection neighborBorderConnection = GetBorderConnection(neighborPoint,
                                                                                    neighborFeature,
                                                                                    neighborPointClassIndex,
                                                                                    neighborBorderClassIndex);

                    if (neighborBorderConnection == null)
                    {
                        // there is no neighboring point within the search distance on its border
                        continue;
                    }

                    anyNeighborFound = true;

                    ICollection <AttributeConstraintViolation> constraintViolations =
                        GetAttributeConstraintViolations(borderConnection,
                                                         neighborFeature,
                                                         neighborPointClassIndex);

                    if (EdgeMatchUtils.IsWithinTolerance(pointDistance, coincidenceTolerance))
                    {
                        // the points are coincident
                        if (constraintViolations.Count == 0)
                        {
                            return(NoError);
                        }

                        AddReportedRowPair(borderConnection.Feature,
                                           borderConnection.ClassIndex,
                                           neighborFeature,
                                           neighborPointClassIndex);

                        foreach (AttributeConstraintViolation constraintViolation in
                                 constraintViolations)
                        {
                            errorCount += ReportError(
                                constraintViolation.Description,
                                GeometryFactory.Clone(borderConnection.Point),
                                Codes[Code.Match_ConstraintsNotFulfilled],
                                constraintViolation.AffectedComponents,
                                new[] { constraintViolation.TextValue },
                                borderConnection.Feature, neighborFeature);
                        }

                        return(errorCount);
                    }

                    // the point is not coincident with the neighbor point
                    bool areBordersCoincident = AreBordersCoincident(
                        borderConnection, neighborBorderConnection);

                    AddReportedRowPair(borderConnection.Feature,
                                       borderConnection.ClassIndex,
                                       neighborBorderConnection.Feature,
                                       neighborBorderConnection.ClassIndex);

                    if (!areBordersCoincident &&
                        AllowDisjointCandidateFeatureIfBordersAreNotCoincident)
                    {
                        continue;
                    }

                    if (constraintViolations.Count == 0 &&
                        AllowDisjointCandidateFeatureIfAttributeConstraintsAreFulfilled)
                    {
                        continue;
                    }

                    errorCount += ReportDisjointNeighborPointErrors(
                        constraintViolations,
                        borderConnection,
                        neighborBorderConnection,
                        areBordersCoincident,
                        pointDistance);
                }
            }

            if (!anyNeighborFound)
            {
                if (!AllowNoFeatureWithinSearchDistance)
                {
                    errorCount += ReportError(
                        LocalizableStrings.QaEdgeMatchBorderingPoints_NoMatch_NoCandidate,
                        GeometryFactory.Clone(borderConnection.Point),
                        Codes[Code.NoMatch_NoCandidate], null,
                        borderConnection.Feature);
                }
            }

            return(errorCount);
        }