背景
统计与一个面相交的多边形面积之和,传统的方法是查询到所有相交要素,进行面积累加。这种方式在以接口方式提供服务时,就会出现性能方面的问题。实测9个500m*500m的范围,统计面积之和时,比较糟糕的状况下,时间竟然长达近60秒!这是不可忍受的。经排查,主要慢在查询得到要素游标后的while循环上,尤其是进行拓扑相关处理,非常耗时。转念一想,不妨采用统计的接口试试。发现效果非常理想。旧方法需要近20秒才能完成的工作,新接口只需要几百毫秒。以下是代码。
private static double CalculatePercentage(double x, double y, double radius, ESRI.ArcGIS.Geodatabase.IFeatureClass targetFeatureClass) { if (targetFeatureClass.ShapeType != esriGeometryType.esriGeometryPolygon) { return 0; } List<GeoJSON.Net.Geometry.Point> lsPoint = new List<GeoJSON.Net.Geometry.Point> { new GeoJSON.Net.Geometry.Point(new GeoJSON.Net.Geometry.Position { X = x, Y = y }) }; ESRI.ArcGIS.Geometry.IPolygon pPolygon = GeometryFactory.CreateEsriRectangle(lsPoint, true, radius); double dRectArea = (pPolygon as IArea).Area; double dEntityArea = 0; string sAreaFieldName = targetFeatureClass.FindField("Shape_Area") == -1 ? "Shape.Area" : "Shape_Area"; ISpatialFilter pSpatialFilter = FilterFactory.CreateSpatialFilter(pPolygon, esriSpatialRelEnum.esriSpatialRelIntersects); pSpatialFilter.SubFields = sAreaFieldName; ICursor pCursor = (targetFeatureClass as ITable).Search(pSpatialFilter, true); IDataStatistics pDataStat = new DataStatisticsClass() { Cursor = pCursor, Field = sAreaFieldName }; dEntityArea = pDataStat.Statistics.Sum; return dEntityArea * 100 / dRectArea; }
关键的地方就是那个IDataStatistics接口的调用。在研究过程中也发现,ArcGIS还有一个工具,可以实现相交导表,工具名称为Tabulate Intersection。可以调用GP工具实现它。