127
ARCOBJECTS EXAMPLES ESRI 1

Arc Objects IMP Examples

  • Upload
    syed75

  • View
    33

  • Download
    7

Embed Size (px)

Citation preview

Page 1: Arc Objects IMP Examples

ARCOBJECTSEXAMPLESESRI

1

Page 2: Arc Objects IMP Examples

'************************************************************************************************' "Lock" layers at top and bottom of TOC'' This code prevents the user from re-ordering the ArcMap Table of Contents, effectively "locking"' the top and bottom layers in position.'' The user cannot drag and drop the top or bottom layers into another position, or drop another layer on top of' the first layer, or below the last layer. Any new layers added to the map will be placed after the top layer, or' before the bottom layer.'' The code could be modified to lock other layers, perhaps by name rather than position - see comments in the script.'' Run the StartEvents routine to start "listening" for changes in the TOC. You could run this routine automatically when' the MXD was opened if necessary.'' Run the StopEvents routine to allow changes to the TOC.'' History' Original coding 1st May 2008 - Stephen Lead'' Known limitations - using group layers may cause problems with this script.'' Please report any problems, questions or comments using the Contact Author option on ArcScripts''************************************************************************************************Option Explicit

Private WithEvents ActiveViewEvents As MapPrivate m_pMxDoc As IMxDocumentPrivate m_FirstLayerName As StringPrivate m_LastLayerName As String'Private m_OtherLockedLayerName as string

Public Sub StartEvents()

' Run this routine to start "listening" for changes. You can run this automatically when the MXD opened by calling this routine' in the MxDocument_OpenDocument section

Set m_pMxDoc = Application.DocumentSet ActiveViewEvents = m_pMxDoc.FocusMap

Dim pMap As IMapSet pMap = m_pMxDoc.FocusMapIf pMap.LayerCount = 0 Then Exit Sub

m_FirstLayerName = pMap.Layer(0).Namem_LastLayerName = pMap.Layer(pMap.LayerCount - 1).Name

2

Page 3: Arc Objects IMP Examples

'You could specify a layer by name rather than position'm_OtherLockedLayerName = "Specify the layer name here"

End SubPublic Sub StopEvents()

'Stop "listening" for changesSet ActiveViewEvents = Nothing

End Sub

Private Sub ActiveViewEvents_ItemAdded(ByVal Item As Variant) Call CheckLayersEnd Sub

Private Sub ActiveViewEvents_ItemReordered(ByVal Item As Variant, ByVal toIndex As Long) Call CheckLayersEnd Sub

Private Sub CheckLayers()

Dim pMap As IMapDim iNumLayers As IntegerDim pEnumLayer As IEnumLayerDim pLayer As ILayer

Set pMap = m_pMxDoc.FocusMapiNumLayers = pMap.LayerCountIf iNumLayers = 0 Then Exit Sub

'If the top layer is already correct, nothing further is required'If pMap.Layer(0).Name = m_FirstLayerName Then Exit Sub

'Comment out the above line and uncomment this code if you also want to check for the bottom layerIf pMap.Layer(0).Name = m_FirstLayerName Then If pMap.Layer(iNumLayers - 1).Name = m_LastLayerName Then Exit Sub End IfEnd If

'Otherwise, scroll through each layer til the desired layer is foundSet pEnumLayer = pMap.LayersSet pLayer = pEnumLayer.Next

Do Until pLayer Is Nothing If pLayer.Name = m_FirstLayerName Then 'Move it to the top of the TOC pMap.MoveLayer pLayer, 0 ElseIf pLayer.Name = m_LastLayerName Then 'Move it to the bottom of the TOC pMap.MoveLayer pLayer, iNumLayers - 1 'ElseIf pLayer.Name = mOtherLockedLayerName Then 'Move it to a particular position 'pmap.MoveLayer player, position_as_index 'specify the layer's position as an index starting from 0 End If Set pLayer = pEnumLayer.NextLoop

End Sub

Private Function MxDocument_BeforeCloseDocument() As Boolean

3

Page 4: Arc Objects IMP Examples

'stop listening for changes to the TOC Call StopEventsEnd Function

Private Function MxDocument_OpenDocument() As Boolean

' This code runs automatically when the MXD is openedMsgBox "The top layer and bottom layers in the TOC will be locked in place", vbInformationCall StartEvents

End Function

Add a Point to an SDE Layer.

Public Sub AddSDEPoint()

' Create connection string to connect to SQL Server Dim ConnectStr As String ConnectStr = "SERVER=MyServer;INSTANCE=esri_sde;VERSION=SDE.DEFAULT;USER=MyUser;PASSWORD=MyPassword" ' Open the SQL Server Workspace Factory Dim pWSF2 As IWorkspaceFactory2 Set pWSF2 = New SdeWorkspaceFactory Dim pWS As IWorkspace Set pWS = pWSF2.OpenFromString(ConnectStr, 0) ' Start Editing Dim pWSEdit As IWorkspaceEdit Set pWSEdit = pWS pWSEdit.StartEditing True pWSEdit.StartEditOperation ' Open the "Point" feature class Dim pFeatureWS As IFeatureWorkspace Set pFeatureWS = pWS Dim pFClass As IFeatureClass Set pFClass = pFeatureWS.OpenFeatureClass("sde.demo.POINT")

' Create new Feature Layer and Point. Then set point x and y Dim pFL As IFeatureLayer Set pFL = New FeatureLayer Set pFL.FeatureClass = pFClass Dim pFeat As IFeature Set pFeat = pFClass.CreateFeature Dim pPoint As IPoint Set pPoint = New esriCore.Point pPoint.X = -107.85 pPoint.Y = 43.23 Set pFeat.Shape = pPoint pFeat.Store ' Get and set the spatial reference of new layer and new point Dim pMxDoc As IMxDocument Set pMxDoc = ThisDocument Dim pMap As IMap Set pMap = pMxDoc.FocusMap Dim pBasicMap As IBasicMap Set pBasicMap = pMap Set pFL.SpatialReference = pBasicMap.SpatialReference

4

Page 5: Arc Objects IMP Examples

Set pPoint.SpatialReference = pBasicMap.SpatialReference ' Add new featurelayer as a layer to the map pFL.Name = "Point" pMap.AddLayer pFL ' Stop Editing pWSEdit.StopEditing True pWSEdit.StopEditOperation ' Refresh the mapview Dim pAV As IActiveView Set pAV = pMap pAV.Refresh

End Sub

ADD ARAEA OF POLYGON TO ATTRIBUTE TABLE

Public Sub AddAreaPolygon() ' ' This VBA script is to calculate the Area of polygons and add the area as new field ' in the attribute table of the polygon ' Guoyun Zhou, Kyushu University, Fukuoka, Japan ' [email protected] ' April,17, 2002

Dim pMxdoc As IMxDocument Set pMxdoc = ThisDocument If Not TypeOf pMxdoc.ActiveView Is IMap Then MsgBox "A Map must be active!" Exit Sub End If Dim pFLayer As IFeatureLayer Dim pFClass As IFeatureClass Set pFLayer = pMxdoc.SelectedLayer If pFLayer Is Nothing Then MsgBox "You have to Select a single polygon shapefile!" Exit Sub End If Set pFClass = pFLayer.FeatureClass If pFClass.ShapeType <> esriGeometryPolygon Then MsgBox "You must Select a single polygon shapefile!" Exit Sub End If Dim indexA As Long indexA = pFClass.FindField("Area") If indexA < 0 Then 'If there is no the field of AREA Dim pFieldx As IFieldEdit Set pFieldx = New Field With pFieldx .Type = esriFieldTypeDouble .Name = "Area" End With pFClass.AddField pFieldx

5

Page 6: Arc Objects IMP Examples

End If indexA = pFClass.FindField("Area") Dim pFCursor As IFeatureCursor ' Set pFCursor = pFClass.Search(Nothing, False) 'return all records

'Get a cursor that can be used to update features for all records in polygon feature Set pFCursor = pFClass.Update(Nothing, False) 'returns all records Dim pFeature As IFeature Set pFeature = pFCursor.NextFeature ' move to fist feature Dim pShape As IGeometry Dim parea As IArea Dim aarea As Double While Not pFeature Is Nothing Set pShape = pFeature.Shape Set parea = pShape aarea = parea.Area pFeature.Value(indexA) = aarea pFCursor.UpdateFeature pFeature ' pFeature.Store

Set pFeature = pFCursor.NextFeature Wend MsgBox "Ok! Finished ! Please chech your attribute table"

End Sub

SUMMRY:Adds and populates ACREAGE and/or AREA field to the attribute table of a dataset. Will properly calculate acreage for projected data, regardless of the linear units (meters, feet) used in that projection. Some other scripts I've seen DO NOT account for the projection and will give you wrong results.

Option Explicit

' NAME: frmAddAcreageDev' CREATOR: Pete Yurkosky' DATE: 5.26.2005

Private pMxDoc As IMxDocumentPrivate pMap As IMapPrivate pFLayer As IFeatureLayerPrivate pFClass As IFeatureClassPrivate pSpatialReference As ISpatialReferencePrivate pGeoDataset As IGeoDatasetPrivate pProjectedCoordinateSystem As IProjectedCoordinateSystemPrivate pLinearUnit As ILinearUnitPrivate MeterPerUnit As DoublePrivate Const SqMetersPerAcre As Double = 4046.8564244Private Const nameWidth As Integer = 17 ' For formatting of MessagePane

6

Page 7: Arc Objects IMP Examples

Private Response As IntegerPrivate canRun As BooleanPrivate lNumFeat As Long

Private Sub Image1_Click()

End Sub

Private Sub UserForm_Initialize()

' Set the default options on the form.optAcreage.Value = TrueoptNativeArea.Value = TruecmdGo.Enabled = TruecanRun = True

' A couple of initial settings.Set pMxDoc = ThisDocumentSet pMap = pMxDoc.FocusMapSet pFLayer = pMxDoc.SelectedLayerSet pGeoDataset = pFLayerDim pEditor As IEditorDim pId As New UID

' Check to see if we are editing. Unstable behavior when editing is turned on,' so disable procedure and show message.pId = "esriCore.Editor"Set pEditor = Application.FindExtensionByCLSID(pId)If pEditor.EditState = esriStateEditing Then 'MsgBox "It is editing." canRun = False cmdGo.Enabled = False With MessagePane .Font = "Arial" .Caption = "ERROR: Procedure cannot operate during edit session." .ForeColor = RGB(255, 0, 0) .Font.Bold = True .Font.Italic = False End With ' Check possible conditions in which we opened without a FocusMapElseIf pMap Is Nothing Then canRun = False cmdGo.Enabled = False With MessagePane .Font = "Arial" .Caption = "ERROR: You must have an active map." .ForeColor = RGB(255, 0, 0) .Font.Bold = True .Font.Italic = False End With

' Check to see that there is a layer selected.ElseIf pFLayer Is Nothing Then canRun = False cmdGo.Enabled = False With MessagePane .Font = "Arial" .Caption = "ERROR: You must select a map layer." .ForeColor = RGB(255, 0, 0)

7

Page 8: Arc Objects IMP Examples

.Font.Bold = True .Font.Italic = False End WithElse ' Check to see that the selected layer is of polygon type, and check the ' spatial reference. Set pFClass = pFLayer.FeatureClass Set pSpatialReference = pGeoDataset.SpatialReference If pFClass.ShapeType <> esriGeometryPolygon Then canRun = False cmdGo.Enabled = False With MessagePane .Font = "Arial" .Caption = "ERROR: You must select a POLYGON map layer." .ForeColor = RGB(255, 0, 0) .Font.Bold = True .Font.Italic = False End With ' Check to see that the layer is projected. If not, we will get a calculation ' of area in "decimal degrees squared" which nobody wants. ElseIf Not TypeOf pSpatialReference Is IProjectedCoordinateSystem Then canRun = False cmdGo.Enabled = False With MessagePane .Font = "Arial" .Caption = "ERROR: You must select a PROJECTED map layer." .ForeColor = RGB(255, 0, 0) .Font.Bold = True .Font.Italic = False End With End IfEnd If

' All is normal? Then set up the units, display them. This could be part of the' above conditional, as the final "Else", but that needs to be reserved for the' initialization of the pFClass. I can do it there, having established that it' exists, but then the checks look like "If object.subobject.subobject.subobject..."' I'll keep this final conditional to keep things readable.If canRun Then Set pProjectedCoordinateSystem = pSpatialReference Set pLinearUnit = pProjectedCoordinateSystem.CoordinateUnit MeterPerUnit = pLinearUnit.MetersPerUnit Dim pUnitName As String pUnitName = pLinearUnit.name lNumFeat = pFClass.FeatureCount(Nothing) With MessagePane ' If length of pFLayer.Name > 17, truncate to 17. Otherwise leave alone. .Caption = "Layer: " + IIf(Len(pFLayer.name) > nameWidth, (Mid(pFLayer.name, 1, nameWidth) + "..."), pFLayer.name) + vbCrLf + _ "Polys: " + LTrim(Str(lNumFeat)) + vbCrLf + _ "Units: " + "square " + pUnitName .ForeColor = RGB(0, 0, 255) .Font.Bold = False .Font.Italic = False End WithEnd If

End Sub

Private Sub optAcreage_Click()If (optAcreage.Value = False And optNativeArea.Value = False) Or Not canRun Then cmdGo.Enabled = False

8

Page 9: Arc Objects IMP Examples

Else cmdGo.Enabled = TrueEnd IfEnd Sub

Private Sub optNativeArea_Click()If (optNativeArea.Value = False And optAcreage.Value = False) Or Not canRun Then cmdGo.Enabled = FalseElse cmdGo.Enabled = TrueEnd IfEnd Sub

Private Sub cmdGO_Click()' We are sure the app is not in an edit mode, and that at least one option is' checked. Ready to execute the main procedure.

' Clear the dialog box.frmAddAcreageDev.HideCalc_Values pFClassUnload frmAddAcreageDev

Set pMxDoc = NothingSet pMap = NothingSet pFLayer = NothingSet pFClass = NothingSet pSpatialReference = NothingSet pGeoDataset = NothingSet pProjectedCoordinateSystem = NothingSet pLinearUnit = Nothing

End Sub

Private Sub Calc_Values(pFClass As IFeatureClass)' Test procedure. Lumping both AREA, ACREAGE procs into one, doing conditionals' within the main cursor loop. Is it faster than opening two cursors each time' we do this on both AREA and ACREAGE?

Dim indexArea As LongindexArea = pFClass.FindField("AREA")Dim indexAcre As LongindexAcre = pFClass.FindField("ACREAGE")

' Are we doing AREA? If so, check for existing field. Create one if necessary.If optNativeArea.Value And indexArea < 0 Then Dim pFieldArea As IFieldEdit Set pFieldArea = New Field With pFieldArea .Type = esriFieldTypeDouble .name = "AREA" End With pFClass.AddField pFieldArea indexArea = pFClass.FindField("AREA")End If

' Are we doing ACREAGE? If so, check for existing field. Create one if necessary.If optAcreage.Value And indexAcre < 0 Then Dim pFieldAcre As IFieldEdit Set pFieldAcre = New Field With pFieldAcre .Type = esriFieldTypeDouble .name = "ACREAGE"

9

Page 10: Arc Objects IMP Examples

End With pFClass.AddField pFieldAcre indexAcre = pFClass.FindField("ACREAGE")End If

' Set up a cursor to hold all features of the current FeatureClass.Dim pFCursor As IFeatureCursorSet pFCursor = pFClass.Update(Nothing, False)Dim pFeature As IFeatureSet pFeature = pFCursor.NextFeatureDim pShape As IGeometryDim pArea As IAreaDim AreaValue As DoubleDim Acreage As Double

Dim pSBar As IStatusBarDim i As LongSet pSBar = Application.StatusBar

' Go through all features, calculate the area/acreage, update the field.' Area is defined by the linear units (meters, feet) of the feature class's' projection. If UTM then meters, etc.For i = 1 To lNumFeat pSBar.Message(esriStatusMain) = "Add acreage: Updating record " & i & " of " & lNumFeat & "..." Set pShape = pFeature.Shape Set pArea = pShape AreaValue = pArea.Area ' Get the absolute value, in case we have negative areas resulting from ' counterclockwise polygon parameterization (for example, if somebody ' digitized or GPS'd a polygon counterclockwise). AreaValue = Abs(AreaValue) If optNativeArea.Value Then pFeature.Value(indexArea) = AreaValue End If If optAcreage.Value Then pFeature.Value(indexAcre) = ((Sqr(AreaValue) * MeterPerUnit) ^ 2) / SqMetersPerAcre End If pFCursor.UpdateFeature pFeature Set pFeature = pFCursor.NextFeatureNext

pSBar.Message(esriStatusMain) = "Add acreage: Finished updating records. Check the attribute table."

End Sub

' Name: AddGraphicsCoords' Creator: Pete Yurkosky' Date: 1/14/2005' Description: Given a selection of point graphics, will create and display' a callout box with the x,y coordinates of the point.' Issues: Currently works only with graphics points. Function' GetCalloutOnPoint, however, takes an IPoint parameter and' could be used with an actual feature, in a similar way.

Private pMxDocument As IMxDocumentPrivate pFillSymbol As IFillSymbolPrivate pRgbColor As IRgbColorPrivate pCallout As ILineCalloutPrivate pTextSymbol As IFormattedTextSymbolPrivate CalloutLocation As IPointPrivate IsDecimalDegrees As BooleanPrivate xOffset, yOffset As Double

10

Page 11: Arc Objects IMP Examples

Sub AddGraphicsCoords()

Dim pActiveView As IActiveViewDim pGraphicsContainer As IGraphicsContainerDim pGraphicsContainerSelect As IGraphicsContainerSelectDim pPoint As IPointDim pPtElement As IElementDim pCalloutElement As IElementDim pEnumElement As IEnumElement

Set pMxDocument = ThisDocument

' There should be a selection of points. Check.Set pActiveView = pMxDocument.ActivatedViewSet pGraphicsContainerSelect = pActiveViewSet pGraphicsContainer = pActiveViewIf pGraphicsContainerSelect.ElementSelectionCount < 1 Then MsgBox "You must select some point graphics to label." Exit SubEnd If

' --------------------------------------------------------------' Now we can set some default parameters for ALL callout boxes,' whether feature or graphic-based.' --------------------------------------------------------------

Set pRgbColor = New RgbColor With pRgbColor .Red = 255 .Green = 255 .Blue = 255 End With

' Remember: an IFormattedTextSymbol is an interface on a TextSymbol.' A TextSymbol contains one TextBackground. A LineCallout is a type of' Callout, which is a type of TextBackground. Each LineCallout has' a Border property, which is a SimpleFillSymbolSet pFillSymbol = New SimpleFillSymbolpFillSymbol.Color = pRgbColorSet pCallout = New LineCalloutSet pCallout.AccentBar = NothingSet pCallout.Border = pFillSymbolpCallout.Gap = 0Set pTextSymbol = New TextSymbolSet pTextSymbol.Background = pCallout

' Use this boolean later to set coordinate text formattingIf pMxDocument.FocusMap.MapUnits = esriDecimalDegrees Then IsDecimalDegrees = TrueElse IsDecimalDegrees = FalseEnd If

' Set these so that the callouts don't appear right over the pointxOffset = pMxDocument.ActiveView.Extent.Width / 8yOffset = pMxDocument.ActiveView.Extent.Width / 20

' Use an enumeration of all the selected points.Set pEnumElement = pGraphicsContainerSelect.SelectedElementspEnumElement.ResetSet pPtElement = pEnumElement.Next

11

Page 12: Arc Objects IMP Examples

' Loop through each selected element.While Not pPtElement Is Nothing If TypeOf pPtElement Is IMarkerElement Then Set pPoint = pPtElement.Geometry Set pCalloutElement = GetCalloutOnPoint(pPoint) ' Can't call AddElement on an empty Geometry pGraphicsContainer.AddElement pCalloutElement, 0 pCalloutElement.Activate pActiveView.ScreenDisplay pActiveView.PartialRefresh esriViewGraphics, pCalloutElement, Nothing Set pPtElement = pEnumElement.Next Else MsgBox "Selection must consist only of points!" Exit Sub End IfWend

Set pFillSymbol = NothingSet pRgbColor = NothingSet pCallout = NothingSet pTextSymbol = NothingSet CalloutLocation = Nothing

End Sub

Private Function GetCalloutOnPoint(param_Pt As IPoint) As IElement' Use point's coordinates to create a new callout.' Return this as an element, and let calling proc. handle display.

Dim xCoord As Double, xCoordText As StringDim yCoord As Double, yCoordText As String

Dim pTextElement As ITextElement, outElement As IElement

param_Pt.QueryCoords xCoord, yCoordIf IsDecimalDegrees Then xCoordText = FormatNumber(xCoord, 5, vbUseDefault, vbUseDefault, vbFalse) yCoordText = FormatNumber(yCoord, 5, vbUseDefault, vbUseDefault, vbFalse)Else xCoordText = FormatNumber(xCoord, 2, vbUseDefault, vbUseDefault, vbFalse) yCoordText = FormatNumber(yCoord, 2, vbUseDefault, vbUseDefault, vbFalse)End If

' Use this code to set the offset for the callout boxSet CalloutLocation = New PointCalloutLocation.PutCoords xCoord - xOffset, yCoord + yOffsetpCallout.AnchorPoint = param_Pt

Set pTextElement = New TextElementSet outElement = pTextElementoutElement.Geometry = CalloutLocationpTextElement.Text = xCoordText & vbCrLf & yCoordTextpTextElement.Symbol = pTextSymbolSet GetCalloutOnPoint = outElement

End Function

Add Elevations to a line or contour shapefile

Attribute VB_Name = "ContourElevation_SK"Option Explicit

12

Page 13: Arc Objects IMP Examples

Sub ContourElev_SK() 'This macro was compiled by Sudarshan Karki 'with ideas borrowed from many other scripts 'in the ESRI site. ([email protected]) 'Set an error handler method On Error GoTo ErrorHandler 'Declare variables Dim pMxDocument As IMxDocument Dim pFeatureLayer As IFeatureLayer Dim pFeatureClass As IFeatureClass 'Set variables Set pMxDocument = ThisDocument Set pFeatureLayer = pMxDocument.SelectedLayer Set pFeatureClass = pFeatureLayer.FeatureClass

'Check if any layer is selected or not If pFeatureLayer Is Nothing Then MsgBox "Please select a layer", vbInformation, "Layer not selected" GoTo ErrorHandler End If 'Declare variables for field name and type Dim SK As Long SK = pFeatureClass.FindField("Elev") If SK < 0 Then Dim TempField As IFieldEdit Set TempField = New Field With TempField .Type = esriFieldTypeDouble .Name = "Elev" End With pFeatureClass.AddField TempField End If SK = pFeatureClass.FindField("Elev") 'Define variable to position cursor Dim pFeatureCursor As IFeatureCursor Set pFeatureCursor = pFeatureClass.Search(Nothing, False) Dim pFeature As IFeature Set pFeature = pFeatureCursor.NextFeature 'Check if the required geometry type is selected Dim pIZAware As IZAware Set pIZAware = pFeature.Shape If pFeatureClass.ShapeType <> esriGeometryPolyline Then If Not pIZAware.ZAware Then MsgBox "Please select a Polyline shapefile with Z values", vbExclamation, "Required PointZ" GoTo ErrorHandler End If End If 'Define variables for progress bar Dim lNumberofFeatures As Long Dim dInterval As Double Dim pStatusBar As IStatusBar Set pStatusBar = StatusBar Dim pStepProgressor As IStepProgressor

13

Page 14: Arc Objects IMP Examples

