Exemple #1
0
 /// <summary>
 /// The validate method check if the XYPolyline is valid. The checks
 /// made are:
 ///   - is number of points >= 3
 ///   - is the length of all line segments positiv
 ///   - do any lines cross
 ///   - is the area positiv
 /// Exception is raised if the constraints are not met.
 /// </summary>
 public new void Validate()
 {
     if (Points.Count < 3)
     {
         throw new System.Exception("Number of vertices in polygon element is less than 3.");
     }
     if (GetArea() <= 0)
     {
         throw new System.Exception("Area of polygon is negative or zero. XYPolygons must be ordered counter clockwise.");
     }
     for (int j = 0; j < Points.Count; j++)
     {
         if (GetLine(j).GetLength() == 0)
         {
             throw new System.Exception("Length of line segment no: " +
                                        j.ToString() + " (0-based) of XYPolygon is zero.");
         }
     }
     for (int j = 0; j < Points.Count; j++)
     {
         for (int m = 0; m < j; m++)
         {
             if (XYGeometryTools.DoLineSegmentsIntersect(GetLine(j), GetLine(m)))
             {
                 throw new System.Exception("Line no: " + j.ToString() + " and line no: " +
                                            m.ToString() + " of XYPolygon crosses.");
             }
         }
     }
 }
Exemple #2
0
        /// <summary>
        /// The method decides if the triangle formed by  P(i-1), P(i) and
        /// P(i+1) from Polygon are intersected by any of the other points
        /// of the polygon.
        /// </summary>
        /// <param name="i">Middle index for the three points that forms the triangle</param>
        /// <returns>
        ///	<p>true: If the triangle P(i-1), P(i), P(i+1) is intersected by other parts of Polygon</p>
        ///	<p>false: otherwise</p>
        /// </returns>
        protected bool IsIntersected(int i)
        {
            double x = 0;
            double y = 0;
            int    n = Points.Count;

            int im1 = i - 1;
            int ip1 = i + 1;

            if (i == 0)
            {
                im1 = n - 1;
            }
            else if (i == n - 1)
            {
                ip1 = 0;
            }

            XYPoint   nodeim1      = new XYPoint((XYPoint)Points[im1]);
            XYPoint   nodei        = new XYPoint((XYPoint)Points[i]);
            XYPoint   nodeip1      = new XYPoint((XYPoint)Points[ip1]);
            XYPolygon localPolygon = new XYPolygon();

            localPolygon.Points.Add(nodeim1);
            localPolygon.Points.Add(nodei);
            localPolygon.Points.Add(nodeip1);

            int  j           = 0;
            bool intersected = false;

            while (((j < n - 1) && (!intersected)))
            {
                x = ((XYPoint)Points[j]).X;
                y = ((XYPoint)Points[j]).Y;

                if (((((j != im1) && (j != i)) && (j != ip1)) && XYGeometryTools.IsPointInPolygon(x, y, localPolygon)))
                {
                    return(true);
                }
                else
                {
                    j++;
                }
            }
            return(false);
        }
