SDE 데이터를 shpefile로 컨버전할때 특정 피쳐클래스를 기준으로 클립하여 shapefile로 컨버전.
엔진 라이센스라 Clip(info 에서 사용가능) 를 사용할 수 없으므로 토폴로지의 Envelope으로 짤라서 shapefile 을 생성한다.
예를 들어 SDE에 한국 지형, 시설물, 등등등..에대한 공간 정보가 있을때 서울시를 기준으로 하여 shapefile을 만들려고 한다.
서울시 피쳐클래스를 기준으로 짤라내어 shapefile을 만든다.
Convert API를 이용하지 않고 SDE에 공간 데이터를 커서로 읽어 shapefile 에 직접 넣는 방법이다.
- SDE, Shpefile 워크스페이스를 생성한다.
/// <summary>
/// SDE 워크스페이스 오픈
/// </summary>
/// <returns></returns>
public IWorkspace openSDEWorkspace(String sServer, String sInstance, String sUser, String sPswd)
{
//IWorkspace pWS = null;
try
{
IPropertySet pPropSet;
pPropSet = new ESRI.ArcGIS.esriSystem.PropertySetClass();
pPropSet.SetProperty("SERVER", sServer.ToString());
pPropSet.SetProperty("INSTANCE", sInstance.ToString());
pPropSet.SetProperty("USER", sUser.ToString());
pPropSet.SetProperty("PASSWORD", sPswd.ToString());
pPropSet.SetProperty("DATABASE", "");
pPropSet.SetProperty("VERSION", "SDE.DEFAULT");
IWorkspaceFactory2 workspaceFactory;
workspaceFactory = (ESRI.ArcGIS.Geodatabase.IWorkspaceFactory2)new SdeWorkspaceFactoryClass();
return workspaceFactory.Open(pPropSet, 0);
}
catch (Exception e)
{
MessageBox.Show("SDE에 연결할수 없습니다.\n 서버에 SDE서비스가 시작되어 있는지 확인하시기 바랍니다.");
return null;
}
}
// <summary>
/// SHAPE Workspace를 반환한다.
/// </summary>
/// <param name="sOutputPath"></param>
/// <returns></returns>
public IWorkspace OpenShpWorkspace(String sOutputPath)
{
try
{
IWorkspaceFactory pFact;
IWorkspace pWorkspace;
pFact = new ShapefileWorkspaceFactory();
pWorkspace = pFact.OpenFromFile(sOutputPath, 0);
return pWorkspace; ;
}
catch (Exception e)
{
MessageBox.Show("SHAPE FILE에 연결할 수 없습니다");
return null;
}
}
-- 이제 SDE의 데이터를 Shapefile로 ...
//내릴때 커서
private IFeatureCursor copySourceCursor;
private IFeatureCursor insertFeatureCursor;
private IFeatureCursor pSearchFeatureCursor1;
private IFeatureCursor featureCursor;
/// <summary>
/// clip 해서 shapefile로 내리기
/// sourceWorkspace : sde 워크스페이스
/// targetworkspace : 쉐입(shapefile 워크스페이스)
/// TargetName : 만들 쉐입파일
/// SourceName ; SDE 피쳐클래스명
/// clipFeatureNm : 짜르려고 하는 피쳐
/// </summary>
/// <returns></returns>
//shape 파일로 내리기
public bool FeatureClipToShapfile(IWorkspace sourceWorkspace, IWorkspace targetWorkspace, string TargetName, string SourceName, string clipFeatureNm)
{
bool result = true;
try
{
IFeatureClass sourceFeatureClass = null;
IFeatureClass targetFeatureClass = null;
IFeatureClass clipFeatureClass = null;
//원본 피쳐 클래스(SDE)
IFeatureWorkspace sorceFW = sourceWorkspace as IFeatureWorkspace;
sourceFeatureClass = sorceFW.OpenFeatureClass(SourceName);
//클립 피쳐 클래스(SDE 에 있는 짜르려고 하는 피쳐클래스-예:서울시)
clipFeatureClass = sorceFW.OpenFeatureClass(clipFeatureNm);
//쿼리필터로 피쳐구하기
IQueryFilter pQueryFilter = new QueryFilter();
pQueryFilter.WhereClause = "지역='서울시'";//쿼리필터: 지역 레이어에서 서울시만 골라내기 ..
pSearchFeatureCursor1 = clipFeatureClass.Search(pQueryFilter, true);
IFeature pFeature = pSearchFeatureCursor1.NextFeature(); //서울시경계피
/************************
나중에.. 여러개 피쳐가 피쳐클래스로 경계를 이룰 경우 여러개의 피쳐를 토폴로지 UNION하여 하나의 피쳐로 만들어 놓고 작업....
***********************/
// define a spatial query filter
//공간쿼리..
SpatialFilter spatialFilter = new SpatialFilter();
// 필드 제거전에 피쳐커서 만듦
// IFeatureCursor interface provides access to a set of features in a feature class
// get a cursor based on the spatial query
featureCursor = sourceFeatureClass.Search(spatialFilter, true);
//필드 제거전에 피쳐커서에 일단 담아서 쓰자
IQueryFilter sQueryFilter = new QueryFilter();
copySourceCursor = sourceFeatureClass.Search(sQueryFilter, true);
/*
//쉐입파일에 맞지 않는 필드제거
* 필드를 제거하는 순간 전체 카운트도 달라 지므로 전체를 돌릴 필드와 실제 삭제되는 필드들을 분리
IFeatureBuffer copySource = sourceFeatureClass.CreateFeatureBuffer();
*/
IFields copyFields = copySourceCursor.Fields;
IFieldsEdit eFieldEdit = copyFields as IFieldsEdit;
IField field;
for (int i = 0; i < copySourceCursor.Fields.FieldCount; i++)
{
field = copyFields.get_Field(i);
if (field.Type == ESRI.ArcGIS.Geodatabase.esriFieldType.esriFieldTypeGlobalID && field.Type == ESRI.ArcGIS.Geodatabase.esriFieldType.esriFieldTypeGeometry && field.Type == ESRI.ArcGIS.Geodatabase.esriFieldType.esriFieldTypeOID && !field.Editable)
{
eFieldEdit.DeleteField(field);
if (i > 1)
{ //필드 삭제 하는 순간 전체 카운트가 줄어듬
--i;
}
}
if (field.Name.ToString().Trim().Equals("SHAPE.LEN"))
{
eFieldEdit.DeleteField(field);
if (i > 1)
{
--i;
}
}
if (field.Name.ToString().Trim().Equals("SHAPE.AREA"))
{
eFieldEdit.DeleteField(field);
if (i > 1)
{
--i;
}
}
}
//쉐입 피쳐클래스 만들기
IFeatureWorkspace targetFW = targetWorkspace as IFeatureWorkspace;
targetFeatureClass = targetFW.CreateFeatureClass(TargetName, copyFields, sourceFeatureClass.CLSID, sourceFeatureClass.EXTCLSID, sourceFeatureClass.FeatureType, sourceFeatureClass.ShapeFieldName, "");
// Loop through all the features and copy them over to the target shapefile.
// We need to cast each feature to an ITopologicalOperator, since
// this is where the clip method is, unfortunately.
ITopologicalOperator geom;
IFeatureBuffer FeaturBuffer;
int valueIndex;
IFeature feature = featureCursor.NextFeature();
insertFeatureCursor = targetFeatureClass.Insert(true);
FeaturBuffer = targetFeatureClass.CreateFeatureBuffer();
//짜르려고 하는 피쳐클래스의 토폴로지 envelope으로 짜름
if (feature != null)
{
IFields flds = feature.Fields;
int fieldCount = feature.Fields.FieldCount;
IRowBuffer pRowBuffer;
IFields pNewFields;
int NewFieldIndex;
//Copy the attributes of the orig feature the new feature
pRowBuffer = FeaturBuffer;
pNewFields = pRowBuffer.Fields;
while (feature != null)
{
IGeometry outgeom;
// get the shape and source to clip it
geom = feature.ShapeCopy as ITopologicalOperator;
geom.Clip(pFeature.Shape.Envelope);
geom.Buffer(0);
outgeom = geom as IGeometry;
FeaturBuffer.Shape = outgeom;
for (int i = 0; i < fieldCount; i++)
{
IField pField = flds.get_Field(i);
if (pField.Type != ESRI.ArcGIS.Geodatabase.esriFieldType.esriFieldTypeGlobalID && pField.Type != ESRI.ArcGIS.Geodatabase.esriFieldType.esriFieldTypeGeometry && pField.Type != ESRI.ArcGIS.Geodatabase.esriFieldType.esriFieldTypeOID && pField.Editable)
{
if (!pField.Name.StartsWith("OBJECTID") && !pField.Name.StartsWith("SHAPE_LEN") && !pField.Name.Equals("SHAPE_AREA") && !pField.Name.Equals("SHAPE.LEN") && !pField.Name.Equals("SHAPE.AREA"))
{
valueIndex = flds.FindField(pField.Name);
NewFieldIndex = pNewFields.FindField(pField.Name);
if (NewFieldIndex != -1)
{
FeaturBuffer.set_Value(FeaturBuffer.Fields.FindField(pField.Name), (feature.get_Value(valueIndex)));
}
}
}
}
//피처커서에 인서트
insertFeatureCursor.InsertFeature(FeaturBuffer);
feature = featureCursor.NextFeature();
}
//커서 넣기
try
{
insertFeatureCursor.Flush();
//트랜젝션 커밋
}
catch (COMException comExc)
{
result = false;
}
finally
{
//커서해제
if (insertFeatureCursor != null)
System.Runtime.InteropServices.Marshal.ReleaseComObject(insertFeatureCursor);
if (pSearchFeatureCursor1 != null)
System.Runtime.InteropServices.Marshal.ReleaseComObject(pSearchFeatureCursor1);
if (copySourceCursor != null)
System.Runtime.InteropServices.Marshal.ReleaseComObject(copySourceCursor);
if (featureCursor != null)
System.Runtime.InteropServices.Marshal.ReleaseComObject(featureCursor);
}
}
}
catch (Exception ex)
{ //커서해제
if(insertFeatureCursor!=null)
System.Runtime.InteropServices.Marshal.ReleaseComObject(insertFeatureCursor);
if(pSearchFeatureCursor1!=null)
System.Runtime.InteropServices.Marshal.ReleaseComObject(pSearchFeatureCursor1);
if(copySourceCursor!=null)
System.Runtime.InteropServices.Marshal.ReleaseComObject(copySourceCursor);
if(featureCursor!=null)
System.Runtime.InteropServices.Marshal.ReleaseComObject(featureCursor);
result = false;
return result;
}
finally
{
//커서해제
if (insertFeatureCursor != null)
System.Runtime.InteropServices.Marshal.ReleaseComObject(insertFeatureCursor);
if (pSearchFeatureCursor1 != null)
System.Runtime.InteropServices.Marshal.ReleaseComObject(pSearchFeatureCursor1);
if (copySourceCursor != null)
System.Runtime.InteropServices.Marshal.ReleaseComObject(copySourceCursor);
if (featureCursor != null)
System.Runtime.InteropServices.Marshal.ReleaseComObject(featureCursor);
}
return result;
}
'GIS' 카테고리의 다른 글
arcGIS Server (ADF) 포인트로 그래픽레이어에 라인그리기-포인트콜렉션사용 (polyline from point) (0) | 2009.11.11 |
---|---|
ArcGIS Server (ADF) Definition Query : 데피니션 쿼리 소스에서 구현하기 (0) | 2009.11.11 |
ArcGiS Server 9.3.X 쿼리필터(QueryFilter)시 maxrecords 500개 이상 가져오기 (Web ADF) (0) | 2009.11.09 |
(ArcObject-C#) SDE 공간정보 ShapeFile 컨버전, DBF(DBASE) 파일로 컨버전 (0) | 2009.10.01 |
ArcGis Server 9.3 맵 캐싱 설정후 특정 사용자에게서 맵 안보일때... (0) | 2009.02.17 |