Set pStepProgressor = pStatusBar.ProgressBar lNumberofFeatures = pFeatureClass.FeatureCount(Nothing) dInterval = lNumberofFeatures / 100 Static i i = 1 pStepProgressor.MinRange = 1 pStepProgressor.MaxRange = lNumberofFeatures pStepProgressor.StepValue = dInterval

'Define variables to extract and store line attributes Dim pGeometry As IGeometry Dim pPolyline As IPolyline Dim Output As Double 'Loop through the table to compute values 'until the cursor reaches the end While Not pFeature Is Nothing 'Compute field values Set pGeometry = pFeature.Shape Set pPolyline = pGeometry Output = pPolyline.FromPoint.Z pFeature.Value(SK) = Output pFeature.Store 'Show status bar and message on the status bar pStepProgressor.Position = i pStepProgressor.Message = "Please be patient...calculating " & Str(i) & " of " & Str(lNumberofFeatures) pStepProgressor.Step pStepProgressor.Show If i < lNumberofFeatures Then DoEvents Else pStepProgressor.Hide End If 'Advance the cursor to the next row Set pFeature = pFeatureCursor.NextFeature i = i + 1 Wend

pStepProgressor.Hide

'Error handlerErrorHandler: Exit Sub

End Sub

Add map elements (north arrow and legend)

Description

This sample adds a north arrow and a legend to the Layout View. North arrows and legends are types of map elements. Map elements are objects that are related to a map.In this sample, you will be running a macro created in the Visual Basic Editor.

How to use

1. Start ArcMap.

14

Page 15: Arc Objects IMP Examples

2. Open an existing map document (.mxd) or add layers to an empty (Untitled) map document. 3. Click Tools, point to Macros, then click Visual Basic Editor. This opens the Visual Basic Editor. 4. Click to expand the Project (<YourProject>.mxd) in the Project Explorer. 5. Right-click Project (<YourProject>.mxd), point to Insert, then click Module. A new module (Module1, and possibly Module folder) is added to the Project folder, and the Module1 (Code) window is opened. 6. Copy and paste the following code into the Module1 (Code) window:

Public Sub AddMapSurrounds()

Dim pMxDoc As IMxDocument Dim pActiveView As IActiveView Dim pEnv As IEnvelope Dim pID As New UID Dim pMapSurround As IMapSurround Dim pMarkerNorthArrow As IMarkerNorthArrow Dim pCharacterMarkerSymbol As ICharacterMarkerSymbol

Set pMxDoc = Application.Document Set pActiveView = pMxDoc.PageLayout Set pEnv = New Envelope

'Add a north arrow pEnv.PutCoords 0.2, 0.2, 1, 1 pID.Value = "esriCore.MarkerNorthArrow" Set pMapSurround = CreateSurround(pID, pEnv, "North Arrow", pMxDoc.FocusMap, pMxDoc.PageLayout) 'Change out the default north arrow Set pMarkerNorthArrow = pMapSurround 'QI Set pCharacterMarkerSymbol = pMarkerNorthArrow.MarkerSymbol 'clones the symbol pCharacterMarkerSymbol.CharacterIndex = 200 'change the symbol pMarkerNorthArrow.MarkerSymbol = pCharacterMarkerSymbol 'set it back

'Add a legend 'In this case just use the default legend pEnv.PutCoords 7.5, 0.2, 8.5, 4 pID.Value = "esriCore.Legend" Set pMapSurround = CreateSurround(pID, pEnv, "Legend", pMxDoc.FocusMap, pMxDoc.PageLayout)

'Refresh the graphics pActiveView.PartialRefresh esriViewGraphics, Nothing, Nothing End Sub

Private Function CreateSurround(pID As UID, pEnv As IEnvelope, strName As String, _ pMap As IMap, pPageLayout As IPageLayout) As IMapSurround

Dim pGraphicsContainer As IGraphicsContainer Dim pActiveView As IActiveView Dim pMapSurroundFrame As IMapSurroundFrame Dim pMapSurround As IMapSurround Dim pMapFrame As IMapFrame Dim pElement As IElement

'MapSurrounds are held in a MapSurroundFrame 'MapSurroundFrames are related to MapFrames 'MapFrames hold Maps

15

Page 16: Arc Objects IMP Examples

Set pGraphicsContainer = pPageLayout Set pMapFrame = pGraphicsContainer.FindFrame(pMap) Set pMapSurroundFrame = pMapFrame.CreateSurroundFrame(pID, Nothing) pMapSurroundFrame.MapSurround.Name = strName

'Set the geometry of the MapSurroundFrame to give it a location 'Activate it and add it to the PageLayout's graphics container Set pElement = pMapSurroundFrame Set pActiveView = pPageLayout pElement.Geometry = pEnv pElement.Activate pActiveView.ScreenDisplay pGraphicsContainer.AddElement pElement, 0

Set CreateSurround = pMapSurroundFrame.MapSurround End Function

7. Minimize or close the Visual Basic Editor. 8. Switch to Layout View. 9. In ArcMap, click Tools, point to Macros, then click Macros. 10. On the Macros dialog box, click the Macros in drop-down arrow and click Project. 11. In the list below the Macro name text box, click Module1.AddMapSurrounds. 12. Click Run.

Tip

* Make sure the code in Visual Basic appears as it does in the above steps. For example, you may have to add carriage returns.

Private Sub CommandButton5_Click()

16

Page 17: Arc Objects IMP Examples

Dim pMxdoc As IMxDocument Dim pMap As IMap Set pMxdoc = ThisDocument 'Get the first map in the document Set pMap = pMxdoc.FocusMap If pMap.LayerCount = 0 Then MsgBox "Please add the shapefile first before add new the field name" MsgBox "You can get this form in Visual Basic Editor and call this form again after added the map in ArcGIS" Unload Me Exit Sub End If If TextBox1.Text = "" Then MsgBox "Please Input the new field name you want to added" Exit Sub End If 'Get the first layer in the map Dim pFeatureLayer As IFeatureLayer Set pFeatureLayer = pMap.Layer(0) Dim pFieldstable As ITableFields Dim c As Integer Set pFieldstable = pFeatureLayer For e = 0 To pFieldstable.FieldCount - 1 'visible all field pFieldstable.FieldInfo(e).Visible = False Next e Call Test 'Get the feature class for the first layer Dim pFeatureClass As IFeatureClass Set pFeatureClass = pFeatureLayer.FeatureClass 'create new field object Dim pFieldEdit As IFieldEdit Set pFieldEdit = New Field Dim pFields As IFields Set pFields = pFeatureClass.Fields For i = 0 To pFields.FieldCount - 1 If pFields.Field(i).name = UCase(TextBox1.Text) Then For c = 0 To pFieldstable.FieldCount - 1 If pFieldstable.Field(c).name = UCase(TextBox1.Text) Then pFieldstable.FieldInfo(c).Visible = True Call Test pMxdoc.CurrentContentsView.ContextItem = pFeatureLayer ThisDocument.CommandBars.Find(ArcID.Layer_Table).Execute UserForm2.Hide pMxdoc.UpdateContents pMxdoc.ActiveView.Refresh If MsgBox("Did you want delete this field?", vbQuestion + vbYesNo, "Delete") = vbYes Then DeleteField UCase(TextBox1.Text) Else CloseWindows UserForm2.Show Exit Sub End If Exit For End If Next c Exit For End If Next Set pFieldstable = pFeatureLayer For h = 0 To pFieldstable.FieldCount - 1 'visible all field

17

Page 18: Arc Objects IMP Examples

pFieldstable.FieldInfo(h).Visible = True Next h Set pFields = pFeatureClass.Fields 'create new calculator object Dim pCalc As ICalculator Set pCalc = New Calculator Dim pCursor As ICursor If ComboBox1.Text = "Short Integer" Then 'create properties of new field With pFieldEdit .name = UCase(TextBox1.Text) .Type = 0 .Precision = TextBox3.Text End With 'add new field pFeatureClass.AddField pFieldEdit ElseIf ComboBox1.Text = "Long Integer" Then 'create properties of new field With pFieldEdit .name = UCase(TextBox1.Text) .Type = 1 .Precision = TextBox3.Text End With 'add new field pFeatureClass.AddField pFieldEdit ElseIf ComboBox1.Text = "Float" Then 'create properties of new field With pFieldEdit .name = UCase(TextBox1.Text) .Type = 2 .Precision = TextBox3.Text .Scale = TextBox4.Text End With 'add new field pFeatureClass.AddField pFieldEdit ElseIf ComboBox1.Text = "Double" Then 'create properties of new field With pFieldEdit .name = UCase(TextBox1.Text) .Type = 3 .Precision = TextBox3.Text .Scale = TextBox4.Text End With 'add new field pFeatureClass.AddField pFieldEdit ElseIf ComboBox1.Text = "Text" Then 'create properties of new field With pFieldEdit .name = UCase(TextBox1.Text) .Type = 4 .Length = TextBox2.Text End With 'add new field pFeatureClass.AddField pFieldEdit 'calculation script to be performed on new field Set pCursor = pFeatureClass.Update(Nothing, True) Set pCalc.Cursor = pCursor With pCalc .Expression = """" & TextBox5.Text & """" .Field = UCase(TextBox1.Text) End With

18

Page 19: Arc Objects IMP Examples

'perform field calculation pCalc.ShowErrorPrompt = True pCalc.Calculate ElseIf ComboBox1.Text = "Date" Then 'create properties of new field With pFieldEdit .name = UCase(TextBox1.Text) .Type = 5 End With 'add new field pFeatureClass.AddField pFieldEditEnd If 'update the attribute table of layer in TOC Call Test MsgBox "Add Field Successfuly" For g = 0 To pFieldstable.FieldCount - 1 'visible all field pFieldstable.FieldInfo(g).Visible = True Next g CloseWindows pMxdoc.UpdateContents pMxdoc.ActiveView.Refresh Set pMxdoc = Nothing Set pFeatureClass = Nothing Set pFieldEdit = Nothing Set pFields = Nothing Set pMap = Nothing Set pFeatureLayer = Nothing Set pFieldEdit = Nothing Set pField = Nothing Set pCalc = Nothing Set pFieldstable = Nothing Set pCursor = Nothing Unload MeEnd SubPrivate Sub CloseWindows()

Dim pAppWindows As IApplicationWindows Set pAppWindows = Application Dim pWindowSet As ISet Set pWindowSet = pAppWindows.DataWindows Dim pDataWindow As IDataWindow Dim pTableWindow As ITableWindow pWindowSet.Reset Set pDataWindow = pWindowSet.Next While Not pDataWindow Is Nothing If (TypeOf pDataWindow Is ITableWindow) Then Set pTableWindow = pDataWindow pTableWindow.Show (False) End If Set pDataWindow = pWindowSet.Next Wend Set pAppWindows = Nothing

19

Page 20: Arc Objects IMP Examples

Set pWindowSet = Nothing Set pTableWindow = Nothing Set pDataWindow = NothingEnd SubPrivate Sub DeleteField(Fieldname As String) Dim pMxdoc As IMxDocument Dim pFeatureLayer As IFeatureLayer Dim pFeatureClass As IFeatureClass Dim pFieldEdit As IFieldEdit Dim pFields As IFields Dim pField1 As IField Set pMxdoc = ThisDocument Set pFeatureLayer = pMxdoc.FocusMap.Layer(0) Set pFeatureClass = pFeatureLayer.FeatureClass Set pFieldEdit = New Field Set pFields = pFeatureClass.Fields Set pField1 = pFields.Field(pFields.FindField(Fieldname)) pFeatureLayer.FeatureClass.DeleteField pField1End Sub

Sub Test() Dim pDWindows As IApplicationWindows Set pDWindows = Application Dim pWinSet As ISet Set pWinSet = pDWindows.DataWindows pWinSet.Reset Dim pDWin As IDataWindow Set pDWin = pWinSet.Next Do Until pDWin Is Nothing If TypeOf pDWin Is ITableWindow Then Dim pTWin As ITableWindow Set pTWin = pDWin pTWin.TableControl.RemoveAndReloadCache' also tried pTWin.Refresh without success' also tried pTWin.TableControl.Redraw without success End If Set pDWin = pWinSet.Next Loop Set pWinSet = Nothing Set pDWin = Nothing Set pTWin = Nothing Set pDWindows = NothingEnd SubPrivate Sub ComboBox1_Click()If ComboBox1.Text = "Short Integer" ThenTextBox2.Visible = FalseTextBox3.Visible = TrueTextBox4.Visible = FalseLabel1.Visible = FalseLabel2.Visible = TrueLabel3.Visible = FalseElseIf ComboBox1.Text = "Long Integer" ThenTextBox2.Visible = FalseTextBox3.Visible = TrueTextBox4.Visible = FalseLabel1.Visible = FalseLabel2.Visible = TrueLabel3.Visible = FalseElseIf ComboBox1.Text = "Float" Then

20

Page 21: Arc Objects IMP Examples

TextBox2.Visible = FalseTextBox3.Visible = TrueTextBox4.Visible = TrueLabel1.Visible = FalseLabel2.Visible = TrueLabel3.Visible = TrueElseIf ComboBox1.Text = "Double" ThenTextBox2.Visible = FalseTextBox3.Visible = TrueTextBox4.Visible = TrueLabel1.Visible = FalseLabel2.Visible = TrueLabel3.Visible = TrueElseIf ComboBox1.Text = "Text" ThenTextBox2.Visible = TrueTextBox3.Visible = FalseTextBox4.Visible = FalseLabel1.Visible = TrueLabel2.Visible = FalseLabel3.Visible = FalseElseIf ComboBox1.Text = "Date" ThenTextBox2.Visible = FalseTextBox3.Visible = FalseTextBox4.Visible = FalseLabel1.Visible = FalseLabel2.Visible = FalseLabel3.Visible = FalseEnd If

End Sub

Private Sub CommandButton6_Click() MsgBox "You can get this form in Visual Basic Editor and call this form again after added the map in ArcGIS" Unload MeEnd Sub

Public Sub Driver() Dim pMxdoc As IMxDocument Dim pMap As IMap Set pMxdoc = ThisDocument 'Get the first map in the document Set pMap = pMxdoc.FocusMap If pMap.LayerCount = 0 Then MsgBox "Please add the shapefile first" Unload Me Exit Sub End If 'Get the first layer in the map Dim pFeatureLayer As IFeatureLayer Set pFeatureLayer = pMap.Layer(0) Dim LayerName As String 'Dummy subroutine to call SetCurrentLayer Dim pApp As IApplication Dim m_pEditor As IEditor Dim SubType As Long Dim pID As New UID pID = "esriEditor.Editor" Set pApp = Application

21

Page 22: Arc Objects IMP Examples

Set m_pEditor = pApp.FindExtensionByCLSID(pID) LayerName = pFeatureLayer.name SubType = 0 'SetCurrentLayer LayerName, SubType 'Subroutine to set the current layer based on a name and subtype index Dim pEditLayers As IEditLayers

Dim Count As Integer Set pEditLayers = m_pEditor Set pMap = pMxdoc.FocusMap 'Loop through all of the maps layers to find the desired one For Count = 0 To pMap.LayerCount - 1 If pMap.Layer(Count).name = LayerName Then 'Make sure the layer is editable If pEditLayers.IsEditable(pMap.Layer(Count)) Then Set pFeatureLayer = pMap.Layer(Count) pEditLayers.SetCurrentLayer pFeatureLayer, SubType Exit Sub Else MsgBox "This layer is not editable" Exit Sub End If End If Next Count End Sub

Private Sub UserForm_Initialize()ComboBox1.AddItem "Short Integer"ComboBox1.AddItem "Long Integer"ComboBox1.AddItem "Float"ComboBox1.AddItem "Double"ComboBox1.AddItem "Text"ComboBox1.AddItem "Date"If ComboBox1.ListCount > 0 Then ComboBox1.ListIndex = 0CloseWindowsEnd Sub

Add Node to mid point of two node polyline

Private Sub AddNode2Polyline()

'For NFCDD upload'For lines with only two nodes it will add a new node at the centroid of that line

Dim pMxDoc As IMxDocumentDim pMap As IMapSet pMxDoc = ThisDocumentSet pMap = pMxDoc.FocusMapDim pFLayer As IFeatureLayerSet pFLayer = pMxDoc.CurrentContentsView.SelectedItemDim pFC As IFeatureCursorDim pFeature As IFeatureDim pPointCollection As IPointCollectionDim pFeatureSelection As IFeatureSelectionSet pFeatureSelection = pFLayer

22

Page 23: Arc Objects IMP Examples

Dim ShapeCounter As IntegerpFeatureSelection.Clear

If pFLayer.FeatureClass.ShapeType = esriGeometryPolyline Then

Set pFC = pFLayer.Search(Nothing, False)Set pFeature = pFC.NextFeatureSet pPointCollection = pFeature.Shape

Do Until pFeature Is Nothing

Set pPointCollection = pFeature.ShapeIf pPointCollection.PointCount <= 2 Then

Dim pPointA As IPoint Set pPointA = New Point Dim pPointB As IPoint Set pPointB = New Point Dim pPointC As IPoint Set pPointC = New Point Set pPointA = pPointCollection.Point(0) Set pPointB = pPointCollection.Point(1) If pPointA.X > pPointB.X Then X = pPointB.X + ((pPointA.X - pPointB.X) / 2) Else X = pPointA.X + ((pPointB.X - pPointA.X) / 2) End If If pPointA.Y > pPointB.Y Then Y = pPointB.Y + ((pPointA.Y - pPointB.Y) / 2) Else Y = pPointA.Y + ((pPointB.Y - pPointA.Y) / 2) End If pPointC.X = X pPointC.Y = Y pPointCollection.AddPoint pPointC, 1 Set pFeature.Shape = pPointCollection pFeature.Store pFeatureSelection.Add pFeature ShapeCounter = ShapeCounter + 1

End If

Set pFeature = pFC.NextFeature

Loop

MsgBox (ShapeCounter & " polyline have been updated")pMxDoc.ActiveView.Refresh

Else

MsgBox ("Please select polyline layer")Exit Sub

End If

End Sub

23

Page 24: Arc Objects IMP Examples

Add a shapefile to a map

Description

This sample, which can easily be changed to support different data types, opens a shapefile on your local disk and adds the contents to the map as a feature layer.In this sample, you will be adding a control button and writing the code for it.

How to use

1. Start ArcMap. 2. Open an existing map document (.mxd) or add layers to the empty (Untitled) map document. 3. Click Tools and click Customize. 4. Click the Commands tab. 5. Click the drop-down arrow on the Save in combo box and click the map document in which the new command will be saved. 6. Scroll through the Categories list and click [UIControls]. 7. Click New UIControl. 8. Click to select the UIButtonControl as the UIControl Type. 9. Click Create. 10. Click and drag the new Project.UIButtonControl1 in the Commands list and drop it on any toolbar. 11. Click Close. 12. Right-click the newly placed control and click View Source. This opens the Visual Basic Editor. 13. In the ThisDocument (Code) window, click the Procedure Box drop-down arrow (the one on the right of the window) and choose Click. This adds the wrapper code for the procedure you are creating. 14. Copy and paste the following code between the two wrapper code lines (between Private Sub UIButtonControl1_Click() and End Sub).

Dim pWorkspaceFactory As IWorkspaceFactory Set pWorkspaceFactory = New ShapefileWorkspaceFactory

Dim pWorkSpace As IFeatureWorkspace 'Change C:\Source to the source location of the shapefile you wish to add Set pWorkSpace = pWorkspaceFactory.OpenFromFile("C:\Source", 0)

Dim pClass As IFeatureClass 'Change USStates to the name of the shapefile you wish to add Set pClass = pWorkSpace.OpenFeatureClass("USStates")

Dim pLayer As IFeatureLayer Set pLayer = New FeatureLayer Set pLayer.FeatureClass = pClass pLayer.Name = pClass.AliasName

Dim pMxDoc As IMxDocument Set pMxDoc = ThisDocument

pMxDoc.AddLayer pLayer pMxDoc.ActiveView.PartialRefresh esriViewGeography, pLayer, Nothing

15. Go to line 5, Set pWorkSpace = pWorkspaceFactory.OpenFromFile("C:\Source", 0), and change C:\Source to the source location of the shapefile you want to add.

24

Page 25: Arc Objects IMP Examples

16. Go to line 8, Set pClass = pWorkSpace.OpenFeatureClass("USStates"), and change USStates to the name of the shapefile you want to add. 17. Close the Visual Basic Editor. 18. Click the new button in ArcMap to add the feature class to the map.

Tip

* Make sure the code in Visual Basic appears as it does in the above steps. For example, you may have to add carriage returns.

Title: AddPointsAtCrossings Version: 1.2

Provided by: ESRI-TeamWater as an unsupported, free sample for Water Utilities

Purpose: Create new point features at every crossing (intersection) between line features in two specified layers

Uses: Create crossing points between water mains and gas pipes

Modifications: 1.2 > Changed to Changed line 225 from

pSFilter.SpatialRel = esriSpatialRelCrosses TopSFilter.SpatialRel = esriSpatialRelIntersects

esriSpatialRelCrosses Does not return a point where the end points of lines meet.esriSpatialRelIntersects Returns a feature if any spatial relationship is found.

1.3> Correction to this help file under data requirements. ONLY the Point layer MUST be in an Editable workspace, not all 3 as previously stated.

Files:ReadMe_ AddPointsAtCrossings.htmAddPointsAtCrossings.bas

Data requirements:

Two line layers are needed. One point layer is needed. The point layer must be in an editable workspace. These layers may be either shapefiles or geodatabase feature classes. Must have edit target set to the desired point feature. Optionally, may have some lines from the first specified layer selected.

Overview of setup (detailed instructions follow this overview):1) use VBA (provided with ArcMap) to import the code file provided with this sample. 2) optionally, alter the user configuration at the top of the code to match your data3) optionally, drag one or more of the provided macros onto a toolbar in ArcMap4) save your mxd (if you did not elect to save these changes to normal)

Setup:In ArcMap

Tools>Macros>VB Editor

In VB EditorIn the Project Window…

Click Project to store changes for this map document only orClick Normal to store changes for all maps you access on your computer

File>Import File...Navigate to AddPointsAtCrossings.bas and click OpenExpand the Modules folder

25

Page 26: Arc Objects IMP Examples

Double-click the AddPointsAtCrossings module to view the codeChange the user configuration as desired (see user configuration below)Close VB Window

If you chose to save your changes with this Project, save your map document now.

User configuration:If you run the UseHighlightedLayers routine, you will not need to change any code.

If desired, you may configure the Example_ AddPointsAtCrossings routine to work with your data, so that you will not need to highlight any layers in the Table of Contents. You will still need to set your edit target and optionally select some lines from the first layer.

To use: In ArcMap, be sure you have the necessary layers in your map. Be sure that you are editing. Set the edit target to the point feature you wish to create. In the Table of Contents, highlight the two line layers that you wish to use. Select some of the points. Optionally, select one line. Tools>Macros>Macros… Select AddLines.UseHighlightedLayers Click Run

Here's what happens... New point features are created.

Credits:This code was created by ESRI-Team Water.

Your Input: Please send any comments via email to Michele Lundeen at [email protected].

1)

Option ExplicitPublic Sub Example_AddPointsAtCrossings() Call AddPoints("Water Mains", "Sewer Gravity Mains")End Sub

Public Sub UseHighlightedLayers()

Dim pMxDoc As IMxDocument Dim pMap As IMap Dim pTest As Variant Dim pSetLayers As ISet Dim pLayer1 As ILayer Dim pLayer2 As ILayer Dim pFLayer1 As IFeatureLayer Dim pFLayer2 As IFeatureLayer Dim pFC1 As IFeatureClass Dim pFC2 As IFeatureClass Set pMxDoc = Application.Document Set pMap = pMxDoc.FocusMap ' Verify that there are at least 2 layers in the table on contents If pMap.LayerCount < 2 Then

26

Page 27: Arc Objects IMP Examples

