bool ArcmapDataBase::checkLayerTopology(dan::Object<iDataPlugin::IPGLayer> layer, const dan::DString &featureDatasetname, const dan::DString &topologyName, const dan::DString &topologyRuleName)
{
/*
参数含义:layer :需要进行拓扑检查的图层 featureDatasetname :所需创建的要素数据集名称 topologyName: 表示新建的拓扑名称 topologyRuleName :表示创建拓扑规则的名称;
*/
/*
拓扑检查步骤:
1. 新建要素数据集
2. 导入要素类(单个/多个)
3. 新建拓扑
4. 添加拓扑规则
5. 验证拓扑
6. 导入拓扑图层
*/
//得到当前要素工作空间mdb
IFeatureWorkspacePtr ipFeatureWorkspace = getWorkspace();
dan::Object<ArcmapLayer> aLayer = layer;
//获取当前空间参照(get ISpatialReference)
IFeatureClassPtr ipFeatureClass = aLayer->getFeatureClass();
IGeoDatasetPtr ipGeoDataset = ipFeatureClass;
ISpatialReferencePtr ipSpatialRefrence;
ipGeoDataset->get_SpatialReference(&ipSpatialRefrence); //得到空间参照SpatialReference
//创建要素数据集---(1.判断要素类是否存在要素数据集--(1)存在便无需创建 (2)不存在时则需创建相应要素数据集
IFeatureDatasetPtr ipFeatureDataset;
ipFeatureClass->get_FeatureDataset(&ipFeatureDataset); //判断是否存在该数据集;
if (ipFeatureDataset == nullptr)
{
/*1. 创建要素数据集 */
ipFeatureWorkspace->CreateFeatureDataset(_bstr_t((LPCTSTR)featureDatasetname.utf16()), ipSpatialRefrence, &ipFeatureDataset);
/*2. 导入要素类到要素数据集 */
IDatasetContainerPtr ipDatasetContainer = ipFeatureDataset;
IDatasetPtr ipInDataset = ipFeatureClass; //ipFeatureClass为同一工作空间下的要素类;
ipDatasetContainer->AddDataset(ipInDataset);
/*3. 新建拓扑 */
//相关变量定义
ITopologyContainerPtr ipTopologyContainer = ipFeatureDataset; //将数据集存入iTopology--用于创建拓扑
ITopologyPtr ipTopology;
double ipClusterTolerance; //返回默认容差
ipTopologyContainer->get_DefaultClusterTolerance(&ipClusterTolerance);
ipTopologyContainer->CreateTopology(_bstr_t((LPCTSTR)topologyName.utf16()), ipClusterTolerance, -1, L"", &ipTopology);
long featureId;
dan::DString ipJoinLayerName = layer->layerName();
IFeatureClassPtr ipJoinFeatureClass;
ipFeatureWorkspace->OpenFeatureClass(_bstr_t((LPCTSTR)ipJoinLayerName.utf16()), &ipJoinFeatureClass);
ipJoinFeatureClass->get_FeatureClassID(&featureId);
IClassPtr ipClass = ipJoinFeatureClass;
ipTopology->AddClass(ipClass,5, 1, 1, VARIANT_FALSE); //添加参与拓扑的图层
/*3. 添加拓扑规则 */
ITopologyRulePtr ipGapTopologyRule(CLSID_TopologyRule); //空隙
ipGapTopologyRule->put_OriginClassID(featureId);
ipGapTopologyRule->put_TopologyRuleType(esriTRTAreaNoGaps); //层内要素是否有空隙;
ipGapTopologyRule->put_Name(_bstr_t((LPCTSTR)topologyRuleName.utf16())); //dstring转BSTR
ipGapTopologyRule->put_AllOriginSubtypes(VARIANT_TRUE);
ITopologyRuleContainerPtr ipTopologyRuleContainer = (ITopologyRuleContainerPtr)ipTopology;
VARIANT_BOOL checkTopoRule;
ipTopologyRuleContainer->get_CanAddRule(ipGapTopologyRule, &checkTopoRule);
if (checkTopoRule == VARIANT_TRUE)
{
ipTopologyRuleContainer->AddRule(ipGapTopologyRule); //添加拓扑规则;
}
else
{
return false;
}
/*4. 验证拓扑 */
IGeoDatasetPtr ipCurGeoDataset = ipTopology;
IEnvelopePtr ipEnvelope;
ipCurGeoDataset->get_Extent(&ipEnvelope);
IPolygonPtr ipPolygon(CLSID_Polygon);
ISegmentCollectionPtr ipSegmentCollection = ipPolygon;
ipSegmentCollection->SetRectangle(ipEnvelope);
IPolygonPtr ipCurPolygon;
ipTopology->get_DirtyArea(ipPolygon, &ipCurPolygon);
if (ipCurPolygon != nullptr)
{
IEnvelopePtr ipAreaToValidate;
ipPolygon->get_Envelope(&ipAreaToValidate);
IEnvelopePtr ipAreaEffectValidated;
ipTopology->ValidateTopology(ipAreaToValidate, &ipAreaEffectValidated);
}
//验证规则是否实现
if (ipSegmentCollection == nullptr)
{
return false;
}
else
{
return true;
}
}
else
{
ITopologyContainerPtr ipTopologyContainer = ipFeatureDataset; //将数据集存入iTopology--用于创建拓扑
ITopologyPtr ipTopology;
double ipClusterTolerance; //返回默认容差
ipTopologyContainer->get_DefaultClusterTolerance(&ipClusterTolerance);
ipTopologyContainer->CreateTopology(_bstr_t((LPCTSTR)topologyName.utf16()), ipClusterTolerance, -1, L"", &ipTopology);
//添加参与拓扑的图层:
long featureId;
dan::DString ipJoinLayerName = layer->layerName();
IFeatureClassPtr ipJoinFeatureClass;
ipFeatureWorkspace->OpenFeatureClass(_bstr_t((LPCTSTR)ipJoinLayerName.utf16()), &ipJoinFeatureClass);
ipJoinFeatureClass->get_FeatureClassID(&featureId);
IClassPtr ipClass = ipJoinFeatureClass;
ipTopology->AddClass(ipClass, 5, 1, 1, VARIANT_FALSE); //添加参与拓扑的图层
/* 添加拓扑规则 */
ITopologyRulePtr ipGapTopologyRule(CLSID_TopologyRule);
ipGapTopologyRule->put_TopologyRuleType(esriTRTAreaNoGaps); //层内要素不能有空隙
ipGapTopologyRule->put_Name(_bstr_t((LPCTSTR)topologyRuleName.utf16())); //dstring转BSTR
ipGapTopologyRule->put_OriginClassID(featureId);
ipGapTopologyRule->put_AllOriginSubtypes(VARIANT_TRUE);
ITopologyRuleContainerPtr ipTopologyRuleContainer = ipTopology;
VARIANT_BOOL checkTopoRule;
ipTopologyRuleContainer->get_CanAddRule(ipGapTopologyRule, &checkTopoRule);
if (checkTopoRule == VARIANT_TRUE) // 判断能否添加该规则
{
ipTopologyRuleContainer->AddRule(ipGapTopologyRule); //添加拓扑规则;
}
else
{
return false;
}
/* 验证拓扑 */
IGeoDatasetPtr ipCurGeoDataset = ipTopology;
IEnvelopePtr ipEnvelope;
ipCurGeoDataset->get_Extent(&ipEnvelope);
IPolygonPtr ipPolygon(CLSID_Polygon);
ISegmentCollectionPtr ipSegmentCollection = ipPolygon;
ipSegmentCollection->SetRectangle(ipEnvelope);
IPolygonPtr ipCurPolygon;
ipTopology->get_DirtyArea(ipPolygon, &ipCurPolygon);
if (ipCurPolygon != nullptr)
{
IEnvelopePtr ipAreaToValidate;
ipPolygon->get_Envelope(&ipAreaToValidate);
IEnvelopePtr ipAreaEffectValidated;
ipTopology->ValidateTopology(ipAreaToValidate, &ipAreaEffectValidated);
}
//验证规则是否实现;
if (ipSegmentCollection == nullptr)
{
return false;
}
else
{
return true;
}
}
return false;
}