Exemple #3
0
        /// <summary>
        /// Calculates the mapping matrix between fromElements and toElements. The mapping method
        /// is decided from the combination of methodDescription, fromElements.ElementType and
        /// toElements.ElementType.
        /// The valid values for methodDescription is obtained through use of the
        /// GetAvailableMethods method.
        /// </summary>
        ///
        /// <remarks>
        /// UpdateMappingMatrix is called during initialisation. UpdateMappingMatrix must be called prior
        /// to Mapvalues.
        /// </remarks>
        ///
        /// <param name="methodIdentifier">String identification of mapping method</param>
        /// <param name="fromElements">The IElementset to map from.</param>
        /// <param name="toElements">The IElementset to map to</param>
        ///
        /// <returns>
        /// The method has no return value.
        /// </returns>
        private void UpdateMappingMatrix(ref IIdentifiable methodIdentifier, ref IElementSet fromElements, ref IElementSet toElements)
        {
            try
            {
                ElementSetChecker.CheckElementSet(fromElements);
                ElementSetChecker.CheckElementSet(toElements);

                _method              = SpatialAdaptedOutputFactory.GetMethod(methodIdentifier);
                _numberOfToRows      = toElements.ElementCount;
                _numberOfFromColumns = fromElements.ElementCount;
                _mappingMatrix       = new DoubleSparseMatrix(_numberOfToRows, _numberOfFromColumns);

                if (fromElements.ElementType == ElementType.Point && toElements.ElementType == ElementType.Point)
                {
                    #region

                    try
                    {
                        for (int i = 0; i < _numberOfToRows; i++)
                        {
                            XYPoint toPoint = CreateXYPoint(toElements, i);
                            for (int j = 0; j < _numberOfFromColumns; j++)
                            {
                                XYPoint fromPoint = CreateXYPoint(fromElements, j);
                                _mappingMatrix[i, j] = XYGeometryTools.CalculatePointToPointDistance(toPoint, fromPoint);
                            }
                        }

                        if (_method == ElementMapperMethod.Nearest)
                        {
                            for (int i = 0; i < _numberOfToRows; i++)
                            {
                                double minDist = _mappingMatrix[i, 0];
                                for (int j = 1; j < _numberOfFromColumns; j++)
                                {
                                    if (_mappingMatrix[i, j] < minDist)
                                    {
                                        minDist = _mappingMatrix[i, j];
                                    }
                                }
                                int denominator = 0;
                                for (int j = 0; j < _numberOfFromColumns; j++)
                                {
                                    if (_mappingMatrix[i, j] == minDist)
                                    {
                                        _mappingMatrix[i, j] = 1;
                                        denominator++;
                                    }
                                    else
                                    {
                                        _mappingMatrix[i, j] = 0;
                                    }
                                }
                                for (int j = 0; j < _numberOfFromColumns; j++)
                                {
                                    _mappingMatrix[i, j] = _mappingMatrix[i, j] / denominator;
                                }
                            }
                        }
                        else if (_method == ElementMapperMethod.Inverse)
                        {
                            for (int i = 0; i < _numberOfToRows; i++)
                            {
                                double minDist = _mappingMatrix[i, 0];
                                for (int j = 1; j < _numberOfFromColumns; j++)
                                {
                                    if (_mappingMatrix[i, j] < minDist)
                                    {
                                        minDist = _mappingMatrix[i, j];
                                    }
                                }
                                if (minDist == 0)
                                {
                                    int denominator = 0;
                                    for (int j = 0; j < _numberOfFromColumns; j++)
                                    {
                                        if (_mappingMatrix[i, j] == minDist)
                                        {
                                            _mappingMatrix[i, j] = 1;
                                            denominator++;
                                        }
                                        else
                                        {
                                            _mappingMatrix[i, j] = 0;
                                        }
                                    }
                                    for (int j = 0; j < _numberOfFromColumns; j++)
                                    {
                                        _mappingMatrix[i, j] = _mappingMatrix[i, j] / denominator;
                                    }
                                }
                                else
                                {
                                    double denominator = 0;
                                    for (int j = 0; j < _numberOfFromColumns; j++)
                                    {
                                        _mappingMatrix[i, j] = 1 / _mappingMatrix[i, j];
                                        denominator          = denominator + _mappingMatrix[i, j];
                                    }
                                    for (int j = 0; j < _numberOfFromColumns; j++)
                                    {
                                        _mappingMatrix[i, j] = _mappingMatrix[i, j] / denominator;
                                    }
                                }
                            }
                        }
                        else
                        {
                            throw new Exception("methodDescription unknown for point point mapping");
                        }
                    }
                    catch (Exception e)
                    {
                        throw new Exception("Point to point mapping failed", e);
                    }

                    #endregion
                }
                else if (fromElements.ElementType == ElementType.Point && toElements.ElementType == ElementType.PolyLine)
                {
                    #region

                    try
                    {
                        for (int i = 0; i < _numberOfToRows; i++)
                        {
                            XYPolyline toPolyLine = CreateXYPolyline(toElements, i);
                            for (int j = 0; j < _numberOfFromColumns; j++)
                            {
                                XYPoint fromPoint = CreateXYPoint(fromElements, j);
                                _mappingMatrix[i, j] = XYGeometryTools.CalculatePolylineToPointDistance(toPolyLine,
                                                                                                        fromPoint);
                            }
                        }

                        if (_method == ElementMapperMethod.Nearest)
                        {
                            for (int i = 0; i < _numberOfToRows; i++)
                            {
                                double minDist = _mappingMatrix[i, 0];
                                for (int j = 1; j < _numberOfFromColumns; j++)
                                {
                                    if (_mappingMatrix[i, j] < minDist)
                                    {
                                        minDist = _mappingMatrix[i, j];
                                    }
                                }
                                int denominator = 0;
                                for (int j = 0; j < _numberOfFromColumns; j++)
                                {
                                    if (_mappingMatrix[i, j] == minDist)
                                    {
                                        _mappingMatrix[i, j] = 1;
                                        denominator++;
                                    }
                                    else
                                    {
                                        _mappingMatrix[i, j] = 0;
                                    }
                                }
                                for (int j = 0; j < _numberOfFromColumns; j++)
                                {
                                    _mappingMatrix[i, j] = _mappingMatrix[i, j] / denominator;
                                }
                            }
                        }
                        else if (_method == ElementMapperMethod.Inverse)
                        {
                            for (int i = 0; i < _numberOfToRows; i++)
                            {
                                double minDist = _mappingMatrix[i, 0];
                                for (int j = 1; j < _numberOfFromColumns; j++)
                                {
                                    if (_mappingMatrix[i, j] < minDist)
                                    {
                                        minDist = _mappingMatrix[i, j];
                                    }
                                }
                                if (minDist == 0)
                                {
                                    int denominator = 0;
                                    for (int j = 0; j < _numberOfFromColumns; j++)
                                    {
                                        if (_mappingMatrix[i, j] == minDist)
                                        {
                                            _mappingMatrix[i, j] = 1;
                                            denominator++;
                                        }
                                        else
                                        {
                                            _mappingMatrix[i, j] = 0;
                                        }
                                    }
                                    for (int j = 0; j < _numberOfFromColumns; j++)
                                    {
                                        _mappingMatrix[i, j] = _mappingMatrix[i, j] / denominator;
                                    }
                                }
                                else
                                {
                                    double denominator = 0;
                                    for (int j = 0; j < _numberOfFromColumns; j++)
                                    {
                                        _mappingMatrix[i, j] = 1 / _mappingMatrix[i, j];
                                        denominator          = denominator + _mappingMatrix[i, j];
                                    }
                                    for (int j = 0; j < _numberOfFromColumns; j++)
                                    {
                                        _mappingMatrix[i, j] = _mappingMatrix[i, j] / denominator;
                                    }
                                }
                            }
                        }
                        else
                        {
                            throw new Exception("methodDescription unknown for point to polyline mapping");
                        }
                    }
                    catch (Exception e)
                    {
                        throw new Exception("Point to polyline mapping failed", e);
                    }

                    #endregion
                }
                else if (fromElements.ElementType == ElementType.Point &&
                         toElements.ElementType == ElementType.Polygon)
                {
                    #region

                    try
                    {
                        for (int i = 0; i < _numberOfToRows; i++)
                        {
                            XYPolygon polygon = CreateXYPolygon(toElements, i);
                            int       count   = 0;
                            XYPoint   point;
                            for (int n = 0; n < _numberOfFromColumns; n++)
                            {
                                point = CreateXYPoint(fromElements, n);
                                if (XYGeometryTools.IsPointInPolygon(point, polygon))
                                {
                                    if (_method == ElementMapperMethod.Mean)
                                    {
                                        count = count + 1;
                                    }
                                    else if (_method == ElementMapperMethod.Sum)
                                    {
                                        count = 1;
                                    }
                                    else
                                    {
                                        throw new Exception(
                                                  "methodDescription unknown for point to polygon mapping");
                                    }
                                }
                            }
                            for (int n = 0; n < _numberOfFromColumns; n++)
                            {
                                point = CreateXYPoint(fromElements, n);

                                if (XYGeometryTools.IsPointInPolygon(point, polygon))
                                {
                                    _mappingMatrix[i, n] = 1.0 / count;
                                }
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        throw new Exception("Point to polygon mapping failed", e);
                    }

                    #endregion
                }
                else if (fromElements.ElementType == ElementType.PolyLine &&
                         toElements.ElementType == ElementType.Point)
                {
                    #region

                    try
                    {
                        for (int i = 0; i < _numberOfToRows; i++)
                        {
                            XYPoint toPoint = CreateXYPoint(toElements, i);
                            for (int j = 0; j < _numberOfFromColumns; j++)
                            {
                                XYPolyline fromPolyLine = CreateXYPolyline(fromElements, j);
                                _mappingMatrix[i, j] =
                                    XYGeometryTools.CalculatePolylineToPointDistance(fromPolyLine, toPoint);
                            }
                        }

                        if (_method == ElementMapperMethod.Nearest)
                        {
                            for (int i = 0; i < _numberOfToRows; i++)
                            {
                                double minDist = _mappingMatrix[i, 0];
                                for (int j = 1; j < _numberOfFromColumns; j++)
                                {
                                    if (_mappingMatrix[i, j] < minDist)
                                    {
                                        minDist = _mappingMatrix[i, j];
                                    }
                                }
                                int denominator = 0;
                                for (int j = 0; j < _numberOfFromColumns; j++)
                                {
                                    if (_mappingMatrix[i, j] == minDist)
                                    {
                                        _mappingMatrix[i, j] = 1;
                                        denominator++;
                                    }
                                    else
                                    {
                                        _mappingMatrix[i, j] = 0;
                                    }
                                }
                                for (int j = 0; j < _numberOfFromColumns; j++)
                                {
                                    _mappingMatrix[i, j] = _mappingMatrix[i, j] / denominator;
                                }
                            }
                        }
                        else if (_method == ElementMapperMethod.Inverse)
                        {
                            for (int i = 0; i < _numberOfToRows; i++)
                            {
                                double minDist = _mappingMatrix[i, 0];
                                for (int j = 1; j < _numberOfFromColumns; j++)
                                {
                                    if (_mappingMatrix[i, j] < minDist)
                                    {
                                        minDist = _mappingMatrix[i, j];
                                    }
                                }
                                if (minDist == 0)
                                {
                                    int denominator = 0;
                                    for (int j = 0; j < _numberOfFromColumns; j++)
                                    {
                                        if (_mappingMatrix[i, j] == minDist)
                                        {
                                            _mappingMatrix[i, j] = 1;
                                            denominator++;
                                        }
                                        else
                                        {
                                            _mappingMatrix[i, j] = 0;
                                        }
                                    }
                                    for (int j = 0; j < _numberOfFromColumns; j++)
                                    {
                                        _mappingMatrix[i, j] = _mappingMatrix[i, j] / denominator;
                                    }
                                }
                                else
                                {
                                    double denominator = 0;
                                    for (int j = 0; j < _numberOfFromColumns; j++)
                                    {
                                        _mappingMatrix[i, j] = 1 / _mappingMatrix[i, j];
                                        denominator          = denominator + _mappingMatrix[i, j];
                                    }
                                    for (int j = 0; j < _numberOfFromColumns; j++)
                                    {
                                        _mappingMatrix[i, j] = _mappingMatrix[i, j] / denominator;
                                    }
                                }
                            }
                        }
                        else
                        {
                            throw new Exception("methodDescription unknown for polyline to point mapping");
                        }
                    }
                    catch (Exception e) // Catch for all of the Point to Polyline part
                    {
                        throw new Exception("Polyline to point mapping failed", e);
                    }

                    #endregion
                }
                else if (fromElements.ElementType == ElementType.PolyLine &&
                         toElements.ElementType == ElementType.Polygon)
                {
                    #region

                    try
                    {
                        // For each polygon in target
                        for (int i = 0; i < _numberOfToRows; i++)
                        {
                            XYPolygon polygon = CreateXYPolygon(toElements, i);

                            if (_method == ElementMapperMethod.WeightedMean)
                            {
                                double totalLineLengthInPolygon = 0;
                                for (int n = 0; n < _numberOfFromColumns; n++)
                                {
                                    XYPolyline polyline = CreateXYPolyline(fromElements, n);
                                    _mappingMatrix[i, n] =
                                        XYGeometryTools.CalculateLengthOfPolylineInsidePolygon(
                                            polyline, polygon);
                                    totalLineLengthInPolygon += _mappingMatrix[i, n];
                                }
                                if (totalLineLengthInPolygon > 0)
                                {
                                    for (int n = 0; n < _numberOfFromColumns; n++)
                                    {
                                        _mappingMatrix[i, n] = _mappingMatrix[i, n] /
                                                               totalLineLengthInPolygon;
                                    }
                                }
                            }
                            else if (_method == ElementMapperMethod.WeightedSum)
                            {
                                // For each line segment in PolyLine
                                for (int n = 0; n < _numberOfFromColumns; n++)
                                {
                                    XYPolyline polyline = CreateXYPolyline(fromElements, n);
                                    _mappingMatrix[i, n] =
                                        XYGeometryTools.CalculateLengthOfPolylineInsidePolygon(
                                            polyline, polygon) / polyline.GetLength();
                                }
                            }
                            else
                            {
                                throw new Exception(
                                          "methodDescription unknown for polyline to polygon mapping");
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        throw new Exception("Polyline to polygon mapping failed", e);
                    }

                    #endregion
                }
                else if (fromElements.ElementType == ElementType.Polygon &&
                         toElements.ElementType == ElementType.Point)
                {
                    #region

                    try
                    {
                        if (_method != ElementMapperMethod.Value)
                        {
                            throw new Exception("methodDescription unknown for polygon to point mapping");
                        }

                        // Only create search tree if number of cols/rows is larger than say 10/10.
                        bool useSearchTree = _numberOfFromColumns > 10 && _numberOfToRows > 10;
                        XYElementSearchTree <int> fromSearchTree     = null;
                        ICollection <int>         fromCandidateElmts = null;
                        if (useSearchTree)
                        {
                            fromSearchTree = XYElementSearchTree <int> .BuildSearchTree(fromElements);
                        }
                        else
                        {
                            fromCandidateElmts = new IntSequence(0, _numberOfFromColumns - 1);
                        }

                        for (int n = 0; n < _numberOfToRows; n++)
                        {
                            XYPoint point = CreateXYPoint(toElements, n);
                            if (useSearchTree)
                            {
                                XYExtent toExtent = XYExtentUtil.GetExtent(point, XYGeometryTools.EPSILON);
                                fromCandidateElmts = fromSearchTree.FindElements(toExtent);
                            }

                            int count = 0;

                            // Check first for strict inclusion
                            foreach (int i in fromCandidateElmts)
                            {
                                XYPolygon polygon = CreateXYPolygon(fromElements, i);
                                if (XYGeometryTools.IsPointInPolygon(point, polygon))
                                {
                                    _mappingMatrix[n, i] = 1.0;
                                    count++;
                                }
                            }
                            if (count == 0)
                            {
                                // Not strictly inside any polygon, check also edges
                                foreach (int i in fromCandidateElmts)
                                {
                                    XYPolygon polygon = CreateXYPolygon(fromElements, i);
                                    if (XYGeometryTools.IsPointInPolygonOrOnEdge(point, polygon))
                                    {
                                        _mappingMatrix[n, i] = 1.0;
                                        count++;
                                    }
                                }
                            }
                            if (count > 1)
                            {
                                // In case of more than one hit, use average
                                foreach (int i in fromCandidateElmts)
                                {
                                    if (_mappingMatrix[n, i] != 0.0)
                                    {
                                        _mappingMatrix[n, i] = 1.0 / count;
                                    }
                                }
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        throw new Exception("Polygon to point mapping failed", e);
                    }

                    #endregion
                }
                else if (fromElements.ElementType == ElementType.Polygon &&
                         toElements.ElementType == ElementType.PolyLine)
                // Polygon to PolyLine
                {
                    #region

                    try
                    {
                        for (int i = 0; i < _numberOfToRows; i++)
                        {
                            XYPolyline polyline = CreateXYPolyline(toElements, i);

                            if (_method == ElementMapperMethod.WeightedMean)
                            {
                                for (int n = 0; n < _numberOfFromColumns; n++)
                                {
                                    XYPolygon polygon = CreateXYPolygon(fromElements, n);
                                    _mappingMatrix[i, n] =
                                        XYGeometryTools.CalculateLengthOfPolylineInsidePolygon(
                                            polyline, polygon) / polyline.GetLength();
                                }
                                double sum = 0;
                                for (int n = 0; n < _numberOfFromColumns; n++)
                                {
                                    sum += _mappingMatrix[i, n];
                                }
                                for (int n = 0; n < _numberOfFromColumns; n++)
                                {
                                    _mappingMatrix[i, n] = _mappingMatrix[i, n] / sum;
                                }
                            }
                            else if (_method == ElementMapperMethod.WeightedSum)
                            {
                                for (int n = 0; n < _numberOfFromColumns; n++)
                                {
                                    XYPolygon polygon = CreateXYPolygon(fromElements, n);
                                    _mappingMatrix[i, n] =
                                        XYGeometryTools.CalculateLengthOfPolylineInsidePolygon(
                                            polyline, polygon) / polyline.GetLength();
                                }
                            }
                            else
                            {
                                throw new Exception(
                                          "methodDescription unknown for polygon to polyline mapping");
                            }
                        }
                    }
                    catch (Exception e) // catch for all of Polygon to PolyLine
                    {
                        throw new Exception("Polygon to polyline mapping failed", e);
                    }

                    #endregion
                }
                else if (fromElements.ElementType == ElementType.Polygon &&
                         toElements.ElementType == ElementType.Polygon)
                // Polygon to Polygon
                {
                    #region

                    try
                    {
                        // Only create search tree if number of cols/rows is larger than say 100/10.
                        bool useSearchTree = _numberOfFromColumns > 10 && _numberOfToRows > 10;
                        XYElementSearchTree <int> fromSearchTree     = null;
                        ICollection <int>         fromCandidateElmts = null;
                        if (useSearchTree)
                        {
                            fromSearchTree = XYElementSearchTree <int> .BuildSearchTree(fromElements);
                        }
                        else
                        {
                            fromCandidateElmts = new IntSequence(0, _numberOfFromColumns - 1);
                        }

                        for (int i = 0; i < _numberOfToRows; i++)
                        {
                            XYPolygon toPolygon = CreateXYPolygon(toElements, i);
                            if (useSearchTree)
                            {
                                XYExtent toExtent = XYExtentUtil.GetExtent(toPolygon);
                                fromCandidateElmts = fromSearchTree.FindElements(toExtent);
                            }

                            foreach (int j in fromCandidateElmts)
                            {
                                XYPolygon fromPolygon = CreateXYPolygon(fromElements, j);
                                _mappingMatrix[i, j] = XYGeometryTools.CalculateSharedArea(
                                    toPolygon, fromPolygon);
                                if (_method == ElementMapperMethod.Distribute)
                                {
                                    _mappingMatrix[i, j] /= fromPolygon.GetArea();
                                }
                            }

                            if (_method == ElementMapperMethod.WeightedMean)
                            {
                                double denominator = 0;
                                foreach (int j in fromCandidateElmts)
                                {
                                    denominator = denominator + _mappingMatrix[i, j];
                                }
                                foreach (int j in fromCandidateElmts)
                                {
                                    if (denominator != 0)
                                    {
                                        _mappingMatrix[i, j] = _mappingMatrix[i, j] / denominator;
                                    }
                                }
                            }
                            else if (_method == ElementMapperMethod.WeightedSum)
                            {
                                foreach (int j in fromCandidateElmts)
                                {
                                    _mappingMatrix[i, j] = _mappingMatrix[i, j] / toPolygon.GetArea();
                                }
                            }
                            else if (_method != ElementMapperMethod.Distribute)
                            {
                                throw new Exception(
                                          "methodDescription unknown for polygon to polygon mapping");
                            }
                        }
                    }
                    catch (Exception e) // catch for all of Polygon to Polygon
                    {
                        throw new Exception("Polygon to polygon mapping failed", e);
                    }

                    #endregion
                }
                else // if the fromElementType, toElementType combination is no implemented
                {
                    throw new Exception(
                              "Mapping of specified ElementTypes not included in ElementMapper");
                }
            }
            catch (Exception e)
            {
                throw new Exception("UpdateMappingMatrix failed to update mapping matrix", e);
            }
        }