MsgBox "Must have at least two layers in your map." Exit Sub End If 'Verify that two layers are selected in the TOC Set pTest = pMxDoc.SelectedItem If pTest Is Nothing Then MsgBox "Please highlight one or two line layers in the TOC." Exit Sub End If If Not TypeOf pMxDoc.SelectedItem Is ISet Then Set pLayer1 = pMxDoc.SelectedItem Set pLayer2 = pMxDoc.SelectedItem Else Set pSetLayers = pMxDoc.SelectedItem If pSetLayers.Count > 2 Then MsgBox "Please highlight only one or two line layers in the TOC." Exit Sub End If pSetLayers.Reset Set pLayer1 = pSetLayers.Next Set pLayer2 = pSetLayers.Next End If

'Verify that the highlighted layers are feature layers If Not TypeOf pLayer1 Is IFeatureLayer Then MsgBox pLayer1.name & " is not a feature layer." Exit Sub End If If Not TypeOf pLayer2 Is IFeatureLayer Then MsgBox pLayer2.name & " is not a feature layer." Exit Sub End If 'Get the feature layer and feature class pointers Set pFLayer1 = pLayer1 Set pFLayer2 = pLayer2 Set pFC1 = pFLayer1.FeatureClass Set pFC2 = pFLayer2.FeatureClass

'If the first highlighted layer is a line layer... If pFC1.ShapeType = esriGeometryPolyline Or pFC1.ShapeType = esriGeometryLine And _ pFC2.ShapeType = esriGeometryPolyline Or pFC1.ShapeType = esriGeometryLine Then 'Run the Addpoints routine AddPoints pLayer1.name, pLayer2.name Else MsgBox "You need two line layers highlighted." Exit Sub End IfEnd Sub

Public Sub AddPoints(sLineLayer1 As String, sLineLayer2 As String)' Purpose: Adds points wherever the line features from the specified layers cross' Requires: must be editing and have target point layer set' Optionally: have some features selected in the first line layer

On Error GoTo EH Dim pApp As IApplication Dim pMxDoc As IMxDocument Dim pMap As IMap

27

Page 28: Arc Objects IMP Examples

Dim pId As New UID Dim pEditor As IEditor Dim pELayers As IEditLayers Dim pFLayerLine1 As IFeatureLayer Dim pFLayerLine2 As IFeatureLayer Dim pFLayerCross As IFeatureLayer Dim pFCLine1 As IFeatureClass Dim pFCLine2 As IFeatureClass Dim pFCCross As IFeatureClass Dim pFSel1 As IFeatureSelection Dim pFCursor1 As IFeatureCursor Dim pFCursor2 As IFeatureCursor Dim pFeature1 As IFeature Dim pFeature2 As IFeature Dim pNewFeature As IFeature Dim lCount As Long Dim lTotal As Long Dim pRowSubtypes As IRowSubtypes Dim pSubtypes As ISubtypes Dim lSubCode As Long Dim bHasSubtypes As Boolean Dim pCurve1 As ICurve Dim pCurve2 As ICurve Dim pTopoOp1 As ITopologicalOperator Dim pEnv1 As IEnvelope Dim pSFilter As ISpatialFilter Dim pPoint As IPoint Dim pMPoint As IMultipoint Dim pGeoCol As IGeometryCollection Dim lGeoTotal As Long Dim lGeoCount As Integer Set pApp = Application Set pMxDoc = pApp.Document Set pMap = pMxDoc.FocusMap ' Verify that there are at least 2 layers in the table on contents If pMap.LayerCount < 2 Then MsgBox "Must have at least two layers in your map." Exit Sub End If 'Find the two line layers by name Set pFLayerLine1 = FindFLayerByName(pMap, sLineLayer1) Set pFLayerLine2 = FindFLayerByName(pMap, sLineLayer2) 'Verify layers exisit If pFLayerLine1 Is Nothing Then MsgBox sLineLayer1 & " layer not found." Exit Sub End If If pFLayerLine2 Is Nothing Then MsgBox sLineLayer2 & " layer not found." Exit Sub End If Set pFCLine1 = pFLayerLine1.FeatureClass Set pFCLine2 = pFLayerLine2.FeatureClass 'Verify that it is a correct type of geometry If pFCLine1.ShapeType <> esriGeometryPolyline And pFCLine1.ShapeType <> esriGeometryLine Then MsgBox sLineLayer1 & " layer must be a line or polyline layer."

28

Page 29: Arc Objects IMP Examples

Exit Sub End If If pFCLine2.ShapeType <> esriGeometryPolyline And pFCLine2.ShapeType <> esriGeometryLine Then MsgBox sLineLayer2 & " layer must be a line or polyline layer." Exit Sub End If 'Verify that we are editing pId = "esriEditor.Editor" Set pEditor = pApp.FindExtensionByCLSID(pId) If Not (pEditor.EditState = esriStateEditing) Then MsgBox "Must be editing." Exit Sub End If 'Verify that the target is a point layer Set pELayers = pEditor If pELayers.CurrentLayer.FeatureClass.ShapeType = esriGeometryMultipoint Then MsgBox "This edit target is a multipoint layer. Please use a point layer." & vbNewLine & "Convert using ""Multipart To Singlepart"" GP tool if needed." Exit Sub End If If pELayers.CurrentLayer.FeatureClass.ShapeType <> esriGeometryPoint Then MsgBox "Edit target must be a point layer (i.e. crossing points)." Exit Sub End If 'Get the target point layer Set pFLayerCross = pELayers.CurrentLayer Set pFCCross = pFLayerCross.FeatureClass 'Get current target subtype If TypeOf pFCCross Is ISubtypes Then Set pSubtypes = pFCCross If pSubtypes.HasSubtype Then bHasSubtypes = True lSubCode = pELayers.CurrentSubtype Else bHasSubtypes = False End If End If 'Update Message bar pApp.StatusBar.Message(0) = "Adding " & pFLayerCross.name & " points..." 'Start edit operation (for undo) pEditor.StartOperation 'Now that an edit operation has been started, use a different error handler 'in order to abort this operation if a problem occurs On Error GoTo EH2 'If any features in the first layer are selected, use them only 'Otherwise use all features from the first layer Set pFSel1 = pFLayerLine1 If pFSel1.SelectionSet.Count > 0 Then pFSel1.SelectionSet.Search Nothing, False, pFCursor1 lTotal = pFSel1.SelectionSet.Count Else If vbNo = MsgBox("Use all " & pFCLine1.FeatureCount(Nothing) & " features?", vbYesNo, "Add Points") Then Exit Sub

29

Page 30: Arc Objects IMP Examples

End If Set pFCursor1 = pFLayerLine1.Search(Nothing, False) lTotal = pFLayerLine1.FeatureClass.FeatureCount(Nothing) End If 'Step through each feature in layer1 lCount = 1 Set pFeature1 = pFCursor1.NextFeature Do While Not pFeature1 Is Nothing 'Update status bar lCount = lCount + 1 pApp.StatusBar.Message(0) = "Processing " & pFLayerLine1.name & " lines ..." & Str(lCount) & " of " & Str(lTotal) 'Get needed references to this feature from layer1 Set pCurve1 = pFeature1.Shape Set pTopoOp1 = pCurve1 Set pEnv1 = pCurve1.Envelope 'Create a spatial filter for layer2 to find any potentially crossing lines Set pSFilter = New SpatialFilter Set pSFilter.Geometry = pEnv1 pSFilter.GeometryField = pFCLine2.ShapeFieldName pSFilter.SpatialRel = esriSpatialRelIntersects Set pFCursor2 = pFCLine2.Search(pSFilter, False) ' Step through each feature in layer2 that crosses the envelope of the ' current feature we are processing from layer1 Set pFeature2 = pFCursor2.NextFeature Do While Not pFeature2 Is Nothing 'Get the geometry for this feature from layer2 If pFLayerLine1 Is pFLayerLine2 Then Set pCurve2 = pFeature2.ShapeCopy Else Set pCurve2 = pFeature2.Shape End If 'Find all intersecting points (returned as multipoint) Set pMPoint = pTopoOp1.Intersect(pCurve2, esriGeometry0Dimension) If Not pMPoint Is Nothing Then If Not pMPoint.IsEmpty Then Set pGeoCol = pMPoint 'Step through each point in the multipoint (often just one) lGeoTotal = pGeoCol.GeometryCount For lGeoCount = 0 To lGeoTotal - 1 'Get the point Set pPoint = pGeoCol.Geometry(lGeoCount) 'Create the new feature and set it's geometry Set pNewFeature = pFCCross.CreateFeature Set pNewFeature.Shape = pPoint 'If needed, set the subtype and default values If bHasSubtypes Then Set pRowSubtypes = pNewFeature pRowSubtypes.SubtypeCode = lSubCode pRowSubtypes.InitDefaultValues End If

30

Page 31: Arc Objects IMP Examples

'Save the new feature pNewFeature.Store Next lGeoCount End If End If

Set pFeature2 = pFCursor2.NextFeature Loop Set pFeature1 = pFCursor1.NextFeature Loop

'Stop feature editing pEditor.StopOperation ("Add Points") 'Clear all feature selections pMap.ClearSelection 'Redraw the map so you'll see the new lines pMxDoc.ActiveView.Refresh 'MsgBox "Auto Add Points is complete." pApp.StatusBar.Message(0) = "Add Points is complete." Exit SubEH: MsgBox Err.Number & " " & Err.Description Exit SubEH2: pEditor.AbortOperation MsgBox Err.Number & " " & Err.Description Exit SubEnd Sub

Public Function FindFLayerByName(pMap As IMap, sLayerName As String) As IFeatureLayer 'This function will return only feature layers. 'It can find feature layers within groups. Dim pEnumLayer As IEnumLayer Dim pCompositeLayer As ICompositeLayer Dim i As Integer Set pEnumLayer = pMap.Layers pEnumLayer.Reset

Dim pLayer As ILayer Set pLayer = pEnumLayer.Next

Do While Not pLayer Is Nothing If TypeOf pLayer Is ICompositeLayer Then Set pCompositeLayer = pLayer For i = 0 To pCompositeLayer.Count - 1 With pCompositeLayer If .Layer(i).name = sLayerName Then If TypeOf .Layer(i) Is IFeatureLayer Then Set FindFLayerByName = pCompositeLayer.Layer(i) Exit Function

31

Page 32: Arc Objects IMP Examples

End If End If End With Next i ElseIf pLayer.name = sLayerName And TypeOf pLayer Is IFeatureLayer Then Set FindFLayerByName = pLayer Exit Function End If Set pLayer = pEnumLayer.Next Loop

End Function2)

Option ExplicitPublic Sub Example_AddPointsAtCrossings() Call AddPoints("Water Mains", "Sewer Gravity Mains")End Sub

Public Sub UseHighlightedLayers()

Dim pMxDoc As IMxDocument Dim pMap As IMap Dim pTest As Variant Dim pSetLayers As ISet Dim pLayer1 As ILayer Dim pLayer2 As ILayer Dim pFLayer1 As IFeatureLayer Dim pFLayer2 As IFeatureLayer Dim pFC1 As IFeatureClass Dim pFC2 As IFeatureClass Set pMxDoc = Application.Document Set pMap = pMxDoc.FocusMap ' Verify that there are layers in the table on contents If pMap.LayerCount < 3 Then MsgBox "Must have at least three layers in your map." Exit Sub End If 'Verify that two layers are selected in the TOC Set pTest = pMxDoc.SelectedItem If pTest Is Nothing Then MsgBox "Please highlight two layers in the TOC." Exit Sub End If If Not TypeOf pMxDoc.SelectedItem Is ISet Then MsgBox "Please highlight two layers in the TOC." Exit Sub End If Set pSetLayers = pMxDoc.SelectedItem If pSetLayers.Count <> 2 Then MsgBox "Please highlight only two layers in the TOC." Exit Sub End If 'Get each of these highlighted layers from the TOC pSetLayers.Reset Set pLayer1 = pSetLayers.Next Set pLayer2 = pSetLayers.Next

32

Page 33: Arc Objects IMP Examples

'Verify that the highlighted layers are feature layers If Not TypeOf pLayer1 Is IFeatureLayer Then MsgBox pLayer1.name & " is not a feature layer." Exit Sub End If If Not TypeOf pLayer2 Is IFeatureLayer Then MsgBox pLayer2.name & " is not a feature layer." Exit Sub End If 'Get the feature layer and feature class pointers Set pFLayer1 = pLayer1 Set pFLayer2 = pLayer2 Set pFC1 = pFLayer1.FeatureClass Set pFC2 = pFLayer2.FeatureClass

'If the first highlighted layer is a line layer... If pFC1.ShapeType = esriGeometryPolyline Or pFC1.ShapeType = esriGeometryLine And _ pFC2.ShapeType = esriGeometryPolyline Or pFC1.ShapeType = esriGeometryLine Then 'Run the Addlines routine AddPoints pLayer1.name, pLayer2.name Else MsgBox "You need two line layers highlighted." Exit Sub End IfEnd Sub

Public Sub AddPoints(sLineLayer1 As String, sLineLayer2 As String)' Purpose: Adds points wherever the line features from the specified layers cross' Requires: must be editing and have target point layer set' Optionally: have some features selected in the first line layer

On Error GoTo EH Dim pApp As IApplication Dim pMxDoc As IMxDocument Dim pMap As IMap Dim pId As New UID Dim pEditor As IEditor Dim pELayers As IEditLayers Dim pFLayerLine1 As IFeatureLayer Dim pFLayerLine2 As IFeatureLayer Dim pFLayerCross As IFeatureLayer Dim pFCLine1 As IFeatureClass Dim pFCLine2 As IFeatureClass Dim pFCCross As IFeatureClass Dim pFSel1 As IFeatureSelection Dim pFCursor1 As IFeatureCursor Dim pFCursor2 As IFeatureCursor Dim pFeature1 As IFeature Dim pFeature2 As IFeature Dim pNewFeature As IFeature Dim lCount As Long Dim lTotal As Long Dim pRowSubtypes As IRowSubtypes Dim pSubtypes As ISubtypes Dim lSubCode As Long Dim bHasSubtypes As Boolean Dim pCurve1 As ICurve Dim pCurve2 As ICurve Dim pTopoOp1 As ITopologicalOperator Dim pEnv1 As IEnvelope

33

Page 34: Arc Objects IMP Examples

Dim pSFilter As ISpatialFilter Dim pPoint As IPoint Dim pMPoint As IMultipoint Dim pGeoCol As IGeometryCollection Dim lGeoTotal As Long Dim lGeoCount As Integer Set pApp = Application Set pMxDoc = pApp.Document Set pMap = pMxDoc.FocusMap ' Verify that there are layers in the table on contents If pMap.LayerCount < 3 Then MsgBox "Must have at least three layers in your map." Exit Sub End If 'Find the two line layers by name Set pFLayerLine1 = FindFLayerByName(pMap, sLineLayer1) Set pFLayerLine2 = FindFLayerByName(pMap, sLineLayer2) 'Verify layers exisit If pFLayerLine1 Is Nothing Then MsgBox sLineLayer1 & " layer not found." Exit Sub End If If pFLayerLine2 Is Nothing Then MsgBox sLineLayer2 & " layer not found." Exit Sub End If Set pFCLine1 = pFLayerLine1.FeatureClass Set pFCLine2 = pFLayerLine2.FeatureClass 'Verify that it is a correct type of geometry If pFCLine1.ShapeType <> esriGeometryPolyline And pFCLine1.ShapeType <> esriGeometryLine Then MsgBox sLineLayer1 & " layer must be a line or polyline layer." Exit Sub End If If pFCLine2.ShapeType <> esriGeometryPolyline And pFCLine2.ShapeType <> esriGeometryLine Then MsgBox sLineLayer2 & " layer must be a line or polyline layer." Exit Sub End If 'Verify that we are editing pId = "esriCore.Editor" Set pEditor = pApp.FindExtensionByCLSID(pId) If Not (pEditor.EditState = esriStateEditing) Then MsgBox "Must be editing." Exit Sub End If 'Verify that the target is a point layer Set pELayers = pEditor If pELayers.CurrentLayer.FeatureClass.ShapeType <> esriGeometryPoint Then MsgBox "Edit target must be a point layer (i.e. crossing points)." Exit Sub End If 'Get the target polyline layer Set pFLayerCross = pELayers.CurrentLayer Set pFCCross = pFLayerCross.FeatureClass

34

Page 35: Arc Objects IMP Examples

'Get current target subtype If TypeOf pFCCross Is ISubtypes Then Set pSubtypes = pFCCross If pSubtypes.HasSubtype Then bHasSubtypes = True lSubCode = pELayers.CurrentSubtype Else bHasSubtypes = False End If End If 'Update Message bar pApp.StatusBar.Message(0) = "Adding " & pFLayerCross.name & " points..." 'Start edit operation (for undo) pEditor.StartOperation 'Now that an edit operation has been started, use a different error handler 'in order to abort this operation if a problem occurs On Error GoTo EH2 'If any features in the first layers are selected, use them only 'Otherwise use all features from the first layer Set pFSel1 = pFLayerLine1 If pFSel1.SelectionSet.Count > 0 Then pFSel1.SelectionSet.Search Nothing, False, pFCursor1 lTotal = pFSel1.SelectionSet.Count Else Set pFCursor1 = pFLayerLine1.Search(Nothing, False) lTotal = pFLayerLine1.FeatureClass.FeatureCount(Nothing) End If 'Step through each feature in layer1 lCount = 1 Set pFeature1 = pFCursor1.NextFeature Do While Not pFeature1 Is Nothing 'Update status bar lCount = lCount + 1 pApp.StatusBar.Message(0) = "Processing " & pFLayerLine1.name & " lines ..." & Str(lCount) & " of " & Str(lTotal) 'Get needed references to this feature from layer1 Set pCurve1 = pFeature1.Shape Set pTopoOp1 = pCurve1 Set pEnv1 = pCurve1.Envelope 'Create a spatial filter for layer2 to find any potentially crossing lines Set pSFilter = New SpatialFilter Set pSFilter.Geometry = pEnv1 pSFilter.GeometryField = pFCLine2.ShapeFieldName pSFilter.SpatialRel = esriSpatialRelIntersects Set pFCursor2 = pFCLine2.Search(pSFilter, False) ' Step through each feature in layer2 that crosses the envelope of the ' current feature we are processing from layer1 Set pFeature2 = pFCursor2.NextFeature Do While Not pFeature2 Is Nothing 'Get the geometry for this feature from layer2 Set pCurve2 = pFeature2.Shape

35

Page 36: Arc Objects IMP Examples

'Find all intersecting points (returned as multipoint) Set pMPoint = pTopoOp1.Intersect(pCurve2, esriGeometry0Dimension) If Not pMPoint Is Nothing Then If Not pMPoint.IsEmpty Then Set pGeoCol = pMPoint 'Step through each point in the multipoint (often just one) lGeoTotal = pGeoCol.GeometryCount For lGeoCount = 0 To lGeoTotal - 1 'Get the point Set pPoint = pGeoCol.Geometry(lGeoCount) 'Create the new feature and set it's geometry Set pNewFeature = pFCCross.CreateFeature Set pNewFeature.Shape = pPoint 'If needed, set the subtype and default values If bHasSubtypes Then Set pRowSubtypes = pNewFeature pRowSubtypes.SubtypeCode = lSubCode pRowSubtypes.InitDefaultValues End If 'Save the new feature pNewFeature.Store Next lGeoCount End If End If

Set pFeature2 = pFCursor2.NextFeature Loop Set pFeature1 = pFCursor1.NextFeature Loop

'Stop feature editing pEditor.StopOperation ("Add Points") 'Clear all feature selections pMap.ClearSelection 'Redraw the map so you'll see the new lines pMxDoc.ActiveView.Refresh 'MsgBox "Auto Add Points is complete." pApp.StatusBar.Message(0) = "Add Points is complete." Exit SubEH: MsgBox Err.Number & " " & Err.Description Exit SubEH2: pEditor.AbortOperation MsgBox Err.Number & " " & Err.Description Exit SubEnd Sub

36

Page 37: Arc Objects IMP Examples

Public Function FindFLayerByName(pMap As IMap, sLayerName As String) As IFeatureLayer 'This function will return only feature layers. 'It can find feature layers within groups. Dim pEnumLayer As IEnumLayer Dim pCompositeLayer As ICompositeLayer Dim i As Integer Set pEnumLayer = pMap.Layers pEnumLayer.Reset

Dim pLayer As ILayer Set pLayer = pEnumLayer.Next

Do While Not pLayer Is Nothing If TypeOf pLayer Is ICompositeLayer Then Set pCompositeLayer = pLayer For i = 0 To pCompositeLayer.Count - 1 With pCompositeLayer If .Layer(i).name = sLayerName Then If TypeOf .Layer(i) Is IFeatureLayer Then Set FindFLayerByName = pCompositeLayer.Layer(i) Exit Function End If End If End With Next i ElseIf pLayer.name = sLayerName And TypeOf pLayer Is IFeatureLayer Then Set FindFLayerByName = pLayer Exit Function End If Set pLayer = pEnumLayer.Next Loop

End Function

37

Page 38: Arc Objects IMP Examples

Public cnnACC As ADODB.Connection 'Access ConnectionPublic rst As ADODB.RecordSetPublic adoCat As ADOX.Catalog 'CatalogPublic adoTbl As ADOX.Table 'TablePublic Location As String

Private Sub ComboBox1_Click() FillrecordinlistviewEnd Sub

Private Sub CommandButton1_Click() '******************************************'Procedure to add a dbf table to the map'****************************************** Dim pFact As IWorkspaceFactory Dim pWorkspace As IWorkspace

38

Page 39: Arc Objects IMP Examples

Dim pFeatws As IFeatureWorkspace Dim pTable As ITable Set pFact = New ShapefileWorkspaceFactory Dim strOpenPath As String Dim strOpenTable As String Dim strTableNamewithPath As String strTableNamewithPath = TextBox1.Text 'Files path location Dim strRev As String strRev = StrReverse(strTableNamewithPath) strRev = Mid(strRev, 1, InStr(1, strRev, "\") - 1) strOpenTable = StrReverse(strRev) strOpenPath = Mid(strTableNamewithPath, 1, InStr(1, strTableNamewithPath, strOpenTable) - 1) Set pWorkspace = pFact.OpenFromFile(strOpenPath, 0) Set pFeatws = pWorkspace Set pTable = pFeatws.OpenTable(strOpenTable) ' add the table Add_Table_TOC pTable End Sub

Private Sub Add_Table_TOC(pTable As ITable)'****************************************************************'Procedure to add the table to Table of Contents of the Map.'**************************************************************** Dim pDoc As IMxDocument Dim pMap As IMap Dim intCol As Integer Dim blnExists As Boolean Set pDoc = ThisDocument Set pMap = pDoc.FocusMap' Create a new standalone table and add it' to the collection of the focus map Dim pStTab As IStandaloneTable Set pStTab = New StandaloneTable Set pStTab.Table = pTable Dim pStTabColl As IStandaloneTableCollection Set pStTabColl = pMap For intCol = 0 To pStTabColl.StandaloneTableCount - 1 If pStTabColl.StandaloneTable(intCol).Name = pStTab.Name Then blnExists = True Exit For End If Next For i = 0 To pDoc.ContentsViewCount - 1 If pDoc.ContentsView(i).Name = "Source" Then Set pDoc.CurrentContentsView = pDoc.ContentsView(i) Exit For End If Next i If blnExists = False Then pStTabColl.AddStandaloneTable pStTab End If' Refresh the TOC pDoc.UpdateContents Set pDoc = Nothing Set pStTabColl = Nothing Set pMap = Nothing Set pStTabColl = Nothing

39

Page 40: Arc Objects IMP Examples

