어떻게 IFeatureClass 객체를 XML로 직렬화 할 수 있습니까?ESRI에서 FeatureClass를 XML로 직렬화 ArcGIS
다른 ArcObjects에서 IXMLSerializer를 사용하기위한 리소스가 있지만 ISeializable을 구현하지 않아 IFeatureClass에서 작동하지 않습니다.
어떻게 IFeatureClass 객체를 XML로 직렬화 할 수 있습니까?ESRI에서 FeatureClass를 XML로 직렬화 ArcGIS
다른 ArcObjects에서 IXMLSerializer를 사용하기위한 리소스가 있지만 ISeializable을 구현하지 않아 IFeatureClass에서 작동하지 않습니다.
나는이 질문에 대한 내 자신의 답변을 실제로 발견했습니다. 저는 다른 사람들의 이익을 위해이 질문과 답변을 게시하고 제 접근 방식에 대한 피드백/비평을하고 있습니다.
IFeatureClass는 직접 직렬화 할 수 없지만 IRecordSet2는 될 수 있습니다. 그래서 첫 번째 단계는 IRecordSet2에 IFeatureClass를 변환하는 방법을 구현한다 : 당신이 IRecordSet2로 변환 할 때
public static XElement StoreAsXml(IFeatureClass fc)
{
// Can't serialize a feature class directly, so convert
// to recordset first.
IRecordSet2 recordset = ConvertToRecordset(fc);
IXMLSerializer xmlSer = new XMLSerializerClass();
string sXml = xmlSer.SaveToString(recordset, null, null);
return XElement.Parse(sXml);
}
그러나,이 기능을 잃게 :
private static IRecordSet2 ConvertToRecordset(IFeatureClass fc)
{
IRecordSet recSet = new RecordSetClass();
IRecordSetInit recSetInit = recSet as IRecordSetInit;
recSetInit.SetSourceTable(fc as ITable, null);
return (IRecordSet2) recSetInit;
}
를 그 다음은 XML 얻을 IXMLSerializer를 사용하기 쉽습니다 클래스 이름, 파일 쓰기, 내가 기능 클래스 이름을 유지하기 위해 XML에 요소를 추가 할 때 너무 : 이제
public static void StoreToFile(IFeatureClass fc, string filePath)
{
XElement xdoc = StoreAsXml(fc);
XElement el = new XElement("FeatureClass", new XAttribute("name", fc.AliasName),
xdoc);
el.Save(filePath);
}
을, 단지 기능으로 XML을 읽는 과정을 반전 수업. 요소가 기능 클래스 이름을 저장하기 위해 추가 된 기억
public static IFeatureClass RetreiveFromFile(string filepath)
{
XElement xdoc = XElement.Load(filepath);
string sName = xdoc.FirstAttribute.Value;
XNode recordset = xdoc.FirstNode;
return RetreiveFromXml(recordset, sName);
}
간단한 드 직렬화를 IRecordSet2를 얻을 수 IXMLSerializer를 사용하여 :
public static IFeatureClass RetreiveFromXml(XNode node, string sName)
{
IXMLSerializer xmlDeSer = new XMLSerializerClass();
IRecordSet2 recordset = (IRecordSet2)xmlDeSer.LoadFromString(node.ToString(), null, null);
return ConvertToFeatureClass(recordset, sName);
}
이
가 까다로운 부분이었다. 나는 IFeatureClass에 IRecordSet2 객체를 은밀한 ...이를 개선하는 방법에 대한 제안에 열려있어 :private static IFeatureClass ConvertToFeatureClass(IRecordSet2 rs, string sName)
{
IWorkspaceFactory pWSFact = new ShapefileWorkspaceFactory();
string sTempPath = Path.GetTempPath();
IFeatureWorkspace pFWS = (IFeatureWorkspace)pWSFact.OpenFromFile(sTempPath, 0);
// Will fail (COM E_FAIL) if the dataset already exists
DeleteExistingDataset(pFWS, sName);
IFeatureClass pFeatClass = null;
pFeatClass = pFWS.CreateFeatureClass(sName, rs.Fields, null, null, esriFeatureType.esriFTSimple,
"SHAPE", "");
// Copy incoming record set table to new feature class's table
ITable table = (ITable) pFeatClass;
table = rs.Table;
IFeatureClass result = table as IFeatureClass;
// It will probably work OK without this, but it makes the XML match more closely
IClassSchemaEdit3 schema = result as IClassSchemaEdit3;
schema.AlterAliasName(sName);
schema.AlterFieldAliasName("FID", "");
schema.AlterFieldModelName("FID", "");
schema.AlterFieldAliasName("Shape", "");
schema.AlterFieldModelName("Shape", "");
// If individual fields need to be edited, do something like this:
// int nFieldIndex = result.Fields.FindField("Shape");
// IFieldEdit2 field = (IFieldEdit2)result.Fields.get_Field(nFieldIndex);
// Cleanup
DeleteExistingDataset(pFWS, sName);
return table as IFeatureClass;
}
마지막으로, 기존의 데이터 집합을 삭제하기위한 유틸리티 메소드. 이것은 어딘가에서 복사/붙여 넣기했지만 소스를 기억할 수 없습니다.
public static void DeleteExistingDataset(IFeatureWorkspace pFWS, string sDatasetName)
{
IWorkspace pWS = (IWorkspace)pFWS;
IEnumDatasetName pEDSN = pWS.get_DatasetNames(esriDatasetType.esriDTFeatureClass);
bool bDatasetExists = false;
pEDSN.Reset();
IDatasetName pDSN = pEDSN.Next();
while (pDSN != null)
{
if (pDSN.Name == sDatasetName)
{
bDatasetExists = true;
break;
}
pDSN = pEDSN.Next();
}
if (bDatasetExists)
{
IFeatureClass pFC = pFWS.OpenFeatureClass(sDatasetName);
IDataset pDataset = (IDataset)pFC;
pDataset.Delete();
}
}