40楼#
发布于:2005-08-02 00:25
<P>如何将Map中显示的图形转化成栅格文件</P>
<P>本例要实现的是如何将当前激活的Map中显示的图形转化成栅格文件。</P> <P>l 要点</P> <P>通过IMap实例获得IActiveView接口对象,定义IExporter接口变量,使用TiffExporter实现该接口并对其中的属性进行赋值,使用IActiveView.Output方法将Map中显示的图形导出。</P> <P>主要用到IActiveView接口,IExporter接口和IEnvelope接口。</P> <P>l 程序说明</P> <P>函数Output将当前激活的Map中显示的图形转化成栅格文件,栅格文件路径及名称由参数sFileAllName确定。</P> <P>l 代码</P> <P> <P>Private Sub Output(ByVal sFileAllName As String)</P> <P> Dim pMxDocument As IMxDocument</P> <P> Dim pActiveView As IActiveView</P> <P> Dim pExporter As IExporter</P> <P> Dim pEnvelope As IEnvelope</P> <P> Dim ptagRECT As tagRECT</P> <P> Dim pTrackCancel As ITrackCancel</P> <P> Dim lscreenResolution As Long </P> <P>On Error GoTo ErrorHandler:</P> <P> Set pMxDocument = ThisDocument</P> <P> Set pActiveView = pMxDocument.ActiveView</P> <P> lscreenResolution = pActiveView.ScreenDisplay.DisplayTransformation.Resolution</P> <P> ptagRECT.Top = 0</P> <P> ptagRECT.Left = 0</P> <P> ptagRECT.Right = pActiveView.Extent.Width</P> <P> ptagRECT.bottom = pActiveView.Extent.Height</P> <P> 'We must calculate the size of the user specified Rectangle in Device units</P> <P> 'Hence convert width and height</P> <P> Set pEnvelope = New Envelope</P> <P> pEnvelope.PutCoords ptagRECT.Left, ptagRECT.bottom, ptagRECT.Right, ptagRECT.Top</P> <P> Set pExporter = New TiffExporter</P> <P> pExporter.Resolution = lscreenResolution</P> <P> pExporter.ExportFileName = sFileAllName</P> <P> pExporter.PixelBounds = pEnvelope</P> <P> Set pTrackCancel = New CancelTracker</P> <P> pActiveView.Output pExporter.StartExporting, lscreenResolution, _</P> <P> ptagRECT, pActiveView.Extent, pTrackCancel</P> <P> </P> <P> pExporter.FinishExporting</P> <P> Exit Sub</P> <P>ErrorHandler:</P> <P> MsgBox Err.Description</P> <P>End Sub</P> <P>Private Sub UIButtonControl1_Click()</P> <P> Dim pVBProject As VBProject</P> <P>On Error GoTo ErrorHandler:</P> <P> Set pVBProject = ThisDocument.VBProject</P> <P> Output pVBProject.FileName ; "\..\..\..\.." ; "\data\MyTifFile.tif"</P> <P> Exit Sub</P> <P>ErrorHandler:</P> <P> MsgBox Err.Description</P> <P>End Sub</P> <br> |
|
41楼#
发布于:2005-08-02 22:40
<img src="images/post/smile/dvbbs/em02.gif" /><img src="images/post/smile/dvbbs/em02.gif" /><img src="images/post/smile/dvbbs/em02.gif" /><img src="images/post/smile/dvbbs/em02.gif" /><img src="images/post/smile/dvbbs/em02.gif" /><img src="images/post/smile/dvbbs/em01.gif" /><img src="images/post/smile/dvbbs/em01.gif" /><img src="images/post/smile/dvbbs/em01.gif" />
|
|
42楼#
发布于:2005-08-02 23:36
如何打开选中的层或独立表的属性窗口
<P>本例实现的是如何打开选中的层或独立表的属性窗口(Attribute Table)。主要用到ITableWindow和ITableWindow2接口。</P> <P>l 要点</P> <P>首先需要选中一个层或独立表。可在UI Button Cotrol的Enabled事件中测试用户选定了有效的对象后,才使按钮有效。</P> <P>然后判断属性窗口是否已经打开。如果尚未打开,则创建新的ITableView2对象。</P> <P>l 程序说明</P> <P>过程UIBAttributeWindow_Click调用过程OpenAttribWnd实现功能。</P> <P>函数UIBAttributeWindow_Enabled用来测试用户是否已正确选中了层或独立表,如果是,则使按钮有效。</P> <P>过程OpenAttribWnd是功能模块,实现了属性窗口的测试和创建,以及显示。</P> <P>l 代码</P> <P>Option Explicit</P> <P>Private Sub UIBAttributeWindow_Click()</P> <P> Call OpenAttribWnd</P> <P>End Sub </P> <P>Private Function UIBAttributeWindow_Enabled() As Boolean</P> <P> Dim pMxDocument As IMxDocument</P> <P> Dim pSelectedItem As IUnknown</P> <P> Dim bEnabled As Boolean</P> <P> Set pMxDocument = ThisDocument</P> <P> Set pSelectedItem = pMxDocument.SelectedItem</P> <P> bEnabled = True</P> <P> ' Disable if the selected item is nothing or if</P> <P> ' it is not a layer or table</P> <P> If pSelectedItem Is Nothing Then</P> <P> bEnabled = False</P> <P> ElseIf (TypeOf pSelectedItem Is IFeatureLayer) Or (TypeOf pSelectedItem Is IStandaloneTable) Then</P> <P> bEnabled = True</P> <P> End If</P> <P> UIBAttributeWindow_Enabled = bEnabled</P> <P>End Function </P> <P>Private Sub OpenAttribWnd()</P> <P> Dim pMxDocument As IMxDocument</P> <P> Dim pLayer As ILayer</P> <P> Dim pStandaloneTable As IStandaloneTable</P> <P> Dim pSelectedItem As IUnknown</P> <P> Dim pTableWindowExist As ITableWindow</P> <P> Dim pTableWindow2 As ITableWindow2</P> <P> Dim bSetProperties As Boolean</P> <P> On Error GoTo ErrorHandler:</P> <P> Set pMxDocument = ThisDocument</P> <P> Set pSelectedItem = pMxDocument.SelectedItem</P> <P> Set pTableWindow2 = New TableWindow</P> <P> ' Determine the selected item's type</P> <P> ' Exit sub if item is not a feature layer or standalone table</P> <P> If TypeOf pSelectedItem Is IFeatureLayer Then</P> <P> Set pLayer = pSelectedItem</P> <P> Set pTableWindowExist = pTableWindow2.FindViaLayer(pLayer)</P> <P> ' Check if a table already exist; if not create one</P> <P> If pTableWindowExist Is Nothing Then</P> <P> Set pTableWindow2.Layer = pLayer</P> <P> bSetProperties = True</P> <P> End If</P> <P> ElseIf TypeOf pSelectedItem Is IStandaloneTable Then</P> <P> Set pStandaloneTable = pSelectedItem</P> <P> Set pTableWindowExist = pTableWindow2.FindViaStandaloneTable(pStandaloneTable)</P> <P> ' Check if a table already exists; if not, create one</P> <P> If pTableWindowExist Is Nothing Then</P> <P> Set pTableWindow2.StandaloneTable = pStandaloneTable</P> <P> bSetProperties = True</P> <P> End If</P> <P> End If</P> <P> If bSetProperties Then</P> <P> pTableWindow2.TableSelectionAction = esriSelectFeatures</P> <P> pTableWindow2.ShowSelected = False</P> <P> pTableWindow2.ShowAliasNamesInColumnHeadings = True</P> <P> Set pTableWindow2.Application = Application</P> <P> Else</P> <P> Set pTableWindow2 = pTableWindowExist</P> <P> End If</P> <P> ' Ensure Table Is Visible</P> <P> If Not pTableWindow2.IsVisible Then</P> <P> pTableWindow2.Show True</P> <P> End If</P> <P> Exit Sub</P> <P>ErrorHandler:</P> <P> MsgBox Err.Description</P> <P>End Sub</P> <br> |
|
43楼#
发布于:2005-08-02 23:36
<P>如何拷贝属性表中的一行</P>
<P>本例要实现的是如何将所有属性表(Attribute Table)中的行拷贝到Windows剪贴板,使用户能使用文本编辑器等软件对选中的数据做进一步编辑,从而满足特殊要求。行中的每个属性用半角字符的逗号“,”分隔,行间用换行符分隔。</P> <P>l 要点</P> <P>首先需要取得某属性表中的所有选中记录的全部属性,以一个字符串来存储。因为在属性表中选取中记录(Row)后,层中的相应记录(Feature)也将选中。两种途径都能获得所需属性值。</P> <P>得到所需的字符串sResult后,就可以将其拷贝到剪贴板。在VB中剪贴板是全局对象。可像如下使用:</P> <P>Clipboard.Clear</P> <P>Clipboard.SetText sResult</P> <P>本例将在VBA中实现相同的功能。用到了IGraphicsContianer、IGraphicsContainerSelect、ITextElement、IElement、IClipboardFormat接口。 </P> <P>l 程序说明</P> <P>过程UIBCopyRow_Click是实现模块,调用过程CopyRow实现功能。过程CopyRow将选中行的全部属性值(忽略Shape属性)连接成字符串,然后创建TextElement对象,并添加到IGraphicsContainer对象的选择集中,再调用TextClipboardFormat的Copy方法,把字符拷贝到Windows剪贴板。</P> <P>l 代码</P> <P>Option Explicit</P> <P>Private Sub UIBCopyRow_Click()</P> <P> Call CopyRow</P> <P>End Sub </P> <P>Public Sub CopyRow()</P> <P> Dim pMxDocument As IMxDocument</P> <P> Dim pMap As IMap</P> <P> Dim pActiveView As IActiveView</P> <P> Dim pGraphicsContainer As IGraphicsContainer</P> <P> Dim pGraphicsContainerS As IGraphicsContainerSelect</P> <P> Dim pFields As IFields</P> <P> Dim iCounter As Integer</P> <P> Dim iIndex As Integer</P> <P> Dim pTextElement As ITextElement</P> <P> Dim pElement As IElement</P> <P> Dim sResult As String</P> <P> Dim pEnumFeature As IEnumFeature</P> <P> Dim pEnumFeatureS As IEnumFeatureSetup</P> <P> Dim pFeature As IFeature</P> <P> Dim pClipboardFormat As IClipboardFormat</P> <P> On Error GoTo ErrorHandler</P> <P> ' Used for string operation on the clipboard</P> <P> Set pClipboardFormat = New TextClipboardFormat</P> <P> Set pMxDocument = ThisDocument</P> <P> Set pActiveView = pMxDocument.ActivatedView</P> <P> Set pMap = pMxDocument.FocusMap</P> <P> Set pGraphicsContainer = pMap</P> <P> ' Get selected features to retieve their attribute values</P> <P> Set pEnumFeature = pMap.FeatureSelection</P> <P> Set pEnumFeatureS = pEnumFeature</P> <P> pEnumFeatureS.AllFields = True</P> <P> Set pFeature = pEnumFeature.Next</P> <P> If pFeature Is Nothing Then</P> <P> MsgBox "No row selected"</P> <P> Exit Sub</P> <P> End If</P> <P> Set pFields = pFeature.Fields</P> <P> iCounter = pFields.FieldCount</P> <P> Do Until pFeature Is Nothing</P> <P> For iIndex = 0 To iCounter - 1</P> <P> If Not TypeOf pFeature.Value(iIndex) Is IGeometry Then</P> <P> sResult = sResult ; pFeature.Value(iIndex) ; ","</P> <P> End If</P> <P> Next iIndex</P> <P> ' Remove the trailing comma</P> <P> sResult = Left(sResult, Len(sResult) - 1)</P> <P> sResult = sResult ; vbNewLine</P> <P> Set pFeature = pEnumFeature.Next</P> <P> Loop</P> <P> ' If you're tending to build a dll to implement the same function and</P> <P> ' programming in VB enviroment, simply use the next to statement</P> <P> ' to copy the string into windows clippboard</P> <P> ' Clipboard.Clear</P> <P> ' Clipboard.SetText sResult</P> <P> ' Otherwise, programe as follows</P> <P> ' Copy the string into clippboard using objects included in esriCore</P> <P> </P> <P> ' To clear clippboard</P> <P> pClipboardFormat.Paste pMxDocument</P> <P> pGraphicsContainer.DeleteAllElements</P> <P> ' Construct a new TextElement with the string to copy into clipboard</P> <P> Set pTextElement = New TextElement</P> <P> pTextElement.Text = sResult</P> <P> Set pElement = pTextElement</P> <P> ' Point(100, 100) is for temporary use</P> <P> pElement.Geometry = pActiveView.ScreenDisplay.DisplayTransformation _</P> <P> .ToMapPoint(100, 100)</P> <P> Set pGraphicsContainer = pMap</P> <P> pGraphicsContainer.AddElement pElement, 0</P> <P> Set pGraphicsContainerS = pGraphicsContainer</P> <P> pGraphicsContainerS.UnselectAllElements</P> <P> pGraphicsContainerS.SelectElement pElement</P> <P> pClipboardFormat.copy pMxDocument</P> <P> pGraphicsContainerS.UnselectElement pElement</P> <P> pGraphicsContainer.DeleteElement pElement</P> <P> pActiveView.Refresh</P> <P> Exit Sub</P> <P>ErrorHandler:</P> <P> MsgBox Err.Description</P> <P>End Sub </P> |
|
44楼#
发布于:2005-08-02 23:37
<P>如何为当前层或独立表创建一个Summary表</P>
<P>本例要实现的是如何按某一字段“分组”(dissolve),统计其它字段的数据信息摘要(创建Summary表)。可得到的主要信息包括该字段值相同的每组记录中的记录数量、最大值、最小值、和、平均值等。主要用到IBasicGeoprocessor接口的Dissolve方法。</P> <P>l 要点</P> <P>为当前层创建Summary表,要得到当前层的引用,并确定在其上执行Dissolve操作的字段。对独立表的操作方法与层的操作类似。</P> <P>l 程序说明</P> <P>过程UIBCreateSummaryTable_Click是实现模块,调用过程CreateSummaryTable实现功能。过程CreateSummaryTable中应先确认层(例中为states)和要“Dissolve”的字段(例中为SUB_REGION)存在,同时要定义摘要表的名字(本例为SumStates)。</P> <P>然后指定执行Dissolve方法的操作符(如Minimum,Count,Average等)和在其上施行操作的字段名(例中为AREA)。操作结果作为独立表添加到当前Map。</P> <P>因为Dissolve方法参数表中的“输入表”和“输出数据集的名字”都是引用,为了避免多次调用过程使最终SumStates表中的结果不唯一,每次执行Dissolve前,将SumStates的已存内容删除。</P> <P>l 代码</P> <P>Private Sub UIBCreateSummaryTable_Click()</P> <P> Call CreateSummaryTable</P> <P>End Sub</P> <P>Public Sub CreateSummaryTable()</P> <P> Dim pMxDocument As IMxDocument</P> <P> Dim pMap As IMap</P> <P> Dim pLayer As ILayer</P> <P> Dim pFeatLayer As IFeatureLayer</P> <P> Dim iCount As Integer</P> <P> Dim pFeatureClass As IFeatureClass</P> <P> Dim pTable As ITable</P> <P> Dim pDataSet As IDataset</P> <P> Dim pWorkspace As IWorkspace</P> <P> Dim pWorkspaceDataset As IDataset</P> <P> Dim pWorkspaceName As IName</P> <P> Dim pOutTableName As ITableName</P> <P> Dim pOutDatasetName As IDatasetName</P> <P> Dim pEnumDataset As IEnumDataset</P> <P> Dim pBasicGeoprocessor As IBasicGeoprocessor</P> <P> Dim pSumTable As ITable</P> <P> Dim pStandaloneTable As IStandaloneTable</P> <P> Dim pStandaloneTableColl As IStandaloneTableCollection</P> <P> ' Define current layer name and output table name</P> <P> Const sLayerName As String = "states"</P> <P> Const sSumTableName As String = "SumStates"</P> <P> Set pMxDocument = ThisDocument</P> <P> Set pMap = pMxDocument.FocusMap</P> <P> On Error GoTo ErrorHandler </P> <P> Set pMxDocument = ThisDocument</P> <P> Set pMap = pMxDocument.FocusMap</P> <P> On Error GoTo ErrorHandler </P> <P> ' Find the layer named states</P> <P> For iCount = 0 To pMap.LayerCount - 1</P> <P> Set pLayer = pMap.Layer(iCount)</P> <P> If TypeOf pLayer Is IFeatureLayer Then</P> <P> If pLayer.Name = sLayerName Then</P> <P> Set pFeatLayer = pLayer</P> <P> Exit For</P> <P> End If</P> <P> End If</P> <P> Next </P> <P> If pFeatLayer Is Nothing Then</P> <P> MsgBox "The " ; sLayerName ; " layer was not found"</P> <P> Exit Sub</P> <P> End If</P> <P> ' Get the workspace of the states layer</P> <P> Set pFeatureClass = pFeatLayer.FeatureClass</P> <P> Set pTable = pFeatureClass</P> <P> Set pDataSet = pTable</P> <P> Set pWorkspace = pDataSet.Workspace</P> <P> Set pWorkspaceDataset = pWorkspace</P> <P> Set pWorkspaceName = pWorkspaceDataset.FullName</P> <P> ' Set up the output table</P> <P> Set pOutTableName = New TableName</P> <P> Set pOutDatasetName = pOutTableName</P> <P> pOutDatasetName.Name = sSumTableName</P> <P> Set pOutDatasetName.WorkspaceName = pWorkspaceName</P> <P> ' Make sure there is a field called SUB_REGION in the layer</P> <P> If pTable.FindField("SUB_REGION") = -1 Then</P> <P> MsgBox "There must be a field named SUB_REGION in states"</P> <P> Exit Sub</P> <P> End If</P> <P> ' Check if SumStates.dbf file already exist: if yes, delete it</P> <P> Set pEnumDataset = pWorkspace.Datasets(esriDTTable)</P> <P> Set pWorkspaceDataset = pEnumDataset.Next</P> <P> Do Until pWorkspaceDataset Is Nothing</P> <P> If pWorkspaceDataset.Name = pOutDatasetName.Name Then</P> <P> pWorkspaceDataset.Delete</P> <P> Exit Do</P> <P> End If</P> <P> Set pWorkspaceDataset = pEnumDataset.Next</P> <P> Loop</P> <P> ' Perform the summarize. Note the summary fields string (minimum.SUB_REGION ...)</P> <P> ' below. This is a comma-delimited string that lists the generated summary</P> <P> ' fields. Each field must start with a keyword, and be followed by .fieldName,</P> <P> ' where fieldName is the name of a field in the original table.</P> <P> '</P> <P> ' If you specify the Shape field, you must use the keyword 'Dissolve'. This</P> <P> ' is not used below since we are creating a non-spatial summary table.</P> <P> Set pBasicGeoprocessor = New BasicGeoprocessor</P> <P> Set pSumTable = pBasicGeoprocessor.Dissolve(pTable, False, "SUB_REGION", _</P> <P> "Minimum.SUB_REGION, Count.SUB_REGION, Sum.AREA, Average.AREA," ; _</P> <P> "Minimum.AREA, Maximum.AREA, StdDev.AREA, Variance.AREA", _</P> <P> pOutDatasetName)</P> <P> ' add the table to map</P> <P> Set pStandaloneTable = New StandaloneTable</P> <P> Set pStandaloneTable.Table = pSumTable</P> <P> Set pStandaloneTableColl = pMap</P> <P> pStandaloneTableColl.AddStandaloneTable pStandaloneTable</P> <P> ' Refresh the TOC</P> <P> pMxDocument.UpdateContents</P> <P> Exit Sub</P> <P>ErrorHandler:</P> <P> MsgBox Err.Number ; " " ; Err.Description</P> <P>End Sub</P> |
|
45楼#
发布于:2005-08-02 23:37
如何利用用户定义的规则创建定制的排序
<P>利用ITableSort接口可以完成普通的对记录排序的功能。ITableSortCallBack机制允许用户通过执行自定义的排序算法来完成定制的排序。本例演示了如何创建这样的用户类,通过实现ITableSortCallBack接口来完成该功能。</P> <P>假设有如下原始数据:其中“Address”字段描述了道路(Street)的道路编号(Street Number)如“2805”,和道路名(Stree Name)如“Citrus Ave”。</P> <br> <P>现在要按道路名排序所有的记录。因为排序字段时必须忽略道路编号,故需要自定排序规则。</P> <P>l 要点</P> <P>首先需要创建用户自定义的类,并生成其实例。该类实现了ITableSortCallBack接口。然后把它的引用赋给ITableSort的Compare属性。最后用ITableSort的Sort方法完成排序。</P> <P>l 程序说明</P> <P>过程UIBCustomSort_Click是实现模块,调用过程CustomSort实现功能。</P> <P>类模块clsTailSort为自定义模块,实现ITalbeSortCallBack接口。包括两个函数:ITableSortCallBack_Compare(用于定义字符串比较的规则)和Get_String(用于得到地址字段的道路名部分)。</P> <P>过程CustomSort中创建Tablesort和clsTailSort的实例,并对结果进行排序,然后调用过程CreateTable,将排序后的结果存入C:\temp目录的NewSortTable.dbf文件,并作为独立表加入当前Map。</P> <P>l 代码</P> <P> 类模块clsTailSort</P> <P>Option Explicit</P> <P>' Custom class for ITableSortCallBack</P> <P>' ClassName: clsTailSort</P> <P>Implements ItableSortCallBack</P> <P>Private Function ITableSortCallBack_Compare(ByVal value1 As Variant, ByVal value2 As_</P> <P>Variant,ByVal FieldIndex As Long, ByVal fieldSortIndex As Long) As Long</P> <P> ' Custom table sort</P> <P> ' Get_string function gets the first block of characters (e.g street numbers)</P> <P> ' in each value.</P> <P> ' Comparison is then made on the remaining characters (e.g. street names).</P> <P> On Error GoTo ErrorHandler</P> <P> value1 = Get_String(value1)</P> <P> value2 = Get_String(value2) </P> <P> If value1 > value2 Then</P> <P> ITableSortCallBack_Compare = 1</P> <P> ElseIf value1 < value2 Then</P> <P> ITableSortCallBack_Compare = -1</P> <P> Else: value1 = value2</P> <P> ITableSortCallBack_Compare = 0</P> <P> End If</P> <P> Exit Function</P> <P>ErrorHandler:</P> <P> MsgBox Err.Description</P> <P>End Function</P> <P>Private Function Get_String(ByVal sMyStr As Variant) As Variant</P> <P> ' This function gets the tail of the string</P> <P> ' after the first block of characters</P> <P> Dim sFindString As String</P> <P> Dim nPosition As Integer</P> <P> Dim nStringLen As Integer</P> <P> On Error GoTo ErrorHandler</P> <P> nStringLen = Len(sMyStr)</P> <P> nPosition = 1</P> <P> Do Until nPosition = nStringLen</P> <P> sFindString = Mid(sMyStr, nPosition, 1)</P> <P> If sFindString = " " Then</P> <P> Exit Do</P> <P> End If</P> <P> nPosition = nPosition + 1</P> <P> Loop</P> <P> Get_String = Mid(sMyStr, nPosition + 1)</P> <P> Exit Function</P> <P>ErrorHandler:</P> <P> MsgBox Err.Description</P> <P>End Function</P> <P>功能模块</P> <P>Option Explicit</P> <P>Private pMxDocument As IMxDocument</P> <P>Private pMap As IMap</P> <P>Private pApplication As IApplication</P> <P>Public Sub CustomSort()</P> <P> Dim pSelectedItem As IUnknown</P> <P> Dim pStandaloneTable As IStandaloneTable</P> <P> Dim pTable As ITable</P> <P> Dim pTableSort As ITableSort</P> <P> Dim pTableSortCallBack As ITableSortCallBack</P> <P> Dim pCursor As ICursor</P> <P> Dim pRow As IRow</P> <P> </P> <P> On Error GoTo ErrorHandler</P> <P> </P> <P> Set pMxDocument = ThisDocument</P> <P> Set pMap = pMxDocument.FocusMap</P> <P> Set pApplication = Application</P> <P> Set pSelectedItem = pMxDocument.SelectedItem</P> <P> </P> <P> If pSelectedItem Is Nothing Then</P> <P> MsgBox "Nothing selectd.", vbExclamation</P> <P> Exit Sub</P> <P> ' If a table is selected</P> <P> ElseIf Not TypeOf pSelectedItem Is IStandaloneTable Then</P> <P> MsgBox "No table selectd.", vbExclamation</P> <P> Exit Sub</P> <P> Else</P> <P> Set pStandaloneTable = New esriCore.StandaloneTable</P> <P> Set pStandaloneTable = pSelectedItem</P> <P> End If</P> <P> </P> <P> Set pTable = pStandaloneTable.Table</P> <P> </P> <P> ' Create a new custom TableSortCallBack and TableSort object</P> <P> ' Class clsTailSort defined in Class Modules</P> <P> Set pTableSortCallBack = New clsTailSort</P> <P> Set pTableSort = New TableSort</P> <P> </P> <P> ' Set up the parameters for the sort and excute</P> <P> With pTableSort</P> <P> .Fields = "Address"</P> <P> .Ascending("Address") = True</P> <P> .CaseSensitive("Address") = True</P> <P> Set .Table = pTable</P> <P> Set .Compare = pTableSortCallBack</P> <P> End With</P> <P> pTableSort.Sort Nothing</P> <P> </P> <P> ' Create a new cursor object to hold the sorted rows</P> <P> Set pCursor = pTableSort.Rows</P> <P> </P> <P> ' Create a new sorted table</P> <P> Call CreateTable(pTable, pCursor)</P> <P> </P> <P> Set pTableSortCallBack = Nothing</P> <P> Set pTableSort = Nothing</P> <P> </P> <P> Exit Sub</P> <P>ErrorHandler:</P> <P> MsgBox Err.Description</P> <P>End Sub</P> <P>Public Sub CreateTable(pTab As ITable, pCur As ICursor)</P> <P> ' Create a new .dbf file of the sorted data</P> <P> Dim pWorkspaceFactory As IWorkspaceFactory</P> <P> Dim pFeatureWorkspace As IFeatureWorkspace</P> <P> Dim pWorkspace As IWorkspace</P> <P> Dim pDatasetWkSp As IDataset</P> <P> Dim pWorkspaceName As IWorkspaceName</P> <P> Dim pDatasetNameOut As IDatasetName</P> <P> Dim pFields As IFields</P> <P> Dim pFields2 As esriCore.IFields</P> <P> Dim pDataset As IDataset</P> <P> Dim pDatasetName As IDatasetName</P> <P> Dim pDS As IDataset</P> <P> Dim pEnumDS As IEnumDataset</P> <P> </P> <P> Dim pStandaloneTable2 As IStandaloneTable</P> <P> Dim pTable2 As ITable</P> <P> Dim pTableNew As ITable</P> <P> Dim pCursor2 As ICursor</P> <P> Dim pRowBuffer As IRowBuffer</P> <P> Dim pRow As IRow</P> <P> Dim pName As IName</P> <P> Dim pStandaloneTable As IStandaloneTable</P> <P> Dim pStandaloneTableC As IStandaloneTableCollection</P> <P> </P> <P> Dim j As Integer</P> <P> Dim i As Integer</P> <P> </P> <P> On Error GoTo ErrorHandler</P> <P> </P> <P> ' Get the dataset name for the input table</P> <P> Set pDataset = pTab</P> <P> Set pDatasetName = pDataset.FullName</P> <P> </P> <P> ' Set the output dataset name.</P> <P> ' New .dbf file will be created in c:\temp</P> <P> Set pFields = pTab.Fields</P> <P> Set pWorkspaceFactory = New ShapefileWorkspaceFactory</P> <P> Set pWorkspace = pWorkspaceFactory.OpenFromFile("c:\temp", 0)</P> <P> Set pFeatureWorkspace = pWorkspace</P> <P> Set pDatasetWkSp = pWorkspace</P> <P> Set pWorkspaceName = pDatasetWkSp.FullName</P> <P> Set pDatasetNameOut = New TableName</P> <P> pDatasetNameOut.Name = "NewSortTable"</P> <P> Set pDatasetNameOut.WorkspaceName = pWorkspaceName</P> <P> </P> <P> ' Check if .dbf file already exist: if yes, delete it</P> <P> Set pEnumDS = pWorkspace.Datasets(esriDTTable)</P> <P> Set pDS = pEnumDS.Next</P> <P> Do Until pDS Is Nothing</P> <P> If pDS.Name = pDatasetNameOut.Name Then</P> <P> pDS.Delete</P> <P> Exit Do</P> <P> End If</P> <P> Set pDS = pEnumDS.Next</P> <P> Loop</P> <P> ' Create a new .dbf table</P> <P> pFeatureWorkspace.CreateTable pDatasetNameOut.Name, pFields, Nothing, Nothing, ""</P> <P> </P> <P> ' Create a new stand alone table object to represent the .dbf table</P> <P> Set pStandaloneTable2 = New StandaloneTable</P> <P> Set pStandaloneTable2.Table = pFeatureWorkspace.OpenTable(pDatasetNameOut.Name)</P> <P> Set pTable2 = pStandaloneTable2.Table</P> <P> Set pFields2 = pTable2.Fields</P> <P> </P> <P> ' Open an insert cursor on the new table</P> <P> Set pCursor2 = pTable2.Insert(True)</P> <P> </P> <P> ' Create a row buffer for the row inserts</P> <P> Set pRowBuffer = pTable2.CreateRowBuffer</P> <P> </P> <P> ' Loop through the sorted cursor and write to new table</P> <P> For j = 0 To pTab.RowCount(Nothing) - 1</P> <P> Set pRow = pCur.NextRow</P> <P> If Not pRow Is Nothing Then</P> <P> i = 1</P> <P> Do Until i = pFields2.FieldCount</P> <P> If Not IsEmpty(pRow.Value(i)) Then</P> <P> If pFields.Field(i).Editable Then</P> <P> pRowBuffer.Value(i) = pRow.Value(i)</P> <P> End If</P> <P> End If</P> <P> i = i + 1</P> <P> Loop</P> <P> pCursor2.InsertRow pRowBuffer</P> <P> End If</P> <P> Next j</P> <P> </P> <P> ' Add the new sorted table to map document</P> <P> Set pName = pDatasetNameOut</P> <P> Set pTableNew = pName.Open</P> <P> Set pStandaloneTable = New StandaloneTable</P> <P> Set pStandaloneTable.Table = pTableNew</P> <P> Set pStandaloneTableC = pMap</P> <P> pStandaloneTableC.AddStandaloneTable pStandaloneTable</P> <P> pMxDocument.UpdateContents </P> <P> Exit Sub</P> <P>ErrorHandler:</P> <P> MsgBox Err.Description</P> <P>End Sub</P> <p> |
|
46楼#
发布于:2005-08-02 23:38
<P>如何实现在ArcMap上进行属性查询(Identify)</P>
<P>本例要演示的是如何查询Feature的属性信息。实现后的结果为选择了UI Tool Control后,在要查询的Feature上单击鼠标,查询的结果将显示在弹出的窗体上。</P> <P>l 要点</P> <P>首先需要得到要查询的Feature对象。使用IIdentify接口的Identify方法可以对给定的位置进行查询,得到结果为IIdentifyObj对象的数组。然后通过为IIdentifyObj对象设置IFeatureIdentifyObj查询接口,即可进一步得到Feature对象。因为IFeatureIdentifyObj接口的Feature属性具有只写(write only)属性,故又用到另一个接口IRowIdentifyObj。</P> <P>得到Feature对象后即可操作其Fields属性和Value属性,得到其属性字段名和值。</P> <P>l 程序说明</P> <P>在窗体上使用了MSFlexGrid Control 6.0来显示查询结果。所以本例也演示了MSFlexGrid控件的使用方法。</P> <P>窗体名: frmResult</P> <P>MSFlexGrid控件名: flxAttr</P> <P>标签控件名: lblLocation (标签用来显示查询位置的地理坐标)</P> <P>l 代码</P> <P>Private Sub UIT_Identify_MouseDown(ByVal button As Long, ByVal shift As Long, _ ByVal x As Long, ByVal y As Long)</P> <P> Dim pMxApplication As IMxApplication</P> <P> Dim pMxDocument As IMxDocument</P> <P> Dim pMap As IMap</P> <P> Dim pPoint As IPoint</P> <P> Dim pIDArray As IArray</P> <P> Dim pIdentify As IIdentify</P> <P> Dim pFeatureIdentifyObj As IFeatureIdentifyObj</P> <P> Dim pIdentifyObj As IIdentifyObj</P> <P> Dim pRowIdentifyObj As IRowIdentifyObject</P> <P> Dim pFeature As IFeature</P> <P> Dim pFields As IFields</P> <P> Dim pField As IField</P> <P> Dim iFieldIndex As Integer</P> <P> Dim iLayerIndex As Integer</P> <P> Dim sShape As String</P> <P>On Error GoTo ErrorHandler</P> <P> Set pMxApplication = Application</P> <P> Set pMxDocument = Application.Document</P> <P> Set pMap = pMxDocument.FocusMap</P> <P> 'Identify from TOP layer to BOTTOM, exit loop since one Feature identified</P> <P> For iLayerIndex = 0 To pMap.LayerCount - 1</P> <P> Set pIdentify = pMap.Layer(iLayerIndex)</P> <P> 'Convert x and y to map units</P> <P> Set pPoint = pMxApplication.Display.DisplayTransformation.ToMapPoint(x, y)</P> <P> 'Set label on the form, coordinates would have 6 digits behind decimal point</P> <P> frmResult.lblLocation = "Location:(" ; Format(pPoint.x, "##0.000000") ; "," _ ; Format(pPoint.y, "##0.000000") ; ")" </P> <P> Set pIDArray = pIdentify.Identify(pPoint)</P> <P> 'Get the FeatureIdentifyObject</P> <P> If Not pIDArray Is Nothing Then</P> <P> Set pFeatureIdentifyObj = pIDArray.Element(0)</P> <P> Set pIdentifyObj = pFeatureIdentifyObj</P> <P> pIdentifyObj.Flash pMxApplication.Display</P> <P> 'Feature property of FeatureIdentifyObject has write only access</P> <P> Set pRowIdentifyObj = pFeatureIdentifyObj</P> <P> Set pFeature = pRowIdentifyObj.Row</P> <P> Set pFields = pFeature.Fields</P> <P> 'Set the MSFlexGrid control on form te display identify result</P> <P> With frmResult.flxAttr</P> <P> .AllowUserResizing = flexResizeColumns</P> <P> .ColAlignment(1) = AlignmentSettings.flexAlignLeftCenter</P> <P> .ColWidth(0) = 1500</P> <P> .ColWidth(1) = 1800</P> <P> 'Add header to MSFlexGrid control</P> <P> .Rows = pFields.FieldCount + 1</P> <P> .Cols = 2</P> <P> .FixedRows = 1</P> <P> .FixedCols = 0</P> <P> .TextMatrix(0, 0) = "Field"</P> <P> .TextMatrix(0, 1) = "Value"</P> <P> For iFieldIndex = 0 To pFields.FieldCount - 1</P> <P> Set pField = pFields.Field(iFieldIndex)</P> <P> 'Set field "Field" of the MSFlex control</P> <P> .TextMatrix(iFieldIndex + 1, 0) = pField.Name</P> <P> 'Set field "Value" of the MSFlex control</P> <P> Select Case pField.Type</P> <P> Case esriFieldTypeOID</P> <P> .TextMatrix(iFieldIndex + 1, 1) = pFeature.OID</P> <P> Case esriFieldTypeGeometry</P> <P> 'The function QueryShapeType return a String that</P> <P> ' correspond with the esriGeoemtryType const</P> <P> sShape = QueryShapeType(pField.GeometryDef.GeometryType) .TextMatrix(iFieldIndex + 1, 1) = sShape</P> <P> Case Else</P> <P> .TextMatrix(iFieldIndex + 1, 1) = pFeature.Value(iFieldIndex)</P> <P> End Select</P> <P> Next iFieldIndex</P> <P> End With </P> <P> frmResult.Show modal</P> <P> Exit Sub</P> <P> End If</P> <P> Next iLayerIndex</P> <P> 'If code goes here, no Feature was indentified, clear the MSFlex control's content</P> <P> ' and show a message</P> <P> frmResult.flxAttr.Clear</P> <P> MsgBox "No feature identified."</P> <P> Exit Sub</P> <P>ErrorHandler:</P> <P> MsgBox Err.Description</P> <P>End Sub</P> <P>Public Function QueryShapeType(ByVal enuGeometryType As esriGeometryType) As String</P> <P> Dim sShapeType As String </P> <P> Select Case enuGeometryType</P> <P> Case esriGeometryPolyline</P> <P> sShapeType = "Polyline"</P> <P> Case esriGeometryPolygon</P> <P> sShapeType = "Polygon"</P> <P> Case esriGeometryPoint</P> <P> sShapeType = "Point"</P> <P> Case esriGeometryMultipoint</P> <P> sShapeType = "Multipoint"</P> <P> Case esriGeometryNull</P> <P> sShapeType = "Unknown"</P> <P> Case esriGeometryLine</P> <P> sShapeType = "Line"</P> <P> Case esriGeometryCircularArc</P> <P> sShapeType = "CircularArc"</P> <P> Case esriGeometryEllipticArc</P> <P> sShapeType = "EllipticArc"</P> <P> Case esriGeometryBezier3Curve</P> <P> sShapeType = "BezierCurve"</P> <P> Case esriGeometryPath</P> <P> sShapeType = "Path"</P> <P> Case esriGeometryRing</P> <P> sShapeType = "Ring"</P> <P> Case esriGeometryEnvelope</P> <P> sShapeType = "Envelope"</P> <P> Case esriGeometryAny</P> <P> sShapeType = "Any valid geometry"</P> <P> Case esriGeometryBag</P> <P> sShapeType = "GeometryBag"</P> <P> Case esriGeometryMultiPatch</P> <P> sShapeType = "MultiPatch"</P> <P> Case esriGeometryTriangleStrip</P> <P> sShapeType = "TriangleStrip"</P> <P> Case esriGeometryTriangeFan</P> <P> sShapeType = "TriangleFan"</P> <P> Case esriGeometryRay</P> <P> sShapeType = "Ray"</P> <P> Case esriGeometrySphere</P> <P> sShapeType = "Sphere"</P> <P> Case Else</P> <P> sShapeType = "Unknown!"</P> <P> End Select</P> <P> QueryShapeType = sShapeType</P> <P>End Function</P> |
|
47楼#
发布于:2005-08-02 23:38
<P>如何设置和修改层的数据源</P>
<P>本例要实现的是如何改变(或设置)一个层的数据源(Data Source)。主要用到IMapAdmin2接口。</P> <P>l 要点</P> <P>首先需要得到新数据源的IFeatureClass接口对象和当前要改变数据源的层的当前IFeatureClass接口对象,然后调用IMapAdmin2接口的FireChangeFeatureClass方法实现之。</P> <P>l 程序说明</P> <P>过程UICMD_ChageDataSource_Click是实现模块,调用过程ChangeLayerDataSource实现功能。</P> <P>sNewFileName是层的新数据源的shape文件的完整文件名(包含)。</P> <P>l 代码</P> <P>Private Sub UICMD_ChageDataSource_Click()</P> <P> Dim pVBProject As VBProject</P> <P> Dim sProjectName As String</P> <P> Dim sNewFileName As String</P> <P>On Error GoTo ErrorHandler:</P> <P> Set pVBProject = ThisDocument.VBProject</P> <P> 'Get MXD File Path</P> <P> sProjectName = pVBProject.FileName</P> <P> 'Get Data File Path</P> <P> sNewFileName = sProjectName ; "\..\..\..\..\data\country.shp"</P> <P> 'Call Procedure </P> <P> ChangeLayerDataSource sNewFileName</P> <P> Exit Sub</P> <P>ErrorHandler:</P> <P> MsgBox Err.Description</P> <P>End Sub</P> <P>Private Sub ChangeLayerDataSource(ByVal sNewFileName As String)</P> <P> Dim pWorkspaceFactory As IWorkspaceFactory</P> <P> Dim pWorkspace As IWorkspace</P> <P> Dim pFeatureWorkspace As IFeatureWorkspace</P> <P> Dim pNewFeatureCls As IFeatureClass</P> <P> Dim pOldFeatureCls As IFeatureClass</P> <P> Dim pMxDocument As IMxDocument</P> <P> Dim pMap As IMap</P> <P> Dim pActiveView As IActiveView</P> <P> Dim pMapAdmin2 As IMapAdmin2</P> <P> Dim pFeatureLayer As IFeatureLayer</P> <P>On Error GoTo ErrorHandler</P> <P> 'Get Data FeatureClass</P> <P> Set pWorkspaceFactory = New ShapefileWorkspaceFactory</P> <P> Set pWorkspace = pWorkspaceFactory.OpenFromFile(sNewFileName ; "\..\", 0)</P> <P> Set pFeatureWorkspace = pWorkspace</P> <P> Set pNewFeatureCls = pFeatureWorkspace.OpenFeatureClass("country")</P> <P> 'Get Lay(0)'s FeatureClass</P> <P> Set pMxDocument = ThisDocument</P> <P> Set pMap = pMxDocument.FocusMap</P> <P> Set pMapAdmin2 = pMap</P> <P> Set pActiveView = pMap</P> <P> Set pFeatureLayer = pMap.Layer(0)</P> <P> Set pOldFeatureCls = pFeatureLayer.FeatureClass</P> <P> 'Change Data Source</P> <P> Set pFeatureLayer.FeatureClass = pNewFeatureCls</P> <P> pMapAdmin2.FireChangeFeatureClass pOldFeatureCls, pNewFeatureCls</P> <P> pActiveView.Refresh</P> <P> 'if want to change Display in Toc ,cancel these comment below</P> <P> 'pFeatureLayer.Name = pNewFeatureCls.AliasName</P> <P> 'pMxDocument.CurrentContentsView.Refresh 0 Exit Sub</P> <P>ErrorHandler:</P> <P> MsgBox Err.Description</P> <P>End Sub</P> |
|
48楼#
发布于:2005-08-02 23:39
如何实现在ArcMap中放大缩小地图
<P>用户点击按钮后,可以在地图上进行点击或者拖放矩形框来放大缩小地图</P> <P>l 要点</P> <P>因为考虑到用户可以单击放大缩小,也可以拖放矩形框来放大缩小,所以不可以直接使用IRubberBand接口,而是采用INewEnvelopeFeedback接口</P> <P>l 程序说明</P> <P>主要通过InewEnvelopeFeedback.StartPoint 和MoveTo方法来绘制矩形框,然后赋值给IActiveView.Extend属性,达到地图的放大缩小</P> <P>l 代码</P> <P> <P>Private m_pFeedbackEnv As INewEnvelopeFeedback<BR>Private m_pPoint As IPoint<BR>Private m_bIsMouseDown As Boolean<BR>Private m_pActiveView As IActiveView </P> <P>Private Sub UIToolControl1_MouseDown(ByVal button As Long, ByVal shift As Long, ByVal x As Long, _ByVal y As Long)<BR> Dim pMxDocument As IMxDocument<BR>On Error GoTo ErrorHandler:<BR> 'Left Button Check<BR> If button <> 1 Then Exit Sub<BR> If m_pActiveView Is Nothing Then<BR> Set pMxDocument = ThisDocument<BR> Set m_pActiveView = pMxDocument.ActivatedView<BR> End If<BR> '得到起始点<BR> Set m_pPoint = m_pActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(x, y)<BR> m_bIsMouseDown = True<BR> Exit Sub<BR>ErrorHandler:<BR> MsgBox Err.Description<BR>End Sub </P> <P>Private Sub UIToolControl1_MouseMove(ByVal button As Long, ByVal shift As Long, ByVal x As Long, _ByVal y As Long)<BR>On Error GoTo ErrorHandler:<BR> If Not m_bIsMouseDown Then Exit Sub<BR> If m_pFeedbackEnv Is Nothing Then<BR> Set m_pFeedbackEnv = New NewEnvelopeFeedback<BR> Set m_pFeedbackEnv.Display = m_pActiveView.ScreenDisplay<BR> m_pFeedbackEnv.Start m_pPoint<BR> End If<BR> Set m_pPoint = m_pActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(x, y)<BR> 'Draw Envelope<BR> m_pFeedbackEnv.MoveTo m_pPoint<BR> Exit Sub<BR>ErrorHandler:<BR> MsgBox Err.Description<BR>End Sub</P> <P>Private Sub UIToolControl1_MouseUp(ByVal button As Long, ByVal shift As Long, ByVal x As Long, _ByVal y As Long)<BR> Dim pEnv As IEnvelope<BR>On Error GoTo ErrorHandler:<BR> 'Left Button Check<BR> If button <> 1 Then Exit Sub<BR> If (m_pFeedbackEnv Is Nothing) Then<BR> 'User Only Click Map with left button<BR> Set pEnv = m_pActiveView.Extent<BR> '如果是缩小的话,将这里的两个0.5都改成1.5<BR> pEnv.Expand 0.5, 0.5, True<BR> Else<BR> 'User Draw a Envelope<BR> Set pEnv = m_pFeedbackEnv.Stop<BR> End If<BR> m_pActiveView.Extent = pEnv<BR> m_bIsMouseDown = False<BR> Set m_pPoint = Nothing<BR> Set m_pFeedbackEnv = Nothing<BR> m_pActiveView.Refresh<BR> Exit Sub<BR>ErrorHandler:<BR> MsgBox Err.Description<BR>End Sub</P> <br> |
|
49楼#
发布于:2005-08-07 17:25
vb环境下,利用AO组件开发Active.DLL。关键是要引用Arcobjects的对象库和实现arcobjects接口(如Icommand,Itool,Itoolbar等),请问如何实现接口?
|
|
|