Set pTable = Nothing Set pFeatws = Nothing Set pWorkspace = Nothing Set pFact = NothingEnd Sub

Private Sub CommandButton2_Click() dlg.Filter = "dBASE Files (*.dbf)| *.dbf" dlg.CancelError = True On Error GoTo FileOpenCancel dlg.InitDir = CurDir dlg.ShowOpen TextBox2.Text = dlg.FileTitle TextBox1.Text = dlg.FileName populateListBoxWithTableNames Exit SubFileOpenCancel: Exit SubEnd Sub'fill the recordset into listviewSub FillListViewFromExcel(lv As ListView, rs As ADODB.RecordSet, Optional ImgNum As Long = 0, Optional MultiplyFirstCol As Boolean = False) lv.ListItems.Clear Set cnnACC = New ADODB.Connection If cnnACC.State = adStateOpen Then cnnACC.Close End If Dim strConn As String Dim sSQL As String 'Set New connection Set rs = New ADODB.RecordSet mFolder = Replace(dlg.FileName, dlg.FileTitle, "", 1) strConn = "Driver={Microsoft dBASE Driver (*.dbf)};DriverID=277;Dbq=" & mFolder cnnACC.Open strConn Dim sTable As String sTable = TextBox2.Text sSQL = "Select * from " & sTable rs.Open sSQL, cnnACC, adOpenDynamic, adLockOptimistic If Not rs.BOF Then rs.MoveFirst Dim a As Long Dim lst As ListItem Dim TempVal(100) As String While Not rs.EOF If Not IsNull(rs.Fields(0).Value) Then Set lst = lv.ListItems.Add(, , rs.Fields(0).Value, , ImgNum) TempVal(0) = rs.Fields(0).Value Else Set lst = lv.ListItems.Add(, , "", , ImgNum) End If For a = 1 To lv.ColumnHeaders.Count - 1 If Not IsNull(rs.Fields(a).Value) Then lst.SubItems(a) = rs.Fields(a).Value End If Next

40

Page 41: Arc Objects IMP Examples

rs.MoveNext Wend End If If rs.State = adStateOpen Then rs.Close End If Set rs = Nothing If cnnACC.State = adStateOpen Then cnnACC.Close End If Set cnnACC = Nothing End Sub

Public Sub populateListBoxWithTableNames() ListView1.ColumnHeaders.Clear ListView1.ListItems.Clear

Dim strConn As String Dim sSQL As String 'Set New connection Set cnnACC = New ADODB.Connection Set rst = New ADODB.RecordSet mFolder = Replace(dlg.FileName, dlg.FileTitle, "", 1) strConn = "Driver={Microsoft dBASE Driver (*.dbf)};DriverID=277;Dbq=" & mFolder cnnACC.Open strConn Dim sTable As String sTable = TextBox2.Text sSQL = "Select * from " & sTable rst.Open sSQL, cnnACC, adOpenDynamic, adLockOptimistic 'Call rst.Open("SELECT * FROM " & sTable, cnnACC, adOpenStatic, adLockReadOnly) Dim a As Long For a = 0 To rst.Fields.Count - 1 ListView1.ColumnHeaders.Add , , rst.Fields(a).Name Next Call FillListViewFromExcel(ListView1, rst, 0) End Sub

41

Page 42: Arc Objects IMP Examples

Add Tables from Excel.

'Option ExplicitDim cnExcel As New ADODB.ConnectionDim rsExcel As New ADODB.RecordSetDim ExcelFields As String'fill the recordset into listviewSub FillListViewFromExcel(lv As ListView, rs As ADODB.RecordSet, Optional ImgNum As Long = 0, Optional MultiplyFirstCol As Boolean = False) lv.ListItems.Clear If Not rs.BOF Then rs.MoveFirst Dim a As Long Dim lst As ListItem Dim TempVal(100) As String While Not rs.EOF If Not IsNull(rs.Fields(0).Value) Then Set lst = lv.ListItems.Add(, , rs.Fields(0).Value, , ImgNum) TempVal(0) = rs.Fields(0).Value Else Set lst = lv.ListItems.Add(, , "", , ImgNum) End If For a = 1 To lv.ColumnHeaders.Count - 1 If Not IsNull(rs.Fields(a).Value) Then

42

Page 43: Arc Objects IMP Examples

lst.SubItems(a) = rs.Fields(a).Value End If Next rs.MoveNext Wend End If If rsExcel.State = adStateOpen Then rsExcel.Close End If Set rsExcel = Nothing If cnExcel.State = adStateOpen Then cnExcel.Close Set cnExcel = Nothing End Sub

Private Sub cmdDisp_Click() ListView1.ColumnHeaders.Clear ListView1.ListItems.Clear If List3.ListCount = 0 Then MsgBox "You have not selected any fields to display.", vbExclamation, "No Fields Available" Exit Sub End If Dim x As Long Dim SelectedFields As String SelectedFields = "select " For x = 0 To List3.ListCount - 1 SelectedFields = SelectedFields & "[" & List3.List(x) & "]" If Not (x = List3.ListCount - 1) Then SelectedFields = SelectedFields & ", " End If Next SelectedFields = SelectedFields & " from [" & List1.Text & "]" ' where not isnull(Product)" If rsExcel.State = adStateOpen Then rsExcel.Close End If If cnExcel.State = adStateOpen Then cnExcel.Close Dim ExcelFile As String ExcelFile = txtExcel.Text cnExcel.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & ExcelFile & ";Persist Security Info=False; Extended Properties=Excel 8.0;" rsExcel.Open SelectedFields, cnExcel, adOpenDynamic, adLockOptimistic Dim a As Long For a = 0 To rsExcel.Fields.Count - 1 ListView1.ColumnHeaders.Add , , rsExcel.Fields(a).Name Next Call FillListViewFromExcel(ListView1, rsExcel, 0)End SubPrivate Sub getTables(cn As ADODB.Connection, lst As ListBox)

43

Page 44: Arc Objects IMP Examples

Dim tbl As ADOX.Table Dim cat As New ADOX.Catalog Set cat.ActiveConnection = cn For Each tbl In cat.Tables If Right(tbl.Name, 1) = "$" Then lst.AddItem tbl.Name End If If Right(tbl.Name, 1) = "'" Then lst.AddItem Mid(tbl.Name, 2, Len(tbl.Name) - 2) End If Next tbl Set cat = Nothing If rsExcel.State = adStateOpen Then rsExcel.Close End If Set rsExcel = Nothing If cnExcel.State = adStateOpen Then cnExcel.Close Set cnExcel = Nothing End Sub

Private Sub CommandButton1_Click()If txtExcel.Text = "" ThenMsgBox "Please put The Excel Files"Exit SubElseIf List3.ListCount = 0 ThenMsgBox "You have not selected any fields to display.", vbExclamation, "No Fields Available"Exit SubEnd If

Dim myPath As String myPath = txtExcel.Text 'excel path location connStr = "Provider=Microsoft.Jet.OLEDB.4.0;" & _ "Data Source = " & myPath & ";" & _ "Extended Properties=""Excel 8.0;HDR=YES;""" Dim pPropset As IPropertySet Set pPropset = New PropertySet pPropset.SetProperty "CONNECTSTRING", connStr '++ connect to database Dim pWorkspace As IFeatureWorkspace Dim pWorkspaceFact As IWorkspaceFactory Set pWorkspaceFact = New OLEDBWorkspaceFactory Set pWorkspace = pWorkspaceFact.Open(pPropset, 0) If pWorkspace Is Nothing Then Exit Sub

For i = 0 To List1.ListCount - 1 'select sheet If List1.Selected(i) = True Then Dim sheet As String sheet = (List1.List(i)) End If Next Dim pTable As ITable Set pTable = pWorkspace.OpenTable(sheet)

44

Page 45: Arc Objects IMP Examples

If pTable Is Nothing Then MsgBox "The table was not found" Exit Sub End If

'create the new table object from the dataset name 'Dim pMxDoc As IMxDocument 'Set pMxDoc = ThisDocument 'Dim pMap As IMap 'Set pMap = pMxDoc.ActiveView.FocusMap 'Dim pTableCollection As ITableCollection 'Set pTableCollection = pMap 'pTableCollection.AddTable pTable 'MsgBox "Table added", vbInformation

'Set pTableCollection = pMxDoc.ActiveView.FocusMap 'add the table to Table of Contents ' pMxDoc.UpdateContents '++ Create a table collection and assign the new table to it MsgBox "Table added", vbInformation Dim pStTab As IStandaloneTable Dim pStTabColl As IStandaloneTableCollection Dim pMap As IMap Dim pMxDoc As IMxDocument Set pMxDoc = ThisDocument Set pMap = pMxDoc.ActiveView.FocusMap Set pStTab = New StandaloneTable Set pStTab.Table = pTable Set pStTabColl = pMap If Not TypeOf pTable Is IStandaloneTable Then Set pStTab.Table = pTable pStTab.Name = Replace$(pStTab.Name, "$", "", 1, -1, vbTextCompare) End If pStTabColl.AddStandaloneTable pStTab pMxDoc.UpdateContents '++ Create and open a new table window for the table Dim ptabWin As ITableWindow Set ptabWin = New TableWindow Set ptabWin.Table = pTable ptabWin.ShowAliasNamesInColumnHeadings = True Set ptabWin.Application = Application ptabWin.Show True

45

Page 46: Arc Objects IMP Examples

Set pMxDoc = Nothing Set pStTabColl = Nothing Set pStTab = Nothing Set pMap = Nothing Set ptabWin = Nothing Set pWorkspace = Nothing Set pWorkspaceFact = Nothing Set pPropset = Nothing If rsExcel.State = adStateOpen Then rsExcel.Close End If Set rsExcel = Nothing If cnExcel.State = adStateOpen Then cnExcel.Close Set cnExcel = Nothing

End Sub

Private Sub CommandButton2_Click()On Error Resume Next

Dim blnHasSelected As BooleanDim i As Long

For i = List2.ListCount - 1 To 0 Step -1 ' counts list entries If List2.Selected(i) = True Then blnHasSelected = True List3.AddItem List2.List(i) ' add to other list List2.RemoveItem i ' optional remove End If Next If blnHasSelected = False Then If List2.ListCount = 0 Then Exit Sub End If MsgBox "You have not selected anything.", vbOKOnly + vbInformation, "Select Something" End If End Sub

Private Sub CommandButton3_Click() For i = 0 To List2.ListCount - 1 'select sheet List3.AddItem (List2.List(i)) Next List2.ClearEnd Sub

46

Page 47: Arc Objects IMP Examples

Private Sub CommandButton4_Click()On Error Resume Next

Dim blnHasSelected As BooleanDim i As Long

For i = List3.ListCount - 1 To 0 Step -1 ' counts list entries If List3.Selected(i) = True Then ' if selected then List2.AddItem List3.List(i) ' add to other list List3.RemoveItem i ' optional remove blnHasSelected = True End If Next If blnHasSelected = False Then If List3.ListCount = 0 Then Exit Sub End If MsgBox "You have not selected anything.", vbOKOnly + vbInformation, "Select Something" End If

End Sub

Private Sub CommandButton5_Click() For i = 0 To List3.ListCount - 1 'select sheet List2.AddItem (List3.List(i)) Next List3.ClearEnd Sub

Private Sub dlg_Enter()

End Sub

Private Sub List1_DblClick(ByVal Cancel As MSForms.ReturnBoolean)

End Sub

Private Sub List2_Click()

End Sub

Private Sub List2_DblClick(ByVal Cancel As MSForms.ReturnBoolean)' On Error Resume Next 'List3.AddItem List2.Text 'List2.RemoveItem List2.ListIndex

End Sub

Private Sub List3_Click()

End Sub

Private Sub List3_DblClick(ByVal Cancel As MSForms.ReturnBoolean) ' On Error Resume Next ' List2.AddItem List3.Text 'List3.RemoveItem List3.ListIndexEnd Sub

47

Page 48: Arc Objects IMP Examples

Private Sub lvOpen_Click() 'open excel filedlg.CancelError = TrueOn Error GoTo FileOpenCancel Dim ExcelFile As String ExcelFile = "xxx"

While Not (LCase(Mid(ExcelFile, Len(ExcelFile) - 2, 3)) = "xls" Or ExcelFile = "Canceled") If ExcelFile = "Canceled" Then Exit Sub ExcelFile = "xxx" ExcelFile = openExcel Wend If cnExcel.State = adStateOpen Then cnExcel.Close txtExcel = ExcelFile cnExcel.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & ExcelFile & ";Persist Security Info=False; Extended Properties=Excel 8.0;" List1.Clear List2.Clear List3.Clear ListView1.ColumnHeaders.Clear ListView1.ListItems.Clear Call getTables(cnExcel, List1) Exit SubFileOpenCancel: Exit SubEnd Sub

'display the worksheet for the excel filePrivate Sub List1_Click() If rsExcel.State = adStateOpen Then rsExcel.Close End If If cnExcel.State = adStateOpen Then cnExcel.Close Dim ExcelFile As String ExcelFile = txtExcel.Text cnExcel.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & ExcelFile & ";Persist Security Info=False; Extended Properties=Excel 8.0;" rsExcel.Open "select * from [" & List1.Text & "]", cnExcel, adOpenDynamic, adLockOptimistic List2.Clear List3.Clear ListView1.ColumnHeaders.Clear ListView1.ListItems.Clear Dim a As Long For a = 0 To rsExcel.Fields.Count - 1 If Not Trim(rsExcel.Fields(a).Name) = "" Then List2.AddItem rsExcel.Fields(a).Name End If Next

If rsExcel.State = adStateOpen Then rsExcel.Close End If

48

Page 49: Arc Objects IMP Examples

Set rsExcel = Nothing If cnExcel.State = adStateOpen Then cnExcel.Close Set cnExcel = Nothing End Sub

Function openExcel() As String 'open excel file dlg.Filter = "All Microsoft Office Excel Files (*.xls)|*.xls|All files (*.*)|*.*" dlg.FilterIndex = 1 dlg.DefaultExt = "xls" dlg.Flags = cdlOFNHideReadOnly dlg.ShowOpen openExcel = dlg.FileName Exit FunctionEnd Function

Add Unique Sequential Value to an Attribute Table

Private Sub UIButtonControl1_Click()

Dim pMxDoc As IMxDocument Dim pMap As IMap Dim pLayer As ILayer Dim pSelItem As IUnknown Dim pStandaloneTable As IStandaloneTable Dim pFeatLyr As IFeatureLayer Dim pFeatClass As IFeatureClass

'++Map Document active Set pMxDoc = ThisDocument Set pMap = pMxDoc.FocusMap '++Get Selected Item Set pSelItem = pMxDoc.SelectedItem

'++Is something selected in TOC? If pMxDoc.SelectedItem Is Nothing Then MsgBox "Must first select a Shapefile or Standalone Table from the TOC." Exit Sub End If '++Make sure selected something is a StandaloneTable or Shapefile If TypeOf pSelItem Is IStandaloneTable Then Set pStandaloneTable = pSelItem ElseIf TypeOf pSelItem Is IFeatureLayer Then Set pLayer = pSelItem Set pFeatLyr = pLayer Set pFeatClass = pFeatLyr.FeatureClass If pFeatClass.ShapeType = esriGeometryPoint Then ElseIf pFeatClass.ShapeType = esriGeometryLine Then ElseIf pFeatClass.ShapeType = esriGeometryPolyline Then ElseIf pFeatClass.ShapeType = esriGeometryPolygon Then Else MsgBox "Selected feature layer must be a point, line, polyline or polygon shapefile!" Exit Sub End If

49

Page 50: Arc Objects IMP Examples

Else MsgBox "Must first select a Standalone Table or Shapefile." Exit Sub End If frmAddUniqueVal2Table.Show End Sub

Private Function UIButtonControl1_Enabled() As Boolean Dim pMxDoc As IMxDocument Dim pMap As IMap Dim pLayer As ILayer Dim bolEnabled As Boolean Dim pSelItem As IUnknown Set pMxDoc = ThisDocument Set pMap = pMxDoc.FocusMap bolEnabled = True Set pSelItem = pMxDoc.SelectedItem

'++Disable if the selected item is nothing, if it is not '++ a layer or table, or if multiple items are selected If pSelItem Is Nothing Then bolEnabled = False ElseIf Not (TypeOf pSelItem Is ILayer Or TypeOf pSelItem Is IStandaloneTable) Then bolEnabled = False End If UIButtonControl1_Enabled = bolEnabledEnd Function

Private Function UIButtonControl1_ToolTip() As String UIButtonControl1_ToolTip = "Add Unique Value to Table"End Function

ADD TABLES FROM ACCESS AND EXPORT TO DBF

50

Page 51: Arc Objects IMP Examples

Public cnnACC As ADODB.Connection 'Access ConnectionPublic rst As ADODB.RecordSetPublic adoCat As ADOX.Catalog 'CatalogPublic adoTbl As ADOX.Table 'Table

Private Sub ComboBox1_Click() FillrecordinlistviewEnd Sub

Private Sub CommandButton1_Click()

'C:\Documents and Settings\fauzul\Desktop\Populate Access\Northwind.mdb Dim pPropset As IPropertySet Set pPropset = New PropertySet Dim Path As String Path = CurDir

51

Page 52: Arc Objects IMP Examples

pPropset.SetProperty "CONNECTSTRING", "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Path & "\Northwind.mdb;" '++ Create a new workspacefactory/workspace Dim pWorkspaceFact As IWorkspaceFactory Set pWorkspaceFact = New OLEDBWorkspaceFactory

Dim pWorkspace As IWorkspace Set pWorkspace = pWorkspaceFact.Open(pPropset, 0) If pWorkspace Is Nothing Then Exit Sub Dim pFeatWorkspace As IFeatureWorkspace Set pFeatWorkspace = pWorkspace

'++ Get the datasets (names) in the workspace Dim pEnumDataset As IEnumDatasetName Set pEnumDataset = pWorkspace.DatasetNames(esriDTTable)

'++ Create a new dataset object for the table you want to load Dim pDataset As IDatasetName Set pDataset = pEnumDataset.Next Dim TABLE_NAME As String TABLE_NAME = ComboBox1.Text Do Until pDataset Is Nothing If pDataset.Name = TABLE_NAME Then Exit Do End If Set pDataset = pEnumDataset.Next Loop '++ Create and open the new table object from the dataset name Dim pTable As ITable Set pTable = pFeatWorkspace.OpenTable(pDataset.Name) If pTable Is Nothing Then MsgBox "The table was not found" Exit Sub End If '++ Create a table collection and assign the new table to it MsgBox "Table added", vbInformation Dim pStTab As IStandaloneTable Dim pStTabColl As IStandaloneTableCollection Dim pMap As IMap Dim pMxDoc As IMxDocument Set pMxDoc = ThisDocument Set pMap = pMxDoc.ActiveView.FocusMap Set pStTab = New StandaloneTable Set pStTab.Table = pTable Set pStTabColl = pMap If Not TypeOf pTable Is IStandaloneTable Then Set pStTab.Table = pTable pStTab.Name = Replace$(pStTab.Name, "$", "", 1, -1, vbTextCompare) End If pStTabColl.AddStandaloneTable pStTab For i = 0 To pMxDoc.ContentsViewCount - 1 If pMxDoc.ContentsView(i).Name = "Source" Then Set pMxDoc.CurrentContentsView = pMxDoc.ContentsView(i)

52

Page 53: Arc Objects IMP Examples

Exit For End If Next i pMxDoc.UpdateContents '++ Create and open a new table window for the table Dim ptabWin As ITableWindow Set ptabWin = New TableWindow Set ptabWin.Table = pTable ptabWin.ShowAliasNamesInColumnHeadings = True Set ptabWin.Application = Application ptabWin.Show True Set pMxDoc = Nothing Set pStTabColl = Nothing Set pStTab = Nothing Set pMap = Nothing Set pWorkspace = Nothing Set pWorkspaceFact = Nothing Set pPropset = Nothing Unload Me If MsgBox("Do you want export this tables to dbf files?", vbOKCancel, "Export") = vbOK Then Unload Me ptabWin.Show False Set ptabWin = Nothing UserForm2.Show Else Exit Sub End If End Sub

Private Sub CommandButton2_Click()

End Sub

Private Sub UserForm_Initialize()populateListBoxWithTableNamesEnd Sub'fill the recordset into listviewSub FillListViewFromExcel(lv As ListView, rs As ADODB.RecordSet, Optional ImgNum As Long = 0, Optional MultiplyFirstCol As Boolean = False) lv.ListItems.Clear If Not rs.BOF Then rs.MoveFirst Dim a As Long Dim lst As ListItem Dim TempVal(100) As String While Not rs.EOF If Not IsNull(rs.Fields(0).Value) Then Set lst = lv.ListItems.Add(, , rs.Fields(0).Value, , ImgNum) TempVal(0) = rs.Fields(0).Value Else Set lst = lv.ListItems.Add(, , "", , ImgNum) End If For a = 1 To lv.ColumnHeaders.Count - 1 If Not IsNull(rs.Fields(a).Value) Then lst.SubItems(a) = rs.Fields(a).Value End If Next rs.MoveNext

53

Page 54: Arc Objects IMP Examples

Wend End IfEnd Sub

Public Sub Fillrecordinlistview() ListView1.ColumnHeaders.Clear Set rst = New ADODB.RecordSet 'Set New connection Set cnnACC = New ADODB.Connection If rst.State = adStateOpen Then rst.Close End If Dim strDB, strConn As String strDB = CurDir & "\Northwind.mdb" 'String Connection with Database path String strConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & strDB & ";Persist Security Info=False" ' Open the connection cnnACC.Open strConn Dim sSQL As String vsRecordSource = ComboBox1.Text sSQL = "SELECT * FROM [" & vsRecordSource & " ]" rst.Open sSQL, cnnACC, adOpenDynamic, adLockOptimistic

Dim a As Long For a = 0 To rst.Fields.Count - 1 ListView1.ColumnHeaders.Add , , rst.Fields(a).Name Next Call FillListViewFromExcel(ListView1, rst, 0) End SubPublic Sub populateListBoxWithTableNames() Dim strDB, strConn As String 'Set New connection Set cnnACC = New ADODB.Connection 'String Database Path strDB = CurDir & "\Northwind.mdb"

strConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & strDB & ";Persist Security Info=False" ' Open the connection cnnACC.Open strConn 'Set new ADOX CAtalog Set adoCat = New ADOX.Catalog 'Allow active connection to the opened connection to enable use of the catalog adoCat.ActiveConnection = cnnACC 'Clear the Userform list box to refresh tables ComboBox1.Clear For Each adoTbl In adoCat.Tables

54

Page 55: Arc Objects IMP Examples

If Left(adoTbl.Name, 4) <> "MSys" Then ComboBox1.AddItem adoTbl.Name If ComboBox1.ListCount > 1 Then ComboBox1.ListIndex = 0 End If Next adoTbl 'Clear Memory Set cnnACC = Nothing: Set adoCat = Nothing End Sub

Private Sub CommandButton1_Click()

Dim pDoc As IMxDocument Dim pMap As IStandaloneTableCollection Dim pTable As ITable Set pDoc = ThisDocument Set pMap = pDoc.FocusMap

Dim pTableCollection As IStandaloneTableCollection Dim pStAloneTab As IStandaloneTable Set pTableCollection = pMap Dim i As Integer For i = 0 To pTableCollection.StandaloneTableCount - 1 If UCase(pTableCollection.StandaloneTable(i).Name) = UCase(ComboBox1.Text) Then Set pStAloneTab = pTableCollection.StandaloneTable(i) Dim pDataset As IDataset Set pDataset = pStAloneTab.Table

Exit For End If Next If pDataset Is Nothing Then MsgBox "The table was not found" Exit Sub End If Dim pDSName As IDatasetName Set pDSName = pDataset.FullName ' case we are creating a dbf file in c:\temp Dim pWkSpFactory As IWorkspaceFactory Dim pWkSp As IWorkspace Dim pWkSpDS As IDataset Dim pWkSpName As IWorkspaceName Dim pOutDSName As IDatasetName

