阅读:1726回复:1
IDataset.cancopy什么时候为true ?
IDataset.cancopy什么时候为true ,什么时候为false,为什么我的一个IFeatureClass转换成IDataset后,candelete为true ,cancopy为false?
|
|
1楼#
发布于:2007-04-26 10:23
<P>如果我不想创建一个新的featureclass,然后把要复制的要素类的所有属性拷贝到新的featureclass中,也不想用 IFeatureDataConverter.ConvertFeatureClass (该方法的源码如下),我能用什么方法(比如icopyhelper接口和idataset.copy)来实现一个要素类的复制呢?(大多数的 idataset.cancopy的值是false,即不能直接复制)</P>
<P>源码如下:</P> <P>Public Sub FCLoader(pInPropertySet As IPropertySet, _<BR>sInName As String, _<BR>pOutPropertySet As IPropertySet, _<BR>sOutName As String)</P> <P>' Setup output workspace.<BR>Dim pOutWorkspaceName As IWorkspaceName<BR>Set pOutWorkspaceName = New WorkspaceName</P> <P>pOutWorkspaceName.ConnectionProperties = pOutPropertySet<BR>pOutWorkspaceName.WorkspaceFactoryProgID = "esriDataSourcesGDB.SDEWorkspaceFactory.1"</P> <P>' Set up for open.<BR>Dim pInWorkspaceName As IWorkspaceName<BR>Set pInWorkspaceName = New WorkspaceName<BR>pInWorkspaceName.ConnectionProperties = pInPropertySet<BR>pInWorkspaceName.WorkspaceFactoryProgID = "esriDataSourcesFile.ShapefileWorkspaceFactory.1"<BR>' Set in dataset and table names.<BR>Dim pInFCName As IFeatureClassName<BR>Set pInFCName = New FeatureClassName<BR>Dim pInDatasetName As IDatasetName<BR>Set pInDatasetName = pInFCName<BR>pInDatasetName.Name = sInName<BR>Set pInDatasetName.WorkspaceName = pInWorkspaceName</P> <P>' Set out dataset and table names.<BR>Dim pOutDatasetName As IDatasetName<BR>Dim pOutFCName As IFeatureClassName<BR>Set pOutFCName = New FeatureClassName<BR>Set pOutDatasetName = pOutFCName<BR>Set pOutDatasetName.WorkspaceName = pOutWorkspaceName<BR>pOutDatasetName.Name = sOutName<BR>' Open input Featureclass to get field definitions.<BR>Dim pName As IName<BR>Dim pInFC As IFeatureClass<BR>Set pName = pInFCName<BR>Set pInFC = pName.Open</P> <P>' Validate the field names.<BR>Dim pOutFCFields As IFields<BR>Dim pInFCFields As IFields<BR>Dim pFieldCheck As IFieldChecker<BR>Dim i As Long</P> <P>Set pInFCFields = pInFC.Fields<BR>Set pFieldCheck = New FieldChecker<BR>pFieldCheck.Validate pInFCFields, Nothing, pOutFCFields</P> <P>' +++ Loop through the output fields to find the geometry field<BR>Dim pGeoField As IField<BR>For i = 0 To pOutFCFields.FieldCount<BR>If pOutFCFields.Field(i).Type = esriFieldTypeGeometry Then<BR>Set pGeoField = pOutFCFields.Field(i)<BR>Exit For<BR>End If<BR>Next i<BR>' +++ Get the geometry field's geometry defenition<BR>Dim pOutFCGeoDef As IGeometryDef<BR>Set pOutFCGeoDef = pGeoField.GeometryDef</P> <P>' +++ Give the geometry definition a spatial index grid count and grid size<BR>Dim pOutFCGeoDefEdit As IGeometryDefEdit<BR>Set pOutFCGeoDefEdit = pOutFCGeoDef<BR>pOutFCGeoDefEdit.GridCount = 1<BR>pOutFCGeoDefEdit.GridSize(0) = DefaultIndexGrid(pInFC)<BR>Set pOutFCGeoDefEdit.SpatialReference = pGeoField.GeometryDef.SpatialReference</P> <P>Dim pQueryFilter As IQueryFilter<BR>Set pQueryFilter = New QueryFilter<BR>pQueryFilter.SubFields = "Shape,STATE_NAME"</P> <P>' Load the table.<BR>Dim pFCToFC As IFeatureDataConverter<BR>Set pFCToFC = New FeatureDataConverter</P> <P>Dim pEnumErrors As IEnumInvalidObject<BR>Set pEnumErrors = pFCToFC.ConvertFeatureClass(pInFCName, pQueryFilter, Nothing, pOutFCName, pOutFCGeoDef, pOutFCFields, "", 1000, 0)</P> <P>' If some of the records do not load, report to report window.</P> <P>Dim pErrInfo As IInvalidObjectInfo<BR>'pEnumErrors.Reset<BR>Set pErrInfo = pEnumErrors.Next<BR>If Not pErrInfo Is Nothing Then<BR>Debug.Print "Load completed with errors"<BR>Else<BR>Debug.Print "Load completed"<BR>End If</P> <P>Exit Sub<BR>ErrorRoutine:<BR>Debug.Print "Load Failed: Errors: " ; Err.Number ; " " ; Err.Description<BR>End Sub</P> <P>Private Function DefaultIndexGrid(InFC As IFeatureClass) As Double<BR>' Calculate approximate first grid<BR>' based on the average of a random sample of feature extents times five<BR>Dim lngNumFeat As Long<BR>Dim lngSampleSize As Long<BR>Dim pFields As IFields<BR>Dim pField As IField<BR>Dim strFIDName As String<BR>Dim strWhereClause As String<BR>Dim lngCurrFID As Long<BR>Dim pFeat As IFeature<BR>Dim pFeatCursor As IFeatureCursor<BR>Dim pFeatEnv As IEnvelope<BR>Dim pQueryFilter As IQueryFilter<BR>Dim pNewCol As New Collection<BR>Dim lngKMax As Long</P> <P>Dim dblMaxDelta As Double<BR>dblMaxDelta = 0<BR>Dim dblMinDelta As Double<BR>dblMinDelta = 1000000000000#<BR>Dim dblSquareness As Double<BR>dblSquareness = 1</P> <P>Dim i As Long<BR>Dim j As Long<BR>Dim k As Long</P> <P>Const SampleSize = 1<BR>Const Factor = 1</P> <P>' Create a recordset</P> <P>Dim ColInfo(0), c0(3)</P> <P>c0(0) = "minext"<BR>c0(1) = CInt(5)<BR>c0(2) = CInt(-1)<BR>c0(3) = False</P> <P>ColInfo(0) = c0</P> <P>lngNumFeat = InFC.FeatureCount(Nothing) - 1<BR>If lngNumFeat 1000 Then lngSampleSize = 1000<BR>' Get the ObjectID Fieldname of the feature class<BR>Set pFields = InFC.Fields<BR>' FID is always the first field<BR>Set pField = pFields.Field(0)<BR>strFIDName = pField.Name<BR>' Add every nth feature to the collection of FIDs<BR>For i = 1 To lngNumFeat Step CLng(lngNumFeat / lngSampleSize)<BR>pNewCol.Add i<BR>Next i<BR>For j = 0 To pNewCol.Count - 1 Step 250<BR>' Will we top out the features before the next 250 chunk?<BR>lngKMax = Min(pNewCol.Count - j, 250)<BR>strWhereClause = strFIDName + " IN("<BR>For k = 1 To lngKMax<BR>strWhereClause = strWhereClause + CStr(pNewCol.Item(j + k)) + ","<BR>Next k<BR>' Remove last comma and add close parenthesis<BR>strWhereClause = Mid(strWhereClause, 1, Len(strWhereClause) - 1) + ")"<BR>Set pQueryFilter = New QueryFilter<BR>pQueryFilter.WhereClause = strWhereClause<BR>Set pFeatCursor = InFC.Search(pQueryFilter, True)<BR>Set pFeat = pFeatCursor.NextFeature<BR>While Not pFeat Is Nothing<BR>' Get the extent of the current feature<BR>Set pFeatEnv = pFeat.Extent<BR>' Find the min, max side of all extents. The "Squareness", a measure<BR>' of how close the extent is to a square, is accumulated for later<BR>' average calculation.<BR>dblMaxDelta = Max(dblMaxDelta, Max(pFeatEnv.Width, pFeatEnv.Height))<BR>dblMinDelta = Min(dblMinDelta, Min(pFeatEnv.Width, pFeatEnv.Height))<BR>' lstSort.AddItem Max(pFeatEnv.Width, pFeatEnv.Height)<BR>If dblMinDelta <> 0 Then<BR>dblSquareness = dblSquareness + ((Min(pFeatEnv.Width, pFeatEnv.Height) / (Max(pFeatEnv.Width, pFeatEnv.Height))))<BR>Else<BR>dblSquareness = dblSquareness + 0.0001<BR>End If<BR>Set pFeat = pFeatCursor.NextFeature<BR>Wend<BR>Next j</P> <P>' If the average envelope approximates a square set the grid size half<BR>' way between the min and max sides. If the envelope is more rectangular,<BR>' then set the grid size to half of the max.<BR>If ((dblSquareness / lngSampleSize) > 0.5) Then<BR>DefaultIndexGrid = (dblMinDelta + ((dblMaxDelta - dblMinDelta) / 2)) * Factor<BR>Else<BR>DefaultIndexGrid = (dblMaxDelta / 2) * Factor<BR>End If<BR>End Function</P> <P>Private Function Min(v1 As Variant, v2 As Variant) As Variant<BR>Min = IIf(v1 v2, v1, v2)<BR>End Function</P> <P>Function DefaultIndexGridPoint(InFC As IFeatureClass) As Double<BR>' Calculates the Index grid based on input feature class<BR>' Get the dataset<BR>Dim pGeoDataSet As IGeoDataset<BR>Set pGeoDataSet = InFC<BR>' Get the envelope of the input dataset<BR>Dim pEnvelope As IEnvelope<BR>Set pEnvelope = pGeoDataSet.Extent<BR>'Calculate approximate first grid<BR>Dim lngNumFeat As Long<BR>Dim dblArea As Double<BR>lngNumFeat = InFC.FeatureCount(Nothing)<BR>If lngNumFeat = 0 Or pEnvelope.IsEmpty Then<BR>' when there are no features or an empty bnd - return 1000<BR>DefaultIndexGridPoint = 1000<BR>Else<BR>dblArea = pEnvelope.Height * pEnvelope.Width<BR>' approximate grid size is the square root of area over the number of features<BR>DefaultIndexGridPoint = Sqr(dblArea / lngNumFeat)<BR>End If<BR>Set pGeoDataSet = Nothing<BR>Set pEnvelope = Nothing<BR>End Function</P> <P>copyright esri comperny</P> |
|
|