Exemplo n.º 1
0
        /// <summary>
        /// Find elements either contained, containing or intersecting polygon.
        /// <para>
        /// If no elements are found, an empty list is returned.
        /// </para>
        /// </summary>
        public IList <MeshElement> FindElements(Polygon polygon)
        {
            if (_elementSearchTree == null)
            {
                SetupElementSearch();
            }

            Envelope targetEnvelope = polygon.EnvelopeInternal;

            IList <MeshElement> potentialElmts = _elementSearchTree.Query(targetEnvelope);

            List <MeshElement> result = new List <MeshElement>();

            // Loop over all potential elements
            for (int i = 0; i < potentialElmts.Count; i++)
            {
                MeshElement element = potentialElmts[i];

                // Fast-lane check: When there is no overlap even by the envelopes
                if (!targetEnvelope.Intersects(element.EnvelopeInternal()))
                {
                    continue;
                }

                // More detailed check for actual overlap
                Polygon elementPolygon = element.ToPolygon();
                if (elementPolygon.Intersects(polygon))
                {
                    result.Add(element);
                }
            }

            return(result);
        }
Exemplo n.º 2
0
 /// <summary>
 /// Create a polygon from a mesh element
 /// </summary>
 public static Polygon ToPolygon(this MeshElement element)
 {
     return(element.ToPolygon(GeomFactory));
 }
Exemplo n.º 3
0
        /// <summary>
        /// Find elements either contained, containing or intersecting the polygon.
        /// <para>
        /// This method can be used if only some elements of the mesh is to be included
        /// in the weight calculations.
        /// </para>
        /// <para>
        /// If polygon is totally contained within one mesh element, then 1 element is returned.
        /// If polygon partially falls outside of the grid, only elements within grid are returned.
        /// </para>
        /// <param name="polygon">Polygon or multi-polygon</param>
        /// <param name="elements">List of elements</param>
        /// </summary>
        public List <ElementWeight> CalculateWeights(Geometry polygon, IList <MeshElement> elements)
        {
            Envelope targetEnvelope = polygon.EnvelopeInternal;

            //// It should be faster to use than the polygon directly?
            //PreparedPolygon prepolygon = new PreparedPolygon(polygon);

            List <ElementWeight> result = new List <ElementWeight>();

            // Total intersecting area
            double totalArea = 0;

            // Loop over all potential elements
            for (int i = 0; i < elements.Count; i++)
            {
                MeshElement element = elements[i];

                // Fast-lane check: When there is no overlap even by the envelopes
                if (!targetEnvelope.Intersects(element.EnvelopeInternal()))
                {
                    continue;
                }

                Polygon elementPolygon = element.ToPolygon();

                Geometry intersection = elementPolygon.Intersection(polygon);
                if (!intersection.IsEmpty)
                {
                    // Target polygon and element polygon has an overlap.
                    // If target  polygon fully contains the element polygon, this is the element area
                    // If element polygon fully contains the target  polygon, this is the polygon area
                    double intersectingArea = intersection.Area;
                    totalArea += intersectingArea;
                    if (WeightType == WeightType.Fraction)
                    {
                        result.Add(new ElementWeight(element, intersectingArea / elementPolygon.Area));
                    }
                    else
                    {
                        result.Add(new ElementWeight(element, intersectingArea));
                    }
                }
            }

            IntersectionArea = totalArea;

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

            // When Weight-based calculations, weight with the total intersecting area
            if (WeightType == WeightType.Weight)
            {
                for (int i = 0; i < result.Count; i++)
                {
                    ElementWeight elmtWeight = result[i];
                    elmtWeight.Weight /= totalArea;
                    result[i]          = elmtWeight;
                }
            }

            return(result);
        }