55

Page 56: Arc Objects IMP Examples

Dim Path As String Path = CurDir Set pWkSpFactory = New ShapefileWorkspaceFactory Set pWkSp = pWkSpFactory.OpenFromFile(Path, 0) Set pWkSpDS = pWkSp Set pWkSpName = pWkSpDS.FullName Set pOutDSName = New TableName pOutDSName.Name = "ExpSample1" Set pOutDSName.WorkspaceName = pWkSpName 'Check the tables collection to see if the table exists in the map document Dim pStandAloneTableCollection As IStandaloneTableCollection Set pStandAloneTableCollection = pMap Dim j As Integer Dim pStandAloneTable As IStandaloneTable For j = 0 To pStandAloneTableCollection.StandaloneTableCount - 1 If TypeOf pStandAloneTableCollection.StandaloneTable(j) Is IStandaloneTable Then If pStandAloneTableCollection.StandaloneTable(j).Name = sNewTableName Then Set pStandAloneTable = pStandAloneTableCollection.StandaloneTable(j) pStandAloneTableCollection.RemoveStandaloneTable pStandAloneTable End If End If Next j 'next table 'Test to see if temp table already exists: if yes, delete it. Dim pED As IEnumDataset Set pED = pWkSp.Datasets(esriDTTable)

Dim pDS As IDataset Set pDS = pED.Next Do Until pDS Is Nothing Debug.Print pDS.Name If pDS.Name = "ExpSample1" Then pDS.Delete Exit Do End If Set pDS = pED.Next Loop 'Check to see if the dbf file already exists If Dir$(Path & "\" & "ExpSample1" & ".dbf") <> "" Then Kill Path & "\" & "ExpSample1" & ".dbf" End If Dim pExpOp As IExportOperation Set pExpOp = New ExportOperation pExpOp.ExportTable pDSName, Nothing, Nothing, pOutDSName, Application.hWnd '******************************************'Procedure to add a dbf table to the map'****************************************** Dim pFact As IWorkspaceFactory Dim pWorkspace As IWorkspace Dim pFeatws As IFeatureWorkspace ' Dim pTable As ITable Set pFact = New ShapefileWorkspaceFactory Dim strOpenPath As String Dim strOpenTable As String Dim strRev As String

56

Page 57: Arc Objects IMP Examples

Set pWorkspace = pFact.OpenFromFile(Path, 0) Set pFeatws = pWorkspace Set pTable = pFeatws.OpenTable("ExpSample1") Add_Table_TOC pTable

Exit SubEH: MsgBox Err.Number & " " & Err.Description

End SubPrivate Sub Add_Table_TOC(pTable As ITable)'****************************************************************'Procedure to add the table to Table of Contents of the Map.'**************************************************************** Dim pDoc As IMxDocument Dim pMap As IMap Dim intCol As Integer Dim blnExists As Boolean Set pDoc = ThisDocument Set pMap = pDoc.FocusMap' Create a new standalone table and add it' to the collection of the focus map Dim pStTab As IStandaloneTable Set pStTab = New StandaloneTable Set pStTab.Table = pTable Dim pStTabColl As IStandaloneTableCollection Set pStTabColl = pMap For intCol = 0 To pStTabColl.StandaloneTableCount - 1 If pStTabColl.StandaloneTable(intCol).Name = pStTab.Name Then blnExists = True Exit For End If Next If blnExists = False Then ' add the table MsgBox "Successfuly Export to Dbf. Now Added on map", vbInformation Unload Me pStTabColl.AddStandaloneTable pStTab End If' Refresh the TOC pDoc.UpdateContents Set pDoc = Nothing Set pMap = Nothing Set pStTab = Nothing Set pStTabColl = Nothing Set pNewTable = Nothing Set pName = Nothing Set pDS = Nothing Set pExpOp = Nothing

Set pDataset = Nothing Set pDSName = Nothing Set pDataset = Nothing Set pWkSpFactory = Nothing Set pWkSp = Nothing Set pWkSpDS = Nothing Set pWkSpName = Nothing Set pOutDSName = Nothing Set pDSName = Nothing

57

Page 58: Arc Objects IMP Examples

Set pActiveView = Nothing Set pSelItem = Nothing Set pStAloneTab = Nothing End Sub

Private Sub UserForm_Click()

End Sub

Private Sub UserForm_Initialize()'Loop through the standalone tables in a mapDim pDoc As IMxDocumentDim pMap As IMapDim pStandAloneTableCollection As IStandaloneTableCollectionDim pStandAloneTable As IStandaloneTableDim pTable As ITable

'Get the current map from the documentSet pDoc = ThisDocumentSet pMap = pDoc.FocusMap 'Get the table collection from the mapComboBox1.ClearSet pStandAloneTableCollection = pMapFor i = 0 To pStandAloneTableCollection.StandaloneTableCount - 1 Set pStandAloneTable = pStandAloneTableCollection.StandaloneTable(i) ComboBox1.AddItem pStandAloneTable.NameNextIf ComboBox1.ListCount > 0 Then ComboBox1.ListIndex = 0End Sub

'Private Sub CalcCentroid_Click()' This script will add a new field for the X and Y coordinate of a polygon feature layer' and insert the centroid X and Y coordinates' The script was written by Andrew Bradley on 16th January 2007 in ArcGIS 9.0' Please feel free to use this script at your discretion' Enjoy GIS, Andy Bradley! =), Hampshire England, [email protected]

'AB - Check the user meant to run the script and that the selected file is the one they want to work withAnswer = MsgBox("Do you want to work with the selected layer?", vbYesNo, "Are you sure?")If Answer = vbNo Then Exit SubEnd If

Dim pMxDoc As IMxDocumentSet pMxDoc = ThisDocumentDim pMap As IMapSet pMap = pMxDoc.FocusMapDim pFeatureLayer As IFeatureLayer

'AB - Ensure the layer is a feature layerIf pMxDoc.SelectedLayer Is Nothing Then MsgBox "No Layer is Selected, you must select a layer", vbCritical, "Select a layer" Exit Sub ElseIf Not TypeOf pMxDoc.SelectedLayer Is IFeatureLayer Then MsgBox "The Selected layer is not a feature layer", vbCritical, "Feature layer" Exit SubEnd If

Set pFeatureLayer = pMxDoc.SelectedLayer

58

Page 59: Arc Objects IMP Examples

Dim pFeatureClass As IFeatureClassSet pFeatureClass = pFeatureLayer.FeatureClass

'AB - Ensure the layer is of a polygon typeIf pFeatureClass.ShapeType <> esriGeometryPolygon Then MsgBox "The Feature Layer you have selected must be a polygon layer", vbCritical, "Error - not Polygon" Exit SubEnd If

Dim pFieldEdit As IFieldEditDim strXCoord As StringDim strYCoord As String'AB - Set field names for the X and Y coordinatesstrXCoord = "X_COORD"strYCoord = "Y_COORD"

'AB - If the field for the X coordinate does not exist then make oneIf pFeatureClass.FindField(strXCoord) = -1 Then Set pFieldEdit = New Field pFieldEdit.Type = esriFieldTypeDouble pFieldEdit.Name = strXCoord pFeatureClass.AddField pFieldEditEnd If'AB - If the field for the Y coordinate does not exist then make oneIf pFeatureClass.FindField(strYCoord) = -1 Then Set pFieldEdit = New Field pFieldEdit.Type = esriFieldTypeDouble pFieldEdit.Name = strYCoord pFeatureClass.AddField pFieldEditEnd If

'AB - Set a feature cursor to look at all the features in the layerDim pFeatureCursor As IFeatureCursorSet pFeatureCursor = pFeatureClass.Search(Nothing, False)

Dim pFeature As IFeatureDim pArea As IAreaDim x As DoubleDim y As Double'Dim pfield As IField'Dim pfields As IFieldsDim pFieldNumberX As LongDim pFieldNumberY As LongDim i As IntegerDim intCount As Long

'AB - Find the field numbers for the 2 coordinate fieldspFieldNumberX = pFeatureClass.FindField(strXCoord)pFieldNumberY = pFeatureClass.FindField(strYCoord)intCount = pFeatureClass.FeatureCount(Nothing)

'AB - Warn user they are about to run process and inform user of feature countAnswer = MsgBox("There are " & intCount & " features" & vbNewLine _ & "Press Yes to Continue or No to Cancel", vbYesNo, "Run Script?")If Answer = vbNo Then Exit SubEnd If

'AB - Find centroids and update features attributesFor i = 0 To intCount - 1 Set pFeature = pFeatureCursor.NextFeature Set pArea = pFeature.Shape

59

Page 60: Arc Objects IMP Examples

x = pArea.Centroid.x pFeature.Value(pFieldNumberX) = x y = pArea.Centroid.y pFeature.Value(pFieldNumberY) = y pFeature.StoreNext'AB - Tell user script has finishedMsgBox "Job Finished!", vbInformation, "Finished"'End Sub

Add X and Y coordinates of features to Attribute Table

Public Sub addxy() Dim thedocument As IMxDocumentSet thedocument = ThisDocumentDim thelay As ILayerSet thelay = thedocument.SelectedLayer

If thelay Is Nothing ThenMsgBox "Select a single point layer or point shapefile"Exit SubEnd If

Dim thelayer As IFeatureLayerSet thelayer = thelayDim theFC As IFeatureClassSet theFC = thelayer.FeatureClass

If TypeOf theFC Is ICoverageFeatureClass Or theFC.ShapeType <> esriGeometryPoint ThenMsgBox "Select a single point layer or point shapefile"Exit SubEnd If

Dim xfield As IFieldEditDim yfield As IFieldEditSet xfield = New FieldSet yfield = New Field With xfield.Type = 3.name = "XFIELD"End With With yfield.Type = 3.name = "YFIELD"End With

theFC.AddField xfieldtheFC.AddField yfield

'Dim thequeryfilter As IQueryFilter'Set thequeryfilter = New QueryFilter'thequeryfilter.WhereClause = ""

Dim thefeaturecursor As IFeatureCursorSet thefeaturecursor = theFC.Search(Nothing, False) Dim thefeature As IFeatureSet thefeature = thefeaturecursor.NextFeature

60

Page 61: Arc Objects IMP Examples

While Not thefeature Is Nothing Dim theenvelope As IEnvelopeSet theenvelope = thefeature.Extent Dim xcoor As Doublexcoor = theenvelope.XMaxDim ycoor As Doubleycoor = theenvelope.YMax Dim indexX As LongindexX = theFC.FindField("XFIELD") Dim indexY As LongindexY = theFC.FindField("YFIELD") thefeature.Value(indexX) = xcoor'thefeature.Storethefeature.Value(indexY) = ycoorthefeature.Store Set thefeature = thefeaturecursor.NextFeature Wend End Sub

Sub AddXY2Att() 'The program adds x and y coordinates to the selected polygon or point feature layer. 'If the field XCOORD or YCOORD does not exist in the layer, the program will add the 'field to the layer attribute table. 'The coordinates that are added to the attribute table is in same coordinate and projection 'as the one sets in the Data Frame Properties. In that case, user can control what coordinate 'and projection of the x and y will be in the attribute table. 'Program by XY at ISIS Center, California State University, Fresno

Dim pMxDoc As IMxDocument Dim pMap As IMap Dim pUnknown As IUnknown Dim pFeatLayer As IFeatureLayer Dim pFeatClass As IFeatureClass Set pMxDoc = ThisDocument Set pMap = pMxDoc.FocusMap Set pUnknown = pMxDoc.SelectedLayer If pUnknown Is Nothing Then MsgBox "No layer selected." & vbCrLf _ & "Please select a point or polygon feature layer from the TOC." Exit Sub End If 'get spatial reference information of the map frame Dim pSpRef As ISpatialReference Set pSpRef = pMap.SpatialReference

61

Page 62: Arc Objects IMP Examples

If TypeOf pUnknown Is IFeatureLayer Then Set pFeatLayer = pUnknown Set pFeatClass = pFeatLayer.FeatureClass If ((pFeatClass.ShapeType <> 1) And (pFeatClass.ShapeType <> 4)) Then MsgBox "Point or polygon feature layer only, please." Exit Sub End If 'get an exclusive schema lock on the dataset Dim pSchemalock As ISchemaLock Set pSchemalock = pFeatClass pSchemalock.ChangeSchemaLock esriExclusiveSchemaLock 'check if fields named XCOORD and YCOORD exist Dim pFieldEdit As IFieldEdit If pFeatClass.FindField("XCOORD") = -1 Then Set pFieldEdit = New esriCore.Field With pFieldEdit .Type = esriFieldTypeDouble .Name = "XCOORD" End With pFeatClass.AddField pFieldEdit End If If pFeatClass.FindField("YCOORD") = -1 Then Set pFieldEdit = New esriCore.Field With pFieldEdit .Type = esriFieldTypeDouble .Name = "YCOORD" End With pFeatClass.AddField pFieldEdit End If 'edit session needed? Dim pDataset As IDataset Dim pWSEdit As IWorkspaceEdit Dim bBypassEditSession As Boolean Set pDataset = pFeatClass Set pWSEdit = pDataset.Workspace bBypassEditSession = CanEditWOEditSession(pFeatClass) If Not bBypassEditSession Then pWSEdit.StartEditing False pWSEdit.StartEditOperation End If 'can bypass STORE? Dim pObjectClassInfo2 As IObjectClassInfo2 Dim pQueryFilter As IQueryFilter Set pObjectClassInfo2 = pFeatClass If pObjectClassInfo2.CanBypassStoreMethod Then 'MsgBox "Yes, can bypass STORE method." Set pQueryFilter = New QueryFilter pQueryFilter.SubFields = pFeatClass.ShapeFieldName & "," & "XCOORD, YCOORD" End If

62

Page 63: Arc Objects IMP Examples

Dim pFeatCursor As IFeatureCursor Dim pFeature As IFeature Dim pPoint As IPoint Dim pFeatGeo As IGeometry Dim pFeatSR As ISpatialReference Dim pShape As IGeometry Set pPoint = New Point Set pFeatCursor = pFeatClass.Update(pQueryFilter, False) Set pFeature = pFeatCursor.NextFeature 'get field indeces of XCOORD and YCOORD Dim lXField As Long Dim lYField As Long lXField = pFeatClass.FindField("XCOORD") lYField = pFeatClass.FindField("YCOORD") 'get spatial reference of the feature class Set pFeatGeo = pFeature.Shape Set pFeatSR = pFeatGeo.SpatialReference 'show progress Dim pSBar As IStatusBar Dim pProg As IStepProgressor Dim lNumFeat As Long Dim dInterval As Double Dim i Set pSBar = StatusBar Set pProg = pSBar.ProgressBar lNumFeat = pFeatClass.FeatureCount(Nothing) dInterval = lNumFeat / 100 pProg.MinRange = 1 pProg.MaxRange = lNumFeat pProg.StepValue = dInterval i = 1 While Not pFeature Is Nothing pProg.Position = i pProg.Message = "Processing record " & Str(i) pProg.Step pProg.Show Dim dblX As Double Dim dblY As Double Select Case pFeatClass.ShapeType Case 1 Set pPoint = pFeature.Shape Case 4 Dim pArea As IArea Set pArea = pFeature.Shape 'substitute LabelPoint to Centroid for true centroid of a polygon pPoint.PutCoords pArea.LabelPoint.X, pArea.LabelPoint.Y Case Else End Select

63

Page 64: Arc Objects IMP Examples

Set pShape = pPoint Set pShape.SpatialReference = pFeatSR If pFeatSR.Name <> pSpRef.Name Then 'project the feature layer coordinate system to the map frame corrdinate system pShape.Project pSpRef End If dblX = pPoint.X dblY = pPoint.Y pFeature.Value(lXField) = dblX pFeature.Value(lYField) = dblY pFeatCursor.UpdateFeature pFeature Set pFeature = pFeatCursor.NextFeature i = i + 1 Wend Set pFeatCursor = Nothing If pWSEdit.IsBeingEdited Then pWSEdit.StopEditOperation pWSEdit.StopEditing True End If MsgBox "Job done!" pProg.Hide Else MsgBox "Selected layer is not a feature layer." Exit Sub End IfEnd Sub

Private Function CanEditWOEditSession(pTable As ITable) As Boolean Dim pVersionedObject As IVersionedObject Dim pObjClassInfo2 As IObjectClassInfo2 Dim bolVersioned As Boolean Dim bolEditable As Boolean If Not TypeOf pTable Is IVersionedObject Then bolVersioned = False Else bolVersioned = True End If Set pObjClassInfo2 = pTable bolEditable = pObjClassInfo2.CanBypassEditSession If bolEditable And Not bolVersioned Then CanEditWOEditSession = True Else CanEditWOEditSession = False End IfEnd Function

Public Sub AddShapePointXY() ' ' This function takes the currently selected Point shape file, and add ' two fields of Xcoord and Ycoord that give the coordante of point. ' ' Xiaodong ZHAO, Kyushu University, Fukuoka, Japan

64

Page 65: Arc Objects IMP Examples

' [email protected] ' Jan 31, 2002 Dim pMxdoc As IMxDocument Set pMxdoc = ThisDocument If Not TypeOf pMxdoc.ActiveView Is IMap Then MsgBox "A Map must be active!" Exit Sub End If Dim pFLayer As IFeatureLayer Dim pFClass As IFeatureClass Set pFLayer = pMxdoc.SelectedLayer If pFLayer Is Nothing Then MsgBox "Select a single point shapefile!" Exit Sub End If Set pFClass = pFLayer.FeatureClass If pFClass.ShapeType <> esriGeometryPoint Then MsgBox "Select a single point shapefile!" Exit Sub End If Dim indexX As Long indexX = pFClass.FindField("Xcoord") If indexX < 0 Then 'If there is no the field of Xcoord, indexxX=-1 Dim pFieldx As IFieldEdit Set pFieldx = New Field With pFieldx .Type = esriFieldTypeDouble .Name = "Xcoord" End With pFClass.AddField pFieldx End If Dim indexY As Long indexY = pFClass.FindField("Ycoord") If indexY < 0 Then 'If there is no the field of Ycoord, indexxX=-1 Dim pFieldy As IFieldEdit Set pFieldy = New Field With pFieldy .Type = esriFieldTypeDouble .Name = "Ycoord" End With pFClass.AddField pFieldy End If indexX = pFClass.FindField("Xcoord") indexY = pFClass.FindField("Ycoord") Dim pFCursor As IFeatureCursor Set pFCursor = pFClass.Search(Nothing, False) Dim pFeature As IFeature Set pFeature = pFCursor.NextFeature Dim pShape As IGeometry Dim pPoint As IPoint

65

Page 66: Arc Objects IMP Examples

Dim xcoor As Double Dim ycoor As Double While Not pFeature Is Nothing Set pShape = pFeature.Shape Set pPoint = pShape xcoor = pPoint.X ycoor = pPoint.Y pFeature.Value(indexX) = xcoor pFeature.Value(indexY) = ycoor pFeature.Store Set pFeature = pFCursor.NextFeature Wend End Sub

Public Sub SelectableTab()

'Add the Selectable Layers tab to the TOC. Copy this code to the Normal.mxt -> ThisDocument'to make it available by default.

Dim pMxDoc As IMxDocumentSet pMxDoc = ThisDocumentDim i As IntegerFor i = 0 To pMxDoc.ContentsViewCount - 1 If pMxDoc.ContentsView(i).Name = "Selection" Then pMxDoc.ContentsView(i).Visible = True pMxDoc.UpdateContents Application.RefreshWindow End IfNext i

'Don't prompt to save the MXD if this is the only changeDim pDocDirty As IDocumentDirty2Set pDocDirty = ThisDocumentpDocDirty.SetClean

End Sub

Private Function MxDocument_NewDocument() As Boolean

'Add the tab when creating a new MXDCall SelectableTab

End Function

Private Function MxDocument_OpenDocument() As Boolean

'Add the tab when opening an existing MXDCall SelectableTab

End Function

66

Page 67: Arc Objects IMP Examples

Attribute VB_Name = "anno2polyline"Public Declare Function GetEnvironmentVariable Lib "kernel32" Alias _"GetEnvironmentVariableA" (ByVal lpName As String, ByVal lpBuffer As String, _ByVal nSize As Long) As Long

Public Sub ConvertAnno2Line(pMap As IMap, pFl As IFeatureLayer)

On Error GoTo myEH ' This macro convert a ArcInfo annotation coverage ' to ESRI Shapefile with the same fields that annotation coverage ' the Shapefile Geometry is Polyline, that store the orientation ' of texts ' The Selected Layer in the Table of contents should be the annotation coverage Dim pNewFL As IFeatureLayer Dim pActiveView As IActiveView Dim pFC As IFeatureClass Dim pfields As IFields Dim pField As IField Dim pClone As IClone Dim pnewFC As IFeatureClass Dim pFW As IFeatureWorkspace Dim pWSf As IWorkspaceFactory Dim pFCursor As IFeatureCursor Dim pFeature As IFeature Dim pnewFeature As IFeature Dim pProDiaFac As IProgressDialogFactory Dim pProgDialog As IProgressDialog2 Dim pStpPro As IStepProgressor Dim pTrackCancel As ITrackCancel Set pFC = pFl.FeatureClass Set pfields = pFC.Fields Set pClone = pfields Set pfields = pClone.Clone Dim sPath As String Dim lSize As Long Dim sNameFC As String sPath = String(255, 0) lSize = GetEnvironmentVariable("Temp", sPath, Len(sPath)) If lSize = 0 Then sPath = "C:" End If sPath = Left(sPath, lSize) sname = InputBox("input the name of feature class to create") If Len(Trim(sname)) = 0 Then Exit Sub Set pWSf = New ShapefileWorkspaceFactory Set pFW = pWSf.OpenFromFile(sPath, 0) Set pnewFC = pFW.CreateFeatureClass(Trim(sname), pfields, Nothing, _ Nothing, esriFTSimple, "Shape", "") Set pFCursor = pFC.Search(Nothing, False) Set pFeature = pFCursor.NextFeature

67

Page 68: Arc Objects IMP Examples

Dim lFields As Long Dim i As Long, k As Long, t As Long Dim pPolyline As IPolyline Dim pTopoOp As ITopologicalOperator Dim lNumFeat As Long Dim pNewFCursor As IFeatureCursor Dim pNewFBuffer As IFeatureBuffer lFields = pfields.FieldCount lNumFeat = pFC.FeatureCount(Nothing) Set pProDiaFac = New ProgressDialogFactory Set pStpPro = pProDiaFac.Create(pTrackCancel, 0) With pStpPro .MinRange = 1 .MaxRange = lNumFeat .StepValue = 1 End With Set pProgDialog = pStpPro With pProgDialog .Animation = esriProgressGlobe .Title = "Annotation to polyline" End With k = 1 t = 1 Set pNewFCursor = pnewFC.Insert(True) Do While Not pFeature Is Nothing pStpPro.Message = "Converting feature " & k & " of " & lNumFeat pStpPro.Step Set pNewFBuffer = pnewFC.CreateFeatureBuffer 'Set pnewFeature = pnewFC.CreateFeature For i = 0 To lFields - 1 Set pField = pfields.Field(i) If Not ((pField.Type = esriFieldTypeGeometry) Or (pField.Type = esriFieldTypeOID)) Then pNewFBuffer.Value(i) = pFeature.Value(i) ElseIf pField.Type = esriFieldTypeGeometry Then Set pPolyline = pFeature.ShapeCopy Set pNewFBuffer.Shape = pPolyline End If Next i 'pnewFeature.Store pNewFCursor.InsertFeature pNewFBuffer Set pFeature = pFCursor.NextFeature k = k + 1 t = t + 1 If t = 1000 Then pNewFCursor.Flush t = 1 End If Loop pNewFCursor.Flush pProgDialog.HideDialog Set pNewFL = New FeatureLayer Set pNewFL.FeatureClass = pnewFC

