/// <summary> /// Setup for element-search /// </summary> public void SetupElementSearch() { _elementSearchTree = new SearchTreeType(); for (int i = 0; i < _mesh.NumberOfElements; i++) { int element = i; Envelope extent = _mesh.ElementEnvelopeInternal(element);; _elementSearchTree.Insert(extent, element); } // When using STRtree, call this method here //_elementSearchTree.Build(); }
/// <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); }