Beispiel #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 <int> FindElements(Polygon polygon)
        {
            if (_elementSearchTree == null)
            {
                SetupElementSearch();
            }

            Envelope targetEnvelope = polygon.EnvelopeInternal;

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

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

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

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

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

            return(result);
        }
Beispiel #2
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 <int> elements)
        {
            if (!(polygon is MultiPolygon) && !(polygon is Polygon))
            {
                throw new Exception("Cannot calculate weights for geometry of type: " + polygon.GeometryType);
            }

            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
            int elementsCount = elements?.Count ?? _mesh.NumberOfElements;

            for (int i = 0; i < elementsCount; i++)
            {
                int element = elements != null ? elements[i] : i;

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

                Polygon elementPolygon = _mesh.ElementToPolygon(element);

                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);
        }