68

Page 69: Arc Objects IMP Examples

pNewFL.Name = pnewFC.AliasName pMap.AddLayer pNewFL Set pActiveView = pMap pActiveView.Refresh MsgBox "Finish"Exit Sub

myEH: If Err.Number = -2147220653 Then MsgBox "the layer exist, delete the layer o change the shapefile name" Exit Sub End If

MsgBox Err.Number & " " & Err.Description End Sub

This code brings in label symbology for label classes from a .lyr file and applies it to a selected Feature Class, Shapefile or Coverage in ArcMap.

To use the code:

1.Add a new UiButtonControl to ArcMap (see Create a new UIButtonControl.doc)

2. After you drag the button to the toolbar, right-click it and select View Source then paste the code in the attached text filed called Buttoncode.txt into the UiButtonControl1_Click event(Between the lines:Private Sub UIButtonControl1_Click() andEnd Sub )

3.Close the Visual Basic Editor

4. Add a Feature Class, Shapefile or Coverage to ArcMap.

5. Select (click) the layer (Feature Class, Shapefile or Coverage) you want to create labels for in the Table of Contents

6. Click the UiButtonControl

7. You will be prompted to select the .lyr file from which you would like to import label symbology.

Note: This code brings in only the LABEL symbology.

private sub lable_display()

Dim pGxFile As IGxFile Dim pGFLayer As IGeoFeatureLayer Dim pGxLayer As IGxLayer Dim pGxDialog As IGxDialog Dim pGxObjFilter As IGxObjectFilter Dim pEnumGxObj As IEnumGxObject Dim pAnnoLayerPropsColl As IAnnotateLayerPropertiesCollection Dim pGxObj As IGxObject Dim pMxDoc As IMxDocument Set pMxDoc = ThisDocument If pMxDoc.SelectedLayer Is Nothing Then MsgBox "Please select feature class to label with .lyr file label classes" Exit Sub

69

Page 70: Arc Objects IMP Examples

End If Set pGxDialog = New GxDialog Set pGxObjFilter = New GxFilterLayers Set pGxDialog.ObjectFilter = pGxObjFilter pGxDialog.Title = "Select Layer(.lyr) file" pGxDialog.ButtonCaption = "Apply Labels"

If pGxDialog.DoModalOpen(0, pEnumGxObj) Then Set pGxObj = pEnumGxObj.Next Set pGxLayer = pGxObj Else Exit Sub End If Set pGFLayer = pGxLayer.Layer Set pAnnoLayerPropsColl = pGFLayer.AnnotationProperties

'Apply label classes to selected layer in arcmap Set pGFLayer = pMxDoc.SelectedLayer pGFLayer.AnnotationProperties = pAnnoLayerPropsColl pGFLayer.DisplayAnnotation = True pMxDoc.ActiveView.Refresh pMxDoc.CurrentContentsView.Refresh pGFLayerEnd sub

'**' Write available printer codes and printer names to a text file'' @instructions Define your current printer within ArcMap first (File > Page and Print Setup...)'' Copy this code into the ThisDocument window within ArcMap's VBA window' Tools > Macros > Visual Basic Editor' Project > ArcMap Objects > ThisDocument'' Once the code has been pasted into the window, press the run button'' You can optionally assign this routine to a customised UIButton control''*

'**' @global sFileName Log file to create'*Private Const sFileName As String = "C:\Temp\PrinterSettings.log"

'**' Method to Log printer settings to text file'''*Public Sub LogPrinterSettings()

Dim pMxApp As IMxApplication Dim pPrinter As IPrinter Dim fso As Object, f As Object Dim pEnumTypeInfo As IEnumNamedID

70

Page 71: Arc Objects IMP Examples

Dim lFormID(100) As Long, l As Long Dim sName As String, sCode As String

On Error GoTo ErrHandler

'Get Printer Set pMxApp = Application Set pPrinter = pMxApp.Printer 'Open/Create log file Set fso = CreateObject("Scripting.FileSystemObject") Set f = fso.CreateTextFile(sFileName, True) ' overwrites existing file 'Temp code to write paper sizes to file f.WriteLine ("Available Printer Sizes for " & pPrinter.DriverName & ":") f.WriteLine ("")

Set pEnumTypeInfo = pPrinter.Paper.Forms pEnumTypeInfo.Reset

lFormID(l) = pEnumTypeInfo.Next(sName) Do Until lFormID(l) = 0 sCode = CStr(lFormID(l)) While Len(sCode) < 4 sCode = sCode & " " Wend f.WriteLine (sCode & ": " & sName) lFormID(l) = pEnumTypeInfo.Next(sName) Loop

'Close temp log file f.Close Set f = Nothing

MsgBox "Settings logged to file:" & vbCrLf & sFileName, vbInformation GoTo Cleanup ErrHandler: MsgBox "Error: " & Err.Description, vbCriticalCleanup: If Not f Is Nothing Then f.Close Set f = Nothing End If Set pEnumTypeInfo = Nothing Set pPrinter = Nothing Set pMxApp = Nothing End Sub

'-- Create two UIButtonControls'-- Attach the two codesets to the appropriate button'-- Sends results to message box

71

Page 72: Arc Objects IMP Examples

Option Explicit

'-- Graphics 1+ works in data view and tells user to switch to data viewPrivate Sub AreaCalcGraphplf_Click() Dim pDoc As IMxDocumentSet pDoc = ThisDocumentDim pAV As IActiveViewSet pAV = pDoc.ActiveViewDim pGC As IGraphicsContainerSelectSet pGC = pAV.GraphicsContainerDim pElem As IElementDim pPoly As IPolygonDim pAcres As Double, pFeet As Double, pMeters As DoubleDim i As Integer, Looper As Integeri = pGC.ElementSelectionCount

'-- Make sure element is selectedIf i = 0 Then MsgBox "Please select one or more graphics" Exit SubEnd If

'-- Check to make sure in Data View for graphics http://forums.esri.com/thread.asp?c=93&f=992&t=61739#157733If TypeOf pDoc.ActiveView Is IPageLayout Then MsgBox "Switch to Data View to calc Ac" Exit SubEnd If

Dim l As Long, dArea As Double 'http://forums.esri.com/Thread.asp?c=93&f=982&t=62974#163462For l = 0 To pGC.ElementSelectionCount - 1 If TypeOf pGC.SelectedElement(l).Geometry Is IArea Then Dim pArea As IArea Set pArea = pGC.SelectedElement(l).Geometry dArea = dArea + pArea.Area End IfNext l

pMeters = dAreapFeet = pMeters * 10.76391042pAcres = pFeet / 43560MsgBox "Acreage = " & Format(pAcres, "##,##0")End Sub

Private Function AreaCalcGraphplf_ToolTip() As String AreaCalcGraphplf_ToolTip = "Calc Area Graphics(Ac)"End Function

'-- Shapes 1+ works in layout or data view'-- tested on gdb, shp, PC A/I covs should work on allPrivate Sub AreaCalcplf_Click() 'http://forums.esri.com/thread.asp?c=93&f=982&t=42209#104695Dim pMxDoc As IMxDocumentDim pArea As IArea

72

Page 73: Arc Objects IMP Examples

Dim pAcres As Double, pFeet As Double, pMeters As DoubleDim i As Integer, Looper As IntegerDim pPoly As IFeatureDim pMap As IMapDim pFSelection As IEnumFeatureDim pActiveView As IActiveViewDim pContentsView As IContentsView

Set pMxDoc = ThisDocumentSet pMap = pMxDoc.FocusMapSet pActiveView = pMapSet pContentsView = pMxDoc.CurrentContentsViewSet pFSelection = pMap.FeatureSelectioni = pMap.SelectionCount

'-- Make sure element is selectedIf i = 0 Then MsgBox "Please select one or more shapes" Exit SubEnd If

Do Until Looper = i Set pPoly = pFSelection.Next Looper = Looper + 1 Set pArea = pPoly.Shape pMeters = (pMeters + pArea.Area)Loop

pFeet = pMeters * 10.76391042pAcres = pFeet / 43560MsgBox "Acreage = " & Format(pAcres, "##,##0")End Sub

Private Function AreaCalcplf_ToolTip() As String AreaCalcplf_ToolTip = "Calc Area Shapes(Ac)"End Function

AREA CALLUCULATION

Dim pMxDoc As IMxDocument Set pMxDoc = ThisDocument Dim pMap As IMap Set pMap = pMxDoc.FocusMap

Dim pFLayer As IFeatureLayer Dim pFClass As IFeatureClass Set pFLayer = pMap.Layer(0) Set pFClass = pFLayer.FeatureClass Dim pFields As IFields Set pFields = pFClass.fields Dim intArea As Integer intArea = pFields.FindField("NewArea")

73

Page 74: Arc Objects IMP Examples

If intArea = -1 Then Dim pFieldEdit As IFieldEdit Set pFieldEdit = New Field pFieldEdit.Name = "NewArea" pFieldEdit.Type = esriFieldTypeDouble pFClass.AddField pFieldEdit End If

Dim pCalc As ICalculator Set pCalc = New Calculator

Dim pCursor As ICursor Set pCursor = pFClass.Update(Nothing, True)

Set pCalc.Cursor = pCursor With pCalc .PreExpression = "Dim dblArea As Double" & vbNewLine & _ "Dim pArea as IArea" & vbNewLine & _ "Set pArea = [shape]" & vbNewLine & _ "dblArea = pArea.Area" .Expression = "dblArea" .Field = "NewArea" End With pCalc.Calculate

Public Sub Ascii2PointFeatureClass(strAsciiFullFilename As String, pInFeatureClass As IFeatureClass, Optional strFieldName As String) ''Create a point feature class from a ascii file including the coordinates of x,y and z '' ''strAsciiFullFilename is the filename of ascii file with folder path, '' such as "e:\project\test\xyz.txt". ''strFieldName is field name that will be created in the feature class depending on accii file '' For example strFieldName = "Elev" '' ''Example call: Ascii2PointFeatureClass "e:\project\test\xyz.txt",pFeatureClass,"Elev" '' '' Xiaodong ZHAO, Kyushu University, Fukuoka, Japan '' [email protected] '' Mar 15, 2002 Const lgMaxPointNum As Long = 100 If strAsciiFulFilename = "" Then Exit Sub End If Dim xCoor(1 To lgMaxPointNum) As Single, yCoor(1 To lgMaxPointNum) As Single, zCoor(1 To lgMaxPointNum) As Single Dim iMaxNum As Long iMaxNum = 0

74

Page 75: Arc Objects IMP Examples

'Read Ascii file for the coordinates of x,y and z Open strAsciiFullFilename For Input As #1 Dim blnIsZValue As Boolean 'Boolean variable dealing with z value blnIsZValue = IIf(IsMissing(strFieldName) Or strFieldName = "", False, True) If blnIsZValue Then 'with z value While Not EOF(1) iMaxNum = iMaxNum + 1 Input #1, xCoor(iMaxNum), yCoor(iMaxNum), zCoor(iMaxNum) Wend Else 'Without z value While Not EOF(1) iMaxNum = iMaxNum + 1 Input #1, xCoor(iMaxNum), yCoor(iMaxNum) Wend End If Close #1 If blnIsZValue Then 'with z value Dim FieldIndex As Integer FieldIndex = pInFeatureClass.FindField(strFieldName) 'Skip adding a newfield if found If FieldIndex < 0 Then ' No find to add a newfield ' Prepare Fields for z value, dimmension as single Dim pFld As IFieldEdit Set pFld = New Field With pFld .Name = strFieldName 'Given by the optional parameter .Type = esriFieldTypeSingle .length = 10 End With ' Add field pInFeatureClass.AddField pFld End If ' Get field index FieldIndex = pInFeatureClass.FindField(strFieldName) If FieldIndex < 0 Then Exit Sub End If 'Use an insert cursor to load features,making loading simple features much quicker Dim pInsertFeatureBuffer As IFeatureBuffer Dim pInsertFeatureCursor As IFeatureCursor Dim NewFeatureCount As Long 'Counter for flushing the feature cursor Set pInsertFeatureCursor = pInFeatureClass.Insert(True) Set pInsertFeatureBuffer = pInFeatureClass.CreateFeatureBuffer 'Define a new point Dim pPoint As IPoint Set pPoint = New Point Dim i As Long

75

Page 76: Arc Objects IMP Examples

For i = 1 To iMaxNum With pPoint .x = xCoor(i) .y = xCoor(i) End With 'Add the Point feature's geometry to the feature buffer Set pInsertFeatureBuffer.Shape = pPoint If blnIsZValue Then 'Add z value to strFieldName field pInsertFeatureBuffer.Value(FieldIndex) = zCoor(i) End If 'Insert the feature into the cursor pInsertFeatureCursor.InsertFeature pInsertFeatureBuffer NewFeatureCount = NewFeatureCount + 1 'Flush the feature cursor every 100 features If NewFeatureCount = 100 Then pInsertFeatureCursor.Flush NewFeatureCount = 0 End If Next pInsertFeatureCursor.Flush 'Flush the cursor one last time End Sub

Public Sub Ascii2PointFeatureClassMultiFields(strAsciiFulFilename As String, pInFeatureClass As IFeatureClass, strFieldName() As String) ''Create a point feature class from a ascii file including the coordinates of x,y and z '' ''strAsciiFulFilename is the filename of ascii file with folder path, '' such as "e:\project\test\xyz.txt". ''strFieldName is an array of field names that will be created in the feature class depending on accii file '' For example strFieldName = "Elev" '' ''Example call: Ascii2PointFeatureClass "e:\project\test\xyz.txt",pFeatureClass,strFieldName '' '' Xiaodong ZHAO, Kyushu University, Fukuoka, Japan '' [email protected] '' Mar 15, 2002 Const lgMaxPointNum As Long = 100 Const intMaxFieldtNum As Long = 10 If strAsciiFulFilename = "" Then Exit Sub End If Dim lgLower As Long, lgUpper As Long lgLower = LBound(strFieldName) 'the smallest available dimension lgUpper = UBound(strFieldName) 'the largest available dimension

76

Page 77: Arc Objects IMP Examples

Dim xCoor(1 To lgMaxPointNum) As Single, yCoor(1 To lgMaxPointNum) As Single Dim FieldValue(1 To lgMaxPointNum, intMaxFieldtNum) As Single Dim iMaxNum As Long, i As Long 'ReDim FieldValue(1 To lgMaxPointNum, lgLower To lgUpper) As Single iMaxNum = 0 'Read Ascii file for the coordinates of x,y and z Open strAsciiFulFilename For Input As #1 While Not EOF(1) iMaxNum = iMaxNum + 1 'Read the coordinates of x,y Input #1, xCoor(iMaxNum), yCoor(iMaxNum) 'Read the field value For i = lgLower To lgUpper Input #1, FieldValue(iMaxNum, i) Next i Wend Close #1 Dim FieldIndex(intMaxFieldtNum) As Integer 'Loop for creating the fields For i = lgLower To lgUpper FieldIndex(i) = pInFeatureClass.FindField(strFieldName(i)) 'Skip adding a newfield if found If FieldIndex(i) < 0 Then ' No find to add a newfield ' Prepare Fields for z value, dimmension as single Dim pFld As IFieldEdit Set pFld = New Field With pFld .Name = strFieldName(i) 'Given by the optional parameter .Type = esriFieldTypeSingle .length = 10 End With ' Add field pInFeatureClass.AddField pFld End If ' Get field index FieldIndex(i) = pInFeatureClass.FindField(strFieldName(i)) If FieldIndex(i) < 0 Then MsgBox "Field:" & strFieldName(i) & "cannot be indexed!", vbExclamation Exit Sub End If Next i 'Use an insert cursor to load features,making loading simple features much quicker Dim pInsertFeatureBuffer As IFeatureBuffer Dim pInsertFeatureCursor As IFeatureCursor Dim NewFeatureCount As Long 'Counter for flushing the feature cursor Set pInsertFeatureCursor = pInFeatureClass.Insert(True) Set pInsertFeatureBuffer = pInFeatureClass.CreateFeatureBuffer

77

Page 78: Arc Objects IMP Examples

'Define a new point Dim pPoint As IPoint Set pPoint = New Point Dim j As Integer For i = 1 To iMaxNum With pPoint .x = xCoor(i) .y = xCoor(i) End With 'Add the Point feature's geometry to the feature buffer Set pInsertFeatureBuffer.Shape = pPoint 'Add field value to strFieldName field For j = lgLower To lgUpper pInsertFeatureBuffer.Value(FieldIndex(j)) = FieldValue(i, j) Next j 'Insert the feature into the cursor pInsertFeatureCursor.InsertFeature pInsertFeatureBuffer NewFeatureCount = NewFeatureCount + 1 'Flush the feature cursor every 100 features If NewFeatureCount = 100 Then pInsertFeatureCursor.Flush NewFeatureCount = 0 End If Next pInsertFeatureCursor.Flush 'Flush the cursor one last time End Sub

Public Sub Ascii2Point(strFilePath As String, strAsciiFilename As String, strShapeFilename As String) ''Create a point shapefile from a ascii file including the coordinates of x,y and z ''strFilePath is the folder that contains the ascii file and also shapefile will be created. '' For example strFilePath = "e:\project\test" ''strAsciiFilename is the filename of ascii file, such as "xyz.txt". ''strShapeFilename is name of shapefile that will be created in the folder of strFilePath. '' For example strShapeFilename = "MyPoint" without extension. '' ''Example call: Ascii2Point "e:\project\test","xyz.txt","MyPoint" '' '' Xiaodong ZHAO, Kyushu University, Fukuoka, Japan '' [email protected] '' Feb 20, 2002 Const strPeriod As String * 1 = "\" Const lgMaxPointNum As Long = 100 If strFilePath = "" Or strAsciiFilename = "" Or strShapeFilename = "" Then

78

Page 79: Arc Objects IMP Examples

Exit Sub End If Dim xCoor(1 To lgMaxPointNum) As Single, yCoor(1 To lgMaxPointNum) As Single, zCoor(1 To lgMaxPointNum) As Single Dim iMaxNum As Long Dim strFullAsciiFilename As String iMaxNum = 0 strFullAsciiFilename = strFilePath + strPeriod + strAsciiFilename 'Read Ascii file for the coordinates of x,y and z Open strFullAsciiFilename For Input As #1 While Not EOF(1) iMaxNum = iMaxNum + 1 Input #1, xCoor(iMaxNum), yCoor(iMaxNum), zCoor(iMaxNum) Wend Close #1 ' Prepare Fields for Shapefile Dim pXCoor As IFieldEdit Set pXCoor = New Field With pXCoor .Name = "XCoor" .Type = esriFieldTypeSingle End With Dim pYCoor As IFieldEdit Set pYCoor = New Field With pYCoor .Name = "YCoor" .Type = esriFieldTypeSingle End With Dim pZCoor As IFieldEdit Set pZCoor = New Field With pZCoor .Name = "ZCoor" .Type = esriFieldTypeSingle End With 'Call for createShapefile function to create a new point shapefile Dim pFClassOutput As IFeatureClass Set pFClassOutput = createShapefile(strFilePath, strShapeFilename, esriGeometryPoint) 'Add fields of xcoor, ycoor and zcoor pFClassOutput.AddField pXCoor pFClassOutput.AddField pYCoor pFClassOutput.AddField pZCoor ' Get indexes of xcoor, ycoor and zcoor Dim indexX As Long, indexY As Long, indexZ As Long indexX = pFClassOutput.FindField("XCoor") indexY = pFClassOutput.FindField("YCoor") indexZ = pFClassOutput.FindField("ZCoor") Dim indexShape As Long indexShape = pFClassOutput.FindField("shape") Dim pPoint As IPoint

79

Page 80: Arc Objects IMP Examples

Set pPoint = New Point Dim i As Long 'Use an insert cursor to load features,making loading simple features much quicker Dim pInsertFeatureBuffer As IFeatureBuffer Dim pInsertFeatureCursor As IFeatureCursor Set pInsertFeatureCursor = pFClassOutput.Insert(True) Set pInsertFeatureBuffer = pFClassOutput.CreateFeatureBuffer For i = 1 To iMaxNum With pPoint .x = xCoor(i) .y = yCoor(i) End With 'Add the Point feature's geometry to the feature buffer Set pInsertFeatureBuffer.Shape = pPoint pInsertFeatureBuffer.Value(indexX) = xCoor(i) pInsertFeatureBuffer.Value(indexY) = yCoor(i) pInsertFeatureBuffer.Value(indexZ) = zCoor(i) 'Insert the feature into the cursor pInsertFeatureCursor.InsertFeature pInsertFeatureBuffer Next pInsertFeatureCursor.Flush 'Flush the cursor one last timeEnd Sub

Public Function createShapefile(strFolder As String, strName As String, _ geomType As esriCore.esriGeometryType) As esriCore.IFeatureClass

'' Simple function to create a shapefile in the strFolder.'' Note: the name of the shapefile should not contain the .shp extension'''' Xiaodong ZHAO, Kyushu University, Fukuoka, Japan'' [email protected]'' Feb 18, 2002

Const strShapeFieldName As String = "Shape" On Error GoTo EH Set createShapefile = Nothing If strFolder = "" Then Exit Function ' Open the folder to contain the shapefile as a workspace Dim pFWS As IFeatureWorkspace Dim pWorkspaceFactory As IWorkspaceFactory Set pWorkspaceFactory = New ShapefileWorkspaceFactory Set pFWS = pWorkspaceFactory.OpenFromFile(strFolder, 0) ' Set up a simple fields collection Dim pFields As IFields Dim pFieldsEdit As IFieldsEdit

80

Page 81: Arc Objects IMP Examples

Set pFields = New esriCore.Fields Set pFieldsEdit = pFields Dim pField As IField Dim pFieldEdit As IFieldEdit ' Make the shape field ' it will need a geometry definition, with a spatial reference Set pField = New esriCore.Field Set pFieldEdit = pField pFieldEdit.Name = strShapeFieldName pFieldEdit.Type = esriFieldTypeGeometry Dim pGeomDef As IGeometryDef Dim pGeomDefEdit As IGeometryDefEdit Set pGeomDef = New GeometryDef Set pGeomDefEdit = pGeomDef With pGeomDefEdit .GeometryType = geomType Set .SpatialReference = New UnknownCoordinateSystem End With Set pFieldEdit.GeometryDef = pGeomDef pFieldsEdit.AddField pField

' Create the shapefile ' (some parameters apply to geodatabase options and can be defaulted as Nothing) Set createShapefile = pFWS.CreateFeatureClass(strName, pFields, Nothing, _ Nothing, esriFTSimple, strShapeFieldName, "") Exit FunctionEH: MsgBox Err.Description, vbInformation, "createShapefile"End Function

Public Sub Ascii2Point(strFilePath As String, strAsciiFilename As String, strShapeFilename As String) ''Create a point shapefile from a ascii file including the coordinates of x,y and z ''strFilePath is the folder that contains the ascii file and also shapefile will be created. '' For example strFilePath = "e:\project\test" ''strAsciiFilename is the filename of ascii file, such as "xyz.txt". ''strShapeFilename is name of shapefile that will be created in the folder of strFilePath. '' For example strShapeFilename = "MyPoint" without extension. '' ''Example call: Ascii2Point "e:\project\test","xyz.txt","MyPoint" '' '' Xiaodong ZHAO, Kyushu University, Fukuoka, Japan '' [email protected] '' Feb 20, 2002 Const strPeriod As String * 1 = "\" If strFilePath = "" Or strAsciiFilename = "" Or strShapeFilename = "" Then Exit Sub End If Dim xCoor(1 To 100) As Single, yCoor(1 To 100) As Single, zCoor(1 To 100) As Single Dim iMaxNum As Long

