要素,当要素存在内外环,外环标记为1,内环标记为0"/>
ArcEngine裂开要素,当要素存在内外环,外环标记为1,内环标记为0
当图斑数据过于复杂时,将图斑组成尽量简化,比如:数据拆分,数据的每一个环均生成一个图斑,外环将图斑属性标记为1,内环图斑属性标记为0
1. 版本1
接上文实现为
object missing = Type.Missing;
IFeatureCursor pCreateFeaCursor =InnerAndOuterRingsResult.Insert(true);
IFeatureBuffer pCreateFeaBuffer =InnerAndOuterRingsResult.CreateFeatureBuffer();
IFeatureCursor pSearchFeaCursor = SourceFeaClassSearch(null, true);
IFeature pFea = null;
int TagFiledIndex = InnerAndOuterRingsResultFindField("TagInfo");
int index = 0;
while ((pFea = pSearchFeaCursor.NextFeature()) !=null)
{IPolygon4 pPolygon2 = pFea.Shape as IPolygon4;IGeometryBag pExteriorRings = pPolygon2.ExteriorRingBag;IEnumGeometry pEteriorRingsEnum = pExteriorRings as IEnumGeometry;pEteriorRingsEnum.Reset();IRing pExteriorRing;while ((pExteriorRing = pEteriorRingsEnum.Next() as IRing) != null){index++;IGeometryCollection pGeometryCollection = new PolygonClass();pGeometryCollection.AddGeometry(pExteriorRing, ref missing, ref missing); //环转面IPolygon pPolygon = (IPolygon)pGeometryCollection;pCreateFeaBuffer.Shape = pPolygon;pCreateFeaBuffer.set_Value(TagFiledIndex,1);pCreateFeaCursor.InsertFeature(pCreateFeaBuffer);if (index % 10000 == 0){pCreateFeaCursor.Flush();}//判断该外环内部的环个数IRing pInteriorRing = null;IGeometryBag pInteriorRings1 = pPolygon2.get_InteriorRingBag(pExteriorRing);IEnumGeometry pInteriorRingsEnum = pInteriorRings1 as IEnumGeometry;pInteriorRingsEnum.Reset();while ((pInteriorRing = pInteriorRingsEnum.Next() as IRing) != null){index++;pGeometryCollection = new PolygonClass();pGeometryCollection.AddGeometry(pInteriorRing, ref missing, ref missing); //环转面pPolygon = (IPolygon)pGeometryCollection;pCreateFeaBuffer.Shape = pPolygon;pCreateFeaBuffer.set_Value(TagFiledIndex, 0);pCreateFeaCursor.InsertFeature(pCreateFeaBuffer);if (index % 10000 == 0){pCreateFeaCursor.Flush();}}Marshal.ReleaseComObject(pInteriorRings1);Marshal.ReleaseComObject(pInteriorRingsEnum);}pCreateFeaCursor.Flush();Marshal.ReleaseComObject(pPolygon2);Marshal.ReleaseComObject(pExteriorRings);Marshal.ReleaseComObject(pEteriorRingsEnum);Marshal.ReleaseComObject(pFea);
}
pCreateFeaCursor.Flush();
当数据异常情况是,这种算法将会非常的慢,这种异常为:一个图斑非常的大,且图斑内部非常的复杂。如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zakCn1T9-1603712289427)(异常数据拆分.png)]
这个为一个图斑,当数据为如下是,将会导致非常的慢,其具体原因为,每一个外环都要找一下内环。具体代码地址如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hPxahoTS-1603712289429)(异常数据拆分效率慢问题.png)]
如上问题,实质上可以归结为以下几点
- 图斑按环拆分
- 外环标记为1,内环标记为0
如果是这样的化,我们先将所有环标记为0,然后找到这些环中的外环标记为1,寻找这些外环标记的方式为定义每一个环的XMin_XMax_YMIn_YMax_Area_Length,如果XMin_XMax_YMIn_YMax_Area_Length一致就说明是同一个环。
XMin_XMax_YMIn_YMax_Area_Length个人觉得这个非常的不严谨
2. 版本2
object missing = Type.Missing;
IFeatureCursor pCreateFeaCursor =InnerAndOuterRingsResult.Insert(true);
IFeatureBuffer pCreateFeaBuffer =InnerAndOuterRingsResult.CreateFeatureBuffer();
IFeatureCursor pSearchFeaCursor =SourceFeaClass.Search(null, true);
int TagFiledIndex = InnerAndOuterRingsResultFindField("TagInfo");
int ExtentTagInfoFieldIndex =InnerAndOuterRingsResult.FindFiel("ExtentTagInfo");
IFeature pFea = null;
int index = 0;
while ((pFea = pSearchFeaCursor.NextFeature())!= null)
{IGeometryCollection pGeoColl = pFea.Shape as IGeometryCollection;for (int i = 0; i < pGeoColl.GeometryCount; i++){index++;IGeometry pGeo = pGeoColl.get_Geometry(i);IGeometryCollection pGeometryCollection = new PolygonClass();pGeometryCollection.AddGeometry(pGeo, ref missing, ref missing); //环转面IPolygon pPolygon = (IPolygon)pGeometryCollection;pCreateFeaBuffer.Shape = pPolygon;pCreateFeaBuffer.set_Value(TagFiledIndex, 0);string strExtentTag = GetGeoTag(pPolygon);pCreateFeaBuffer.set_Value(ExtentTagInfoFieldIndex, strExtentTag);pCreateFeaCursor.InsertFeature(pCreateFeaBuffer);if (index % 10000 == 0){pCreateFeaCursor.Flush();}}
}
pCreateFeaCursor.Flush();Dictionary<string, string> dic = GetAllOuterRing(SourceFeaClass);IFeatureCursor pUpdateFeaCursor = InnerAndOuterRingsResult.Update(null, true);IFeature pUpdateFea = null;while ((pUpdateFea = pUpdateFeaCursor.NextFeature()) != null){string strExtentTag = pUpdateFea.get_Value(ExtentTagInfoFieldIndex).ToString();if (dic.ContainsKey(strExtentTag)){pUpdateFea.set_Value(TagFiledIndex, 1);pUpdateFeaCursor.UpdateFeature(pUpdateFea);}}/// <summary>
/// 获取外环
/// </summary>
/// <param name="SourceFeaClass"></param>
/// <returns></returns>
private Dictionary<string, string> GetAllOuterRin(IFeatureClass SourceFeaClass)
{object missing = Type.Missing;Dictionary<string, string> dicReturn = new Dictionary<string, string>();IFeatureCursor pSearchFeaCursor = SourceFeaClass.Search(null, true);IFeature pFea = null;while ((pFea = pSearchFeaCursor.NextFeature()) != null){IPolygon4 pPolygon2 = pFea.Shape as IPolygon4;IGeometryBag pExteriorRings = pPolygon2.ExteriorRingBag;IEnumGeometry pEteriorRingsEnum = pExteriorRings as IEnumGeometry;pEteriorRingsEnum.Reset();IRing pExteriorRing;while ((pExteriorRing = pEteriorRingsEnum.Next() as IRing) != null){IGeometryCollection pGeometryCollection = new PolygonClass();pGeometryCollection.AddGeometry(pExteriorRing, ref missing, ref missing); //环转面IPolygon pPolygon = (IPolygon)pGeometryCollection;string strExtentTag = GetGeoTag(pPolygon);dicReturn.Add(strExtentTag,"");}}return dicReturn;
}
基于上述考虑内存情况后
3. 版本3
object missing = Type.Missing;
IFeatureCursor pCreateFeaCursor =InnerAndOuterRingsResult.Insert(true);
IFeatureBuffer pCreateFeaBuffer =InnerAndOuterRingsResult.CreateFeatureBuffer();
IFeatureCursor pSearchFeaCursor =SourceFeaClass.Search(null, true);
int TagFiledIndex = InnerAndOuterRingsResultFindField("TagInfo");
int ExtentTagInfoFieldIndex =InnerAndOuterRingsResult.FindFiel("ExtentTagInfo");
IFeature pFea = null;
int index = 0;
while ((pFea = pSearchFeaCursor.NextFeature())!= null)
{IGeometryCollection pGeoColl = pFea.Shape as IGeometryCollection;for (int i = 0; i < pGeoColl.GeometryCount; i++){index++;IGeometry pGeo = pGeoColl.get_Geometry(i);IGeometryCollection pGeometryCollection = new PolygonClass();pGeometryCollection.AddGeometry(pGeo, ref missing, ref missing); //环转面IPolygon pPolygon = (IPolygon)pGeometryCollection;pCreateFeaBuffer.Shape = pPolygon;pCreateFeaBuffer.set_Value(TagFiledIndex, 0);string strExtentTag = GetGeoTag(pPolygon);pCreateFeaBuffer.set_Value(ExtentTagInfoFieldIndex, strExtentTag);pCreateFeaCursor.InsertFeature(pCreateFeaBuffer);if (index % 10000 == 0){pCreateFeaCursor.Flush();}}
}
pCreateFeaCursor.Flush();
SetAlllOuterRing(SourceFeaClass,InnerAndOuterRingsResult);/// <summary>
/// 设置所有外环
/// </summary>
/// <param name="SourceFeaClass"></param>
/// <param name="InnerAndOuterRingsResult"></param>
private void SetAlllOuterRing(IFeatureClassSourceFeaClass, IFeatureClassInnerAndOuterRingsResult)
{object missing = Type.Missing;Dictionary<string, string> dicReturn = new Dictionary<string, string>();IFeatureCursor pSearchFeaCursor = SourceFeaClass.Search(null, true);IFeature pFea = null;while ((pFea = pSearchFeaCursor.NextFeature()) != null){IPolygon4 pPolygon2 = pFea.Shape as IPolygon4;IGeometryBag pExteriorRings = pPolygon2.ExteriorRingBag;IEnumGeometry pEteriorRingsEnum = pExteriorRings as IEnumGeometry;pEteriorRingsEnum.Reset();IRing pExteriorRing;while ((pExteriorRing = pEteriorRingsEnum.Next() as IRing) != null){IGeometryCollection pGeometryCollection = new PolygonClass();pGeometryCollection.AddGeometry(pExteriorRing, ref missing, ref missing); //环转面IPolygon pPolygon = (IPolygon)pGeometryCollection;string strExtentTag = GetGeoTag(pPolygon);dicReturn.Add(strExtentTag, "");if (dicReturn.Keys.Count == 100000){UpdateFeaOuterRing(dicReturn, InnerAndOuterRingsResult);}}Marshal.ReleaseComObject(pFea);Marshal.ReleaseComObject(pExteriorRings);Marshal.ReleaseComObject(pEteriorRingsEnum);}Marshal.ReleaseComObject(pSearchFeaCursor);UpdateFeaOuterRing(dicReturn, InnerAndOuterRingsResult);
}
/// <summary>
/// 更新外环
/// </summary>
/// <param name="dic"></param>
/// <param name="InnerAndOuterRingsResult"></param>
private void UpdateFeaOuterRing(Dictionary<string,string> dic, IFeatureClass InnerAndOuterRingsResult)
{int TagFiledIndex = InnerAndOuterRingsResult.FindField("TagInfo");int ExtentTagInfoFieldIndex = InnerAndOuterRingsResult.FindField("ExtentTagInfo");IFeatureCursor pUpdateFeaCursor = InnerAndOuterRingsResult.Update(null, true);IFeature pUpdateFea = null;while ((pUpdateFea = pUpdateFeaCursor.NextFeature()) != null){string strExtentTag = pUpdateFea.get_Value(ExtentTagInfoFieldIndex).ToString();if (dic.ContainsKey(strExtentTag)){pUpdateFea.set_Value(TagFiledIndex, 1);pUpdateFeaCursor.UpdateFeature(pUpdateFea);dic.Remove(strExtentTag);if (dic.Keys.Count == 0){Marshal.ReleaseComObject(pUpdateFeaCursor);return;}}}Marshal.ReleaseComObject(pUpdateFeaCursor);
}
/// <summary>
/// 获取环信息
/// </summary>
/// <param name="pPolygon"></param>
/// <returns></returns>
public string GetGeoTag(IPolygon pPolygon)
{string strExtentTag = string.Format("{0}_{1}_{2}_{3}_{4}_{5}",pPolygon.Envelope.XMin, pPolygon.Envelope.XMax, pPolygon.Envelope.YMin, pPolygon.Envelope.YMax, (pPolygon as IArea).Area, pPolygon.Length);return strExtentTag;
}
更多推荐
ArcEngine裂开要素,当要素存在内外环,外环标记为1,内环标记为0
发布评论