81

Page 82: Arc Objects IMP Examples

Dim strFullAsciiFilename As String iMaxNum = 0 strFullAsciiFilename = strFilePath + strPeriod + strAsciiFilename 'Read Ascii file for the coordinates of x,y and z Open strFullAsciiFilename For Input As #1 While Not EOF(1) iMaxNum = iMaxNum + 1 Input #1, xCoor(iMaxNum), yCoor(iMaxNum), zCoor(iMaxNum) Wend Close #1 ' Prepare Fields for Shapefile Dim pXCoor As IFieldEdit Set pXCoor = New Field With pXCoor .Name = "XCoor" .Type = esriFieldTypeSingle End With Dim pYCoor As IFieldEdit Set pYCoor = New Field With pYCoor .Name = "YCoor" .Type = esriFieldTypeSingle End With Dim pZCoor As IFieldEdit Set pZCoor = New Field With pZCoor .Name = "ZCoor" .Type = esriFieldTypeSingle End With 'Call for createShapefile function to create a new point shapefile Dim pFClassOutput As IFeatureClass Set pFClassOutput = createShapefile(strFilePath, strShapeFilename, esriGeometryPoint) 'Add fields of xcoor, ycoor and zcoor pFClassOutput.AddField pXCoor pFClassOutput.AddField pYCoor pFClassOutput.AddField pZCoor ' Get indexes of xcoor, ycoor and zcoor Dim indexX As Long, indexY As Long, indexZ As Long indexX = pFClassOutput.FindField("XCoor") indexY = pFClassOutput.FindField("YCoor") indexZ = pFClassOutput.FindField("ZCoor") Dim indexShape As Long indexShape = pFClassOutput.FindField("shape") Dim pPoint As IPoint Set pPoint = New Point Dim i As Long For i = 1 To iMaxNum With pPoint .X = xCoor(i) .Y = xCoor(i) End With Dim pFeature As IFeature Set pFeature = pFClassOutput.CreateFeature pFeature.Value(indexShape) = pPoint pFeature.Value(indexX) = xCoor(i)

82

Page 83: Arc Objects IMP Examples

pFeature.Value(indexY) = yCoor(i) pFeature.Value(indexZ) = zCoor(i) pFeature.Store NextEnd Sub

Public Function createShapefile(strFolder As String, strName As String, _ geomType As esriCore.esriGeometryType) As esriCore.IFeatureClass

'' Simple function to create a shapefile in the strFolder.'' Note: the name of the shapefile should not contain the .shp extension'''' Xiaodong ZHAO, Kyushu University, Fukuoka, Japan'' [email protected]'' Feb 18, 2002

Const strShapeFieldName As String = "Shape" On Error GoTo EH Set createShapefile = Nothing If strFolder = "" Then Exit Function ' Open the folder to contain the shapefile as a workspace Dim pFWS As IFeatureWorkspace Dim pWorkspaceFactory As IWorkspaceFactory Set pWorkspaceFactory = New ShapefileWorkspaceFactory Set pFWS = pWorkspaceFactory.OpenFromFile(strFolder, 0) ' Set up a simple fields collection Dim pFields As IFields Dim pFieldsEdit As IFieldsEdit Set pFields = New esriCore.Fields Set pFieldsEdit = pFields Dim pField As IField Dim pFieldEdit As IFieldEdit ' Make the shape field ' it will need a geometry definition, with a spatial reference Set pField = New esriCore.Field Set pFieldEdit = pField pFieldEdit.Name = strShapeFieldName pFieldEdit.Type = esriFieldTypeGeometry Dim pGeomDef As IGeometryDef Dim pGeomDefEdit As IGeometryDefEdit Set pGeomDef = New GeometryDef Set pGeomDefEdit = pGeomDef With pGeomDefEdit .GeometryType = geomType Set .SpatialReference = New UnknownCoordinateSystem End With Set pFieldEdit.GeometryDef = pGeomDef pFieldsEdit.AddField pField

' Create the shapefile ' (some parameters apply to geodatabase options and can be defaulted as Nothing) Set createShapefile = pFWS.CreateFeatureClass(strName, pFields, Nothing, _ Nothing, esriFTSimple, strShapeFieldName, "") Exit FunctionEH:

83

Page 84: Arc Objects IMP Examples

MsgBox Err.Description, vbInformation, "createShapefile"End Function

Private Sub UIButtonOffsetBuffers_Click()

'creates two offset arcs, connects the endpoints with circular arcs,'converts to a polygon and displays as a graphic

Dim pMxDoc As IMxDocument Dim pActiveView As IActiveView Dim pGraphicsContainer As IGraphicsContainer Dim pEnumFeature As IEnumFeature Dim pFeature As IFeature Dim pElementPoly As IElement Dim pPolyline As IPolyline Dim strOffsetDistR As String Dim strOffsetDistL As String Dim dblOffsetDistR As Double Dim dblOffsetDistL As Double

Set pMxDoc = Application.Document Set pActiveView = pMxDoc.FocusMap Set pGraphicsContainer = pMxDoc.FocusMap

'verify that there is a feature selection If pMxDoc.FocusMap.SelectionCount = 0 Then Exit Sub

'Get offset distances from user 'left side, distance is negative strOffsetDistL = InputBox("Enter Left offset: ", "Left offset") If strOffsetDistL = "" Or Not IsNumeric(strOffsetDistL) Then Exit Sub dblOffsetDistL = -(CDbl(strOffsetDistL)) 'right side, distance is positive strOffsetDistR = InputBox("Enter Right offset: ", "Right offset") If strOffsetDistR = "" Or Not IsNumeric(strOffsetDistR) Then Exit Sub dblOffsetDistR = CDbl(strOffsetDistR) 'Get the selected features Set pEnumFeature = pMxDoc.FocusMap.FeatureSelection pEnumFeature.Reset Set pFeature = pEnumFeature.Next

'Loop through selected features Do While Not pFeature Is Nothing If TypeOf pFeature.Shape Is IPolyline Then Set pPolyline = pFeature.Shape 'create offset curves for buffer edges Dim pOffsetCurveL As IConstructCurve Dim pOffsetCurveR As IConstructCurve Set pOffsetCurveL = New Polyline Set pOffsetCurveR = New Polyline

pOffsetCurveL.ConstructOffset pPolyline, dblOffsetDistL, esriConstructOffsetRounded + esriConstructOffsetSimple

84

Page 85: Arc Objects IMP Examples

pOffsetCurveR.ConstructOffset pPolyline, dblOffsetDistR, esriConstructOffsetRounded + esriConstructOffsetSimple Dim pOffsetL As IPolyline Dim pOffsetR As IPolyline Set pOffsetL = pOffsetCurveL Set pOffsetR = pOffsetCurveR 'Reverse the directon of left offsetcurve to maintain Counterclockwise directionality pOffsetL.ReverseOrientation 'create the curved ends of buffer Dim pFromPointL As IPoint Dim pFromPointR As IPoint Dim pToPointL As IPoint Dim pToPointR As IPoint Set pFromPointL = pOffsetL.FromPoint Set pFromPointR = pOffsetR.FromPoint Set pToPointL = pOffsetL.ToPoint Set pToPointR = pOffsetR.ToPoint

Dim pConstructCircularArcL As IConstructCircularArc Dim pConstructCircularArcR As IConstructCircularArc Set pConstructCircularArcL = New CircularArc Set pConstructCircularArcR = New CircularArc Dim Pi As Double Pi = 4 * Atn(1) 'calculate the value of Pi 'angles are in radians (Radians = Degrees * PI/180)

'construct a round arc connecting the From points pConstructCircularArcR.ConstructEndPointsAngle pToPointR, pFromPointL, True, Pi pConstructCircularArcL.ConstructEndPointsAngle pToPointL, pFromPointR, True, Pi

'obtain circular arcs Dim pCurveLR As ICircularArc Dim pCurveRL As ICircularArc Set pCurveLR = pConstructCircularArcL Set pCurveRL = pConstructCircularArcR 'polylines must be converted to segment collections Dim pPolySegL As ISegmentCollection Dim pPolySegR As ISegmentCollection Set pPolySegL = pOffsetL Set pPolySegR = pOffsetR 'construct a ring Dim pRing As IRing Dim pRingBuffer As ISegmentCollection Set pRingBuffer = New Ring

pRingBuffer.AddSegmentCollection pPolySegR pRingBuffer.AddSegment pCurveRL

85

Page 86: Arc Objects IMP Examples

pRingBuffer.AddSegmentCollection pPolySegL pRingBuffer.AddSegment pCurveLR Set pRing = pRingBuffer 'construct a polygon geometry collection Dim pPolygonGeoColl As IGeometryCollection Set pPolygonGeoColl = New Polygon pPolygonGeoColl.AddGeometry pRing 'construct and simplify polygon Dim pPolygonFinal As IPolygon Dim pTopological As ITopologicalOperator Set pPolygonFinal = pPolygonGeoColl Set pTopological = pPolygonGeoColl pPolygonFinal.SimplifyPreserveFromTo pTopological.Simplify 'create polygon graphic element Set pElementPoly = New PolygonElement pElementPoly.Geometry = pPolygonFinal pGraphicsContainer.AddElement pElementPoly, 0 End If Set pFeature = pEnumFeature.Next Loop

pActiveView.PartialRefresh esriViewGraphics, Nothing, Nothing

'Created by: Justin Johnson '[email protected]

End Sub

Attribute VB_Name = "OffsetBufferCode"Option Explicit

'Author: Justin Johnson'Email : [email protected]'Date : February 2004'Description: Creates buffers around polylines and polygon boundaries allowing user to' specify a different buffer distance for each side of the line.

Public Sub OffsetBuffers() 'Creates offset buffers around polylines and polygons

Dim pMxDoc As IMxDocument Dim pMap As IMap Dim pInLayer As ILayer Dim pInFlayer As IFeatureLayer Dim pOutFLayer As IFeatureLayer Dim pInFCursor As IFeatureCursor Dim pOutFCursor As IFeatureCursor Dim pOutFBuffer As IFeatureBuffer Dim pInFClass As IFeatureClass Dim pOutFClass As IFeatureClass Dim pInFeature As IFeature

86

Page 87: Arc Objects IMP Examples

Dim pInGeom As IGeometry Dim sInput As String Dim dBufferDistance As Double Dim dLBufferDistance As Double Dim dRBufferDistance As Double Dim k As Integer Set pMxDoc = ThisDocument Set pMap = pMxDoc.FocusMap Set pInLayer = pMxDoc.SelectedLayer Set pOutFLayer = pMap.Layer(0) Set pOutFClass = pOutFLayer.FeatureClass Dim pGeomBag As IGeometryCollection Set pGeomBag = New GeometryBag Dim pEnumGeom As IEnumGeometry Set pEnumGeom = pGeomBag Dim pNewGeom As IGeometry 'Test compatibility of input/output feature layers If pInLayer Is Nothing Then MsgBox "Please select a feature layer", vbCritical, "Incompatible input layer" Exit Sub End If If Not TypeOf pInLayer Is IFeatureLayer Then MsgBox "Please select a feature layer", vbCritical, "Incompatible input layer" Exit Sub End If If Not pOutFClass.ShapeType = esriGeometryPolygon Then MsgBox "Geometry of output layer is not Polygon", vbCritical, "Incompatible output layer" Exit Sub End If 'Set input feature interfaces Set pInFlayer = pInLayer Set pInFClass = pInFlayer.FeatureClass 'Create input and output cursors Set pInFCursor = GetInputFeatures Set pOutFBuffer = pOutFClass.CreateFeatureBuffer Set pOutFCursor = pOutFClass.Insert(True) If pInFClass.ShapeType = esriGeometryPolyline Or pInFClass.ShapeType = esriGeometryPolygon Then 'If feature is a polyline or polygon, ask for offsets 'Get Left side buffer distance, test if response is empty or non-numeric sInput = InputBox("Enter left buffer distance:", "Left Buffer Distance") If sInput = "" Or Not IsNumeric(sInput) Then Exit Sub dLBufferDistance = -CDbl(sInput) If dLBufferDistance > 0 Then Exit Sub 'Get Right side buffer distance, test if response is empty or non-numeric sInput = InputBox("Enter right buffer distance:", "Right Buffer Distance") If sInput = "" Or Not IsNumeric(sInput) Then Exit Sub dRBufferDistance = CDbl(sInput) If dRBufferDistance < 0 Then Exit Sub ElseIf pInFClass.ShapeType = esriGeometryPoint Then

87

Page 88: Arc Objects IMP Examples

'if feature is a point, ask for buffer radius sInput = InputBox("Enter point buffer distance:", "Point Buffer Distance") If sInput = "" Or Not IsNumeric(sInput) Then Exit Sub dBufferDistance = CDbl(sInput) Else Exit Sub End If

Set pInFeature = pInFCursor.NextFeature 'Get first feature Do While Not pInFeature Is Nothing

Dim pPolygonGeoColl As IGeometryCollection Dim pOutGeom As IGeometry Dim pOutPolygon As IPolygon Set pPolygonGeoColl = New Polygon Select Case pInFClass.ShapeType Case esriGeometryPoint Dim pCenter As IPoint Set pCenter = pInFeature.Shape Set pOutPolygon = ProcessPoint(pCenter, dBufferDistance) Set pOutGeom = pOutPolygon pGeomBag.AddGeometry pOutGeom Case esriGeometryPolyline Dim pPolyline As IPolyline Set pPolyline = pInFeature.Shape Set pOutPolygon = ProcessPolyline(pPolyline, dLBufferDistance, dRBufferDistance, False) Set pOutGeom = pOutPolygon pGeomBag.AddGeometry pOutGeom Case esriGeometryPolygon Dim pPolygon As IPolygon Dim pTopoOp As ITopologicalOperator Dim pPolygonBoundary As IPolyline Set pPolygon = pInFeature.Shape Set pTopoOp = pPolygon Set pPolygonBoundary = pTopoOp.Boundary Set pOutPolygon = ProcessPolyline(pPolygonBoundary, dLBufferDistance, dRBufferDistance, True) Set pOutGeom = pOutPolygon pGeomBag.AddGeometry pOutGeom End Select Set pInFeature = pInFCursor.NextFeature Loop

88

Page 89: Arc Objects IMP Examples

'send all completed buffer polygons to the output featureclass pEnumGeom.Reset Dim pBufferPolygon As IPolygon Set pBufferPolygon = pEnumGeom.Next Do While Not pBufferPolygon Is Nothing Set pOutFBuffer.Shape = pBufferPolygon pOutFCursor.InsertFeature pOutFBuffer pOutFCursor.Flush Set pBufferPolygon = pEnumGeom.Next Loop pMxDoc.ActiveView.Refresh End Sub

Private Function ProcessPoint(pCenter As IPoint, dBufferDistance As Double) As IPolygon 'returns a circle centered on IPoint with a radius dBufferDistance

Dim pCCircularArc As IConstructCircularArc Dim pSegment As ISegment Dim pSegColl As ISegmentCollection Dim pRing As IRing Dim pGeometry As IGeometry Dim pGeomColl As IGeometryCollection Dim pPolygon As IPolygon Set pCCircularArc = New CircularArc Set pSegment = pCCircularArc Set pSegColl = New Ring Set pRing = pSegColl pCCircularArc.ConstructCircle pCenter, dBufferDistance, False

pSegColl.AddSegment pSegment Set pPolygon = New Polygon Set pGeomColl = pPolygon Set pGeometry = pRing pGeomColl.AddGeometry pGeometry Set ProcessPoint = pPolygon End Function

Private Function ProcessPolyline(pPolyline As IPolyline, dLBufferDistance As Double, _ dRBufferDistance As Double, IsPolygon As Boolean) As IPolygon

'obtains the polyline segments, creates a rectangle around each segment according to the offsets 'obtains each vertex, sends each vertex to the ProcessVertex function to get the exterior angle buffer 'obtains each endpoint, sends each to ProcessPoint, where circles are created according to the offsets 'unions all polygons, returns the unioned polygon buffer for the entire polyline

Dim pPointColl As IPointCollection Dim pSegColl As ISegmentCollection Dim pSegment As ISegment Dim pCurve As ICurve

89

Page 90: Arc Objects IMP Examples

Dim pTopoOp As ITopologicalOperator Dim pOffsetpoint As IPoint Dim pVertexBuffer As IPolygon

Set pPointColl = pPolyline Set pSegColl = pPolyline Dim pPolygonGC As IGeometryCollection Dim pNewGeom As IGeometry Dim pGeomBag As IGeometryCollection Dim pIEnumGeom As IEnumGeometry Set pGeomBag = New GeometryBag Set pIEnumGeom = pGeomBag Dim pFseg As ISegment 'from segment Dim pTseg As ISegment 'to segment Set pFseg = pSegColl.Segment(0) Dim k As Integer For k = 0 To pSegColl.SegmentCount - 1 'process each segment Dim pConPoint As IConstructPoint Dim pFpoint As IPoint 'from point Dim pTpoint As IPoint 'to point Dim pFL As IPoint 'offset point - left of from point Dim pFR As IPoint 'offset point - right of from point Dim pTL As IPoint 'offset point - left of to point Dim pTR As IPoint 'offset point - right of to point Dim pClone As IClone Set pSegment = pSegColl.Segment(k) Set pCurve = pSegment Set pFpoint = pSegment.FromPoint Set pTpoint = pSegment.ToPoint Set pConPoint = New Point Set pClone = pConPoint 'Create the corners of the rectangular buffer for this segment pConPoint.ConstructOffset pCurve, esriNoExtension, 0, False, dLBufferDistance Set pFL = pClone.Clone pConPoint.ConstructOffset pCurve, esriNoExtension, pCurve.Length, False, dLBufferDistance Set pTL = pClone.Clone pConPoint.ConstructOffset pCurve, esriNoExtension, 0, False, dRBufferDistance Set pFR = pClone.Clone pConPoint.ConstructOffset pCurve, esriNoExtension, pCurve.Length, False, dRBufferDistance Set pTR = pClone.Clone Dim pRingPtColl As IPointCollection Dim pRing As IRing Set pRingPtColl = New Ring Set pRing = pRingPtColl

pRingPtColl.AddPoint pFR pRingPtColl.AddPoint pFL pRingPtColl.AddPoint pTL pRingPtColl.AddPoint pTR pRingPtColl.AddPoint pFR

90

Page 91: Arc Objects IMP Examples

Set pPolygonGC = New Polygon pPolygonGC.AddGeometry pRing

Set pNewGeom = pPolygonGC MakeGeometrySimple pNewGeom pGeomBag.AddGeometry pNewGeom

'send current segment, and previous segment, to obtain the exterior angular buffer at their vertex If k > 0 Then Set pTseg = pSegColl.Segment(k) Set pVertexBuffer = ProcessVertex(pFseg, pTseg, dLBufferDistance, dRBufferDistance) Set pNewGeom = pVertexBuffer MakeGeometrySimple pNewGeom pGeomBag.AddGeometry pNewGeom Set pFseg = pSegColl.Segment(k) End If

Next k If IsPolygon Then 'If polyline is a polygon boundary, create an exterior angular buffer at the vertex of the first 'and last segments of the boundary Dim pFirstSeg As ISegment Dim pLastSeg As ISegment Set pFirstSeg = pSegColl.Segment(0) Set pLastSeg = pSegColl.Segment(pSegColl.SegmentCount - 1) Set pVertexBuffer = ProcessVertex(pLastSeg, pFirstSeg, dLBufferDistance, dRBufferDistance) Set pNewGeom = pVertexBuffer MakeGeometrySimple pNewGeom pGeomBag.AddGeometry pNewGeom Else 'If polyline is not a polygon boundary, create circle buffers at polyline endpoints Set pFpoint = pPolyline.FromPoint Set pTpoint = pPolyline.ToPoint Set pCurve = pPolyline 'get the centerpoint of the buffer circle at the From point pConPoint.ConstructOffset pCurve, esriNoExtension, 0, False, _ (dRBufferDistance + -dLBufferDistance) / 2 + dLBufferDistance Set pOffsetpoint = pClone.Clone Set pVertexBuffer = ProcessPoint(pOffsetpoint, (dRBufferDistance + -(dLBufferDistance)) / 2) Set pNewGeom = pVertexBuffer MakeGeometrySimple pNewGeom pGeomBag.AddGeometry pNewGeom 'get the centerpoint of the buffer circle at the To point pConPoint.ConstructOffset pCurve, esriNoExtension, pCurve.Length, False, _ (dRBufferDistance + -dLBufferDistance) / 2 + dLBufferDistance

91

Page 92: Arc Objects IMP Examples

Set pOffsetpoint = pClone.Clone Set pVertexBuffer = ProcessPoint(pOffsetpoint, (dRBufferDistance + -(dLBufferDistance)) / 2) Set pNewGeom = pVertexBuffer MakeGeometrySimple pNewGeom pGeomBag.AddGeometry pNewGeom End If 'create output polygon by unioning all geometries in the GeometryBag created so far

Dim pOutPolygon As IPolygon Set pOutPolygon = New Polygon Set pTopoOp = pOutPolygon

pTopoOp.ConstructUnion pIEnumGeom pTopoOp.Simplify Set ProcessPolyline = pOutPolygon

End Function

Private Function ProcessVertex(pFseg As ISegment, pTseg As ISegment, _ dLBufferDistance As Double, dRBufferDistance As Double) As IPolygon 'takes two segments joined at a common vertex, creates a pie-shaped polygon centered over 'the vertex, sweeping from one segment to the other through the exterior angle (>180°), at a 'radius equal to that specified for that side of the polyline. The interior angle is the "slice" 'taken out of the pie. These polygons are used to fill in the areas not covered by the 'rectangular buffers of each polyline segment. Dim pPolygon As IPolygon Dim pRing As IRing Dim pGeomColl As IGeometryCollection Dim pSegColl As ISegmentCollection Set pPolygon = New Polygon Set pRing = New Ring Set pGeomColl = pPolygon Set pSegColl = pRing

Dim pConstCirc As IConstructCircularArc Dim pConstPoint As IConstructPoint Dim pCircArc As ICircularArc Dim dRadius As Double 'circular arc radius Dim pCircArcFpt As IPoint 'circular arc From point Dim pCircArcTpt As IPoint 'circular arc To point Dim pCircArcVtx As IPoint 'circular arc Vertex point Dim pSegment1 As ISegment 'line segment connecting circular arc to vertex Dim pSegment2 As ISegment 'line segment connecting circular arc to vertex, completing the polygon Dim pPtClone As IClone Set pConstPoint = New Point Set pConstCirc = New CircularArc Set pPtClone = pConstPoint Set pSegment1 = New Line Set pSegment2 = New Line Dim pTcurve As ICurve Dim pFcurve As ICurve

92

Page 93: Arc Objects IMP Examples

Set pTcurve = pTseg Set pFcurve = pFseg Dim pFfpt As IPoint 'From segment From point Dim pFtpt As IPoint 'From segment To point Dim pTfpt As IPoint 'To segment From point Dim pTtpt As IPoint 'To segment To point Set pFfpt = pFseg.FromPoint Set pFtpt = pFseg.ToPoint Set pTfpt = pTseg.FromPoint Set pTtpt = pTseg.ToPoint 'Find out if pTseg turns left or right from pFseg Select Case PointIsLeft(pFfpt, pFtpt, pTtpt) Case Is = -1 'line bends left, use right buffer distance dRadius = dRBufferDistance pConstPoint.ConstructAlong pTcurve, esriExtendAtTo, dRadius, False Set pCircArcTpt = pPtClone.Clone

pConstPoint.ConstructAlong pFcurve, esriExtendAtFrom, pFcurve.Length - dRadius, False Set pCircArcFpt = pPtClone.Clone Case Is = 1 'line bends right, use left buffer distance (left distance is a negative value) 'notice that the To and From points of the curve are switched. Find out why. dRadius = -dLBufferDistance

pConstPoint.ConstructAlong pTcurve, esriExtendAtTo, dRadius, False Set pCircArcFpt = pPtClone.Clone

pConstPoint.ConstructAlong pFcurve, esriExtendAtFrom, pFcurve.Length - dRadius, False Set pCircArcTpt = pPtClone.Clone Case Is = 0 'line segments are inline, don't do anything, the rectangles will merge seamlessly Set ProcessVertex = pPolygon Exit Function

End Select

Set pCircArcVtx = pFseg.ToPoint 'set the vertex

pConstCirc.ConstructEndPointsRadius pCircArcFpt, pCircArcTpt, True, dRadius, False

pSegColl.AddSegment pConstCirc 'Add circular segment to Ring

pSegment1.FromPoint = pCircArcTpt 'create first straight-line segment pSegment1.ToPoint = pCircArcVtx pSegColl.AddSegment pSegment1 pSegment2.FromPoint = pCircArcVtx 'create second straight-line segment pSegment2.ToPoint = pCircArcFpt pSegColl.AddSegment pSegment2 pRing.Close 'close ring pGeomColl.AddGeometry pRing 'add ring to Polygon Set ProcessVertex = pPolygon

93

Page 94: Arc Objects IMP Examples

End Function

Private Function GetInputFeatures() As IFeatureCursor 'Gets a Search cursor from the selected layer in the TOC 'Returns IFeatureCursor on either the selected features in the ' FeatureLayer, or all features if none (or all) are selected ' 'Preconditions: Input FeatureLayer is selected in the TOC Dim iVal As Integer Dim lVal As Long Dim sVal As Single Dim dVal As Double

Dim pMxDoc As IMxDocument Dim pInFlayer As IFeatureLayer Dim pInFCursor As IFeatureCursor Dim pInFClass As IFeatureClass Dim pFSelection As IFeatureSelection Dim pSelSet As ISelectionSet

Set pMxDoc = ThisDocument Set pInFlayer = pMxDoc.SelectedLayer Set pInFClass = pInFlayer.FeatureClass Set pFSelection = pInFlayer Set pSelSet = pFSelection.SelectionSet If pSelSet.Count <> 0 Then 'use selected features pFSelection.SelectionSet.Search Nothing, True, pInFCursor Else 'use all features Set pInFCursor = pInFClass.Search(Nothing, True) End If Set GetInputFeatures = pInFCursor

End Function

Private Function PointIsLeft(p0 As IPoint, p1 As IPoint, p2 As IPoint) As Integer

'returns -1 if p2 is LEFT of the line from p0 to p1 'returns 1 if p2 is RIGHT of the line 'returns 0 if p2 is ON the line from p0 to p1 Dim dResult As Double Dim vReturn As Integer dResult = (p1.X - p0.X) * (p2.Y - p0.Y) - (p2.X - p0.X) * (p1.Y - p0.Y) Select Case dResult Case Is > 0 vReturn = -1 Case Is = 0 vReturn = 0 Case Is < 0 vReturn = 1 End Select PointIsLeft = vReturn

End Function

94

Page 95: Arc Objects IMP Examples

Private Function MakeGeometrySimple(ByRef pGeometry As IGeometry) 'Simplifies a geometry by setting the IsKnownSimple value to False, then calling Simplify. 'Should be used to avoid "non-simple geometry" errors when trying to merge geometries.

Dim pTopoOp2 As ITopologicalOperator2 Set pTopoOp2 = pGeometry pTopoOp2.IsKnownSimple = False pTopoOp2.Simplify End Function

'************************************************

Const CzasOds As Integer = 10 '###refresh time in seconds###Dim i As IntegerDim RefsDim pMxDoc As IMxDocumentPrivate Declare Sub Sleep Lib "kernel32" _ (ByVal dwMilliseconds As Long)Sub RefreshMap() Set pMxDoc = ThisDocument Dim pmap As IMap Set pmap = pMxDoc.FocusMap Dim pav As IActiveView Set pav = pmap Do While i = 0 Czekaj CzasOds pav.Refresh Refs = DoEvents LoopEnd SubPublic Sub Czekaj(Seconds As Single) Dim lMilliSeconds As Long lMilliSeconds = Seconds * 1000 Sleep lMilliSecondsEnd Sub

Attribute VB_Name = "AutoAddLines"Option ExplicitPublic Sub Example_AutoAdd_HydrantLaterals() Call AddLines("Water Mains", "Water Fire Hydrants", False)End SubPublic Sub Example_AutoAdd_ServiceLaterals() Call AddLines("Water Mains", "Water Meters", True)End SubPublic Sub UseHighlightedLayers()

Dim pMxDoc As IMxDocument Dim pMap As IMap Dim pTest As Variant Dim pSetLayers As ISet Dim pLayer1 As ILayer Dim pLayer2 As ILayer Dim pFLayer1 As IFeatureLayer Dim pFLayer2 As IFeatureLayer Dim pFC1 As IFeatureClass Dim pFC2 As IFeatureClass Set pMxDoc = Application.Document Set pMap = pMxDoc.FocusMap ' Verify that there are layers in the table on contents

95

Page 96: Arc Objects IMP Examples

If pMap.LayerCount < 3 Then MsgBox "Must have at least three layers in your map." Exit Sub End If 'Verify that two layers are selected in the TOC Set pTest = pMxDoc.SelectedItem If pTest Is Nothing Then MsgBox "Please highlight two layers in the TOC." Exit Sub End If If Not TypeOf pMxDoc.SelectedItem Is ISet Then MsgBox "Please highlight two layers in the TOC." Exit Sub End If Set pSetLayers = pMxDoc.SelectedItem If pSetLayers.Count <> 2 Then MsgBox "Please highlight only two layers in the TOC." Exit Sub End If 'Get each of these highlighted layers from the TOC pSetLayers.Reset Set pLayer1 = pSetLayers.Next Set pLayer2 = pSetLayers.Next

'Verify that the highlighted layers are feature layers If Not TypeOf pLayer1 Is IFeatureLayer Then MsgBox pLayer1.Name & " is not a feature layer." Exit Sub End If If Not TypeOf pLayer2 Is IFeatureLayer Then MsgBox pLayer2.Name & " is not a feature layer." Exit Sub End If 'Get the feature layer and feature class pointers Set pFLayer1 = pLayer1 Set pFLayer2 = pLayer2 Set pFC1 = pFLayer1.FeatureClass Set pFC2 = pFLayer2.FeatureClass

'If the first highlighted layer is a line layer... If pFC1.ShapeType = esriGeometryPolyline Or pFC1.ShapeType = esriGeometryLine Then 'Stop if the other layer is not a point layer If pFC2.ShapeType <> esriGeometryPoint Then MsgBox "You need a point layer and a line layer highlighted." & vbNewLine & _ "Neither of these should be your edit target." Exit Sub End If 'Otherwise, go ahead add run the AddLines routine AddLines pLayer1.Name, pLayer2.Name, True 'If the first highlighted layer is a point layer... ElseIf pFC1.ShapeType = esriGeometryPoint Then 'Stop if the other layer is not a line layer If pFC2.ShapeType <> esriGeometryPolyline And pFC2.ShapeType <> esriGeometryLine Then MsgBox "You need a point layer and a line layer highlighted." & vbNewLine & _ "Neither of these should be your edit target."

96

Page 97: Arc Objects IMP Examples

Exit Sub End If 'Otherwise, go ahead add run the AddLines routine AddLines pLayer2.Name, pLayer1.Name, True

Else MsgBox "You need a point layer and a line layer highlighted." & vbNewLine & _ "Neither of these should be your edit target." Exit Sub End IfEnd Sub

Public Sub AddLines(sLineLayer As String, sPointLayer As String, blnAllowDoubles As Boolean)' Requires: must be editing; have some points selected; have target line layer set' Optional: select one line to force new line(s) to be drawn to it

On Error GoTo EH

Dim pMxDoc As IMxDocument Dim pMap As IMap Dim pFLayerPoint As IFeatureLayer Dim pFLayerLine As IFeatureLayer Dim pFLayerLateral As IFeatureLayer Dim pFCPoint As IFeatureClass Dim pFCLine As IFeatureClass Dim pFCLateral As IFeatureClass Dim pFSelPoint As IFeatureSelection Dim pFSelLine As IFeatureSelection Dim pFCursorLine As IFeatureCursor Dim pFeature As IFeature Dim pFeatureLine As IFeature Dim pGeometryPoint As IGeometry Dim pGeometryLine As IGeometry Dim pPolyLine As IPolyline Dim pToPoint As IPoint Dim pFromPoint As IPoint Dim pApp As IApplication Dim pId As New UID Dim pEditor As IEditor Dim pELayers As IEditLayers Dim pNewFeature As IFeature Dim lCount As Long Dim pProxOpLine As IProximityOperator Dim pRowSubtypes As IRowSubtypes Dim pSubtypes As ISubtypes Dim lSubCode As Long Dim pEnumPointOIDs As IEnumIDs Dim pLateral1 As IPolyline Dim pLateral2 As IPolyline Dim pSegCol As ISegmentCollection Dim bHasSubtypes As Boolean Dim lSelPointCount As Long Dim pLineFeat1 As IFeature Dim pLineFeat2 As IFeature Dim pRelOp As IRelationalOperator Set pApp = Application Set pMxDoc = pApp.Document Set pMap = pMxDoc.FocusMap ' Verify that there are layers in the table on contents

97

Page 98: Arc Objects IMP Examples

If pMap.LayerCount < 3 Then MsgBox "Must have at least three layers in your map." Exit Sub End If Set pFLayerPoint = FindFLayerByName(pMap, sPointLayer) Set pFLayerLine = FindFLayerByName(pMap, sLineLayer) 'Verify layers exisit If pFLayerPoint Is Nothing Then MsgBox sPointLayer & " layer not found." Exit Sub End If If pFLayerLine Is Nothing Then MsgBox sLineLayer & " layer not found." Exit Sub End If Set pFCPoint = pFLayerPoint.FeatureClass Set pFCLine = pFLayerLine.FeatureClass 'Verify that it is a correct type of geometry If pFCPoint.ShapeType <> esriGeometryPoint Then MsgBox pFCPoint.AliasName MsgBox sPointLayer & " layer must be a point layer." Exit Sub End If If pFCLine.ShapeType <> esriGeometryPolyline And pFCLine.ShapeType <> esriGeometryLine Then MsgBox sLineLayer & " layer must be a line or polyline layer." Exit Sub End If 'Verify that some Points are selected Set pFSelPoint = pFLayerPoint Set pFSelLine = pFLayerLine If pFSelPoint.SelectionSet.Count < 1 Then MsgBox sPointLayer & " layer must have some features selected." Exit Sub End If 'Verify that we are editing pId = "esriCore.Editor" Set pEditor = pApp.FindExtensionByCLSID(pId) If Not (pEditor.EditState = esriStateEditing) Then MsgBox "Must be editing." Exit Sub End If 'Verify that the target is a polyline layer Set pELayers = pEditor If pELayers.CurrentLayer.FeatureClass.ShapeType <> esriGeometryPolyline Then MsgBox "Edit target must be a polyline layer (i.e. laterals)." Exit Sub End If 'Get the target polyline layer Set pFLayerLateral = pELayers.CurrentLayer Set pFCLateral = pFLayerLateral.FeatureClass

'Verify that the target is not also the source line layer If pFLayerLine Is pFLayerLateral Then MsgBox "Target layer must be different than " & sLineLayer & " layer."

98

Page 99: Arc Objects IMP Examples

Exit Sub End If 'Get current target subtype If TypeOf pFCLateral Is ISubtypes Then Set pSubtypes = pFCLateral If pSubtypes.HasSubtype Then bHasSubtypes = True lSubCode = pELayers.CurrentSubtype Else bHasSubtypes = False End If End If 'Update Message bar pApp.StatusBar.Message(0) = "Adding " & pFLayerLateral.Name & " lines..." 'Start edit operation (for undo) pEditor.StartOperation On Error GoTo EH2 'Get the number of selected points lSelPointCount = pFSelPoint.SelectionSet.Count 'Get list of selected point object ids Set pEnumPointOIDs = pFSelPoint.SelectionSet.IDs

'Step through each selected point For lCount = 1 To lSelPointCount 'Get the point feature Set pFeature = pFCPoint.GetFeature(pEnumPointOIDs.Next)

'Update status bar pApp.StatusBar.Message(0) = "Adding " & pFLayerLateral.Name & " lines..." & str(lCount) & " of " & str(lSelPointCount)

'Get the "to" point for new line (start from selected point) Set pGeometryPoint = pFeature.Shape Set pToPoint = pGeometryPoint 'Get the selected line If pFSelLine.SelectionSet.Count = 1 Then pFSelLine.SelectionSet.Search Nothing, True, pFCursorLine Set pFeatureLine = pFCursorLine.NextFeature End If 'Or get closest line If pFSelLine.SelectionSet.Count <> 1 Then Set pFeatureLine = GetNearestFeature(pFeature, pFCLine) End If 'If a line was found using either method, then process If Not pFeatureLine Is Nothing Then 'Get geometry of existing line Set pGeometryLine = pFeatureLine.Shape 'Create the "from" point for new line Set pFromPoint = New Point Set pProxOpLine = pGeometryLine

99

Page 100: Arc Objects IMP Examples

pProxOpLine.QueryNearestPoint pToPoint, esriNoExtension, pFromPoint 'Create the new line Set pPolyLine = New Polyline pPolyLine.FromPoint = pFromPoint pPolyLine.ToPoint = pToPoint 'If this is not a special double "pig-tail" line, add the line If blnAllowDoubles = False Or lSelPointCount <> 2 Then 'Single Lateral 'Create a new feature in the target feature class Set pNewFeature = pFCLateral.CreateFeature 'Set the shape of this new line feature Set pNewFeature.Shape = pPolyLine 'If needed, set the subtype and default values If bHasSubtypes Then Set pRowSubtypes = pNewFeature pRowSubtypes.SubtypeCode = lSubCode pRowSubtypes.InitDefaultValues End If 'Save the new line pNewFeature.Store Else 'Double lateral------------------------------------------- 'Store each of the two selected points for later processing Select Case lCount Case 1 Set pLineFeat1 = pFeatureLine 'Closest or Selected Line Set pLateral1 = pPolyLine Case 2 Set pLineFeat2 = pFeatureLine 'Closest or Selected Line Set pLateral2 = pPolyLine 'If the two points have different closest lines 'use the one with the shortest distance for both points Set pRelOp = pLineFeat2.Shape If Not pRelOp.Equals(pLineFeat1.Shape) Then If pLateral1.length < pLateral2.length Then Set pProxOpLine = pLineFeat1.ShapeCopy pProxOpLine.QueryNearestPoint pLateral2.ToPoint, esriNoExtension, pFromPoint pLateral2.FromPoint = pFromPoint Else Set pProxOpLine = pLineFeat2.Shape pProxOpLine.QueryNearestPoint pLateral1.ToPoint, esriNoExtension, pFromPoint pLateral1.FromPoint = pFromPoint End If End If Set pLateral2 = pPolyLine End Select End If '-------------------------------------------------------- 'If line was not found... Else Debug.Print "Could not find closest line in " & sLineLayer If pFeature.HasOID Then Debug.Print "for feature OID = " & str(pFeature.OID) End If blnAllowDoubles = False End If

100

Page 101: Arc Objects IMP Examples

'Process next selected point Next lCount 'DOUBLE LATERAL ONLY ----------------------------------------------------- If blnAllowDoubles = True And lSelPointCount = 2 Then Dim dMaxDist As Double Dim dDist As Double Dim pMainLine As IPolyline Dim pMainMidPoint As IPoint Dim pConstructEndPoint As IConstructPoint Dim pTempPt1 As IPoint Dim pTempPt2 As IPoint Dim pConstTempPt1 As IConstructPoint Dim pConstTempPt2 As IConstructPoint Dim pCrossPiece As IPolyline Dim pCrossMidpoint As IPoint Dim pConstructpCrossMidpoint As IConstructPoint Dim pEndPolyLine As IPolyline Dim pEndSegColl As ISegmentCollection Dim pEndSegment As ISegment Dim pReturnPoint As IPoint Dim pTempLine2 As IPolyline Dim pTempLine As IPolyline 'First, determine the distance to the split...

'Find which lateral is shorter, use this as max distance If pLateral1.length < pLateral2.length Then dMaxDist = CInt(pLateral1.length) Else dMaxDist = CInt(pLateral2.length) End If 'Max dist should be less than the available distance dMaxDist = dMaxDist - 1 'Prompt user for desired distance dDist = CDbl(InputBox("Enter distance to lateral split" & vbCrLf & _ "Max distance is " & dMaxDist, "Double Lateral")) 'Verify that this will work If dDist < 0.01 Or dDist > dMaxDist Then 'use 1/2 the max dist MsgBox "Input distance is not acceptable. Using " & dMaxDist / 2 dDist = dMaxDist \ 2 End If

'Draw a line along the main between the two perpendicular intersections Set pMainLine = New Polyline pMainLine.FromPoint = pLateral1.FromPoint pMainLine.ToPoint = pLateral2.FromPoint 'Find the midpoint (this will be the start of the new line) Set pMainMidPoint = New Point Set pConstructEndPoint = pMainMidPoint pConstructEndPoint.ConstructAlong pMainLine, 0, 0.5, True 'Create a point along each lateral line ddist from the main Set pTempPt1 = New Point Set pTempPt2 = New Point Set pConstTempPt1 = pTempPt1

101

Page 102: Arc Objects IMP Examples

Set pConstTempPt2 = pTempPt2 pConstTempPt1.ConstructAlong pLateral1, 0, dDist, False pConstTempPt2.ConstructAlong pLateral2, 0, dDist, False 'Shorten the laterals to these new points pLateral1.FromPoint = pTempPt1 pLateral2.FromPoint = pTempPt2 'Create a crosspiece between the laterals Set pCrossPiece = New Polyline pCrossPiece.FromPoint = pTempPt1 pCrossPiece.ToPoint = pTempPt2 'Create the midpoint of the cross piece Set pCrossMidpoint = New Point Set pConstructpCrossMidpoint = pCrossMidpoint pConstructpCrossMidpoint.ConstructAlong pCrossPiece, 0, 0.5, True 'Create the line for the main trunk Set pEndPolyLine = New Polyline pEndPolyLine.FromPoint = pMainMidPoint pEndPolyLine.ToPoint = pCrossMidpoint Set pReturnPoint = New Point Set pEndSegColl = pEndPolyLine Set pEndSegment = pEndSegColl.Segment(pEndSegColl.SegmentCount - 1) Set pReturnPoint = pProxOpLine.ReturnNearestPoint(pEndSegment.ToPoint, 0) pEndPolyLine.FromPoint = pReturnPoint 'Build "U" portion of the line pLateral1.ReverseOrientation Set pSegCol = pLateral1 pSegCol.AddSegmentCollection pCrossPiece pSegCol.AddSegmentCollection pLateral2 'Add "U" as the target line feature Set pNewFeature = pFCLateral.CreateFeature Set pNewFeature.Shape = pSegCol 'If needed, set the subtype and default values If bHasSubtypes Then Set pRowSubtypes = pNewFeature pRowSubtypes.SubtypeCode = lSubCode pRowSubtypes.InitDefaultValues End If pNewFeature.Store

'Add the main trunk for the double line Set pNewFeature = pFCLateral.CreateFeature Set pNewFeature.Shape = pEndPolyLine 'If needed, set the subtype and default values If bHasSubtypes Then Set pRowSubtypes = pNewFeature pRowSubtypes.SubtypeCode = lSubCode pRowSubtypes.InitDefaultValues End If pNewFeature.Store End If 'END DOUBLE LATERAL ONLY-------------------------------------------------- 'Stop feature editing pEditor.StopOperation ("Auto Add Lines ")

102

Page 103: Arc Objects IMP Examples

'Clear all feature selections pMap.ClearSelection 'Redraw the map so you'll see the new lines pMxDoc.ActiveView.Refresh 'MsgBox "Auto Add Lines is complete." pApp.StatusBar.Message(0) = "Auto Add is complete." Exit SubEH: MsgBox Err.Number & " " & Err.Description Exit SubEH2: pEditor.AbortOperation MsgBox Err.Number & " " & Err.Description Exit SubEnd Sub

Public Function GetNearestFeature(pSrcFeature As IFeature, pSearchFeatureClass As IFeatureClass) As IFeature Dim pFilter As ISpatialFilter Dim sShapeField As String Dim pCursor As IFeatureCursor Dim pPoint As IPoint Dim pSearchEnvelope As IEnvelope Dim pPnt As IPoint Dim pProxOp As IProximityOperator Dim dMinDist As Double, dDist As Double Dim pFeature As IFeature Dim pSafePoint As IPoint Dim pSourceFeaturePoint As IPoint On Error GoTo ErrorHandler If Not TypeOf pSrcFeature.Shape Is IPoint Then Err.Raise vbObjectError, , "Source feature is not a Point." End If ' Make search envelope Set pSearchEnvelope = New Envelope Set pPnt = New Point pPnt.PutCoords 0, 0 pSearchEnvelope.LowerLeft = pPnt pPnt.PutCoords 1000, 1000 ' cEnvelopeSize, cEnvelopeSize pSearchEnvelope.UpperRight = pPnt pSearchEnvelope.CenterAt pSrcFeature.Shape ' Setup the search Set pFilter = New SpatialFilter pFilter.SpatialRel = esriSpatialRelIntersects Set pFilter.Geometry = pSearchEnvelope sShapeField = pSearchFeatureClass.ShapeFieldName pFilter.GeometryField = sShapeField 'Set pFilter.OutputSpatialReference(sShapeField) = m_pMap.SpatialReference ' Find all main line features within the search envelope Set pSafePoint = New Point Set pSourceFeaturePoint = pSrcFeature.Shape pSafePoint.PutCoords pSourceFeaturePoint.X, pSourceFeaturePoint.Y Set pProxOp = pSafePoint Set pCursor = pSearchFeatureClass.Search(pFilter, False) ' Find the closest one to the source feature (point)

103

Page 104: Arc Objects IMP Examples

dMinDist = 500 Set pFeature = pCursor.NextFeature Do While (Not pFeature Is Nothing) dDist = pProxOp.ReturnDistance(pFeature.ShapeCopy) If dDist < dMinDist Then Set GetNearestFeature = pFeature dMinDist = dDist End If Set pFeature = pCursor.NextFeature Loop Exit Function ResumeErrorHandler: MsgBox "Error: " & Err.Description, , "GetNearestFeature" Set GetNearestFeature = NothingEnd Function

Public Function FindFLayerByName(pMap As IMap, sLayerName As String) As IFeatureLayer 'This function will return only feature layers. 'It can find feature layers within groups. Dim pEnumLayer As IEnumLayer Dim pCompositeLayer As ICompositeLayer Dim i As Integer Set pEnumLayer = pMap.Layers pEnumLayer.Reset

Dim pLayer As ILayer Set pLayer = pEnumLayer.Next

Do While Not pLayer Is Nothing If TypeOf pLayer Is ICompositeLayer Then Set pCompositeLayer = pLayer For i = 0 To pCompositeLayer.Count - 1 With pCompositeLayer If .Layer(i).Name = sLayerName Then If TypeOf .Layer(i) Is IFeatureLayer Then Set FindFLayerByName = pCompositeLayer.Layer(i) Exit Function End If End If End With Next i ElseIf pLayer.Name = sLayerName And TypeOf pLayer Is IFeatureLayer Then Set FindFLayerByName = pLayer Exit Function End If Set pLayer = pEnumLayer.Next Loop

End Function

104