EXAMPLES
ESRI
1
'***********************************************************************************************
*
' "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
' 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
m_FirstLayerName = pMap.Layer(0).Name
m_LastLayerName = pMap.Layer(pMap.LayerCount - 1).Name
2
'You could specify a layer by name rather than position
'm_OtherLockedLayerName = "Specify the layer name here"
End Sub
Public Sub StopEvents()
End Sub
'Comment out the above line and uncomment this code if you also want to check for the bottom layer
If pMap.Layer(0).Name = m_FirstLayerName Then
If pMap.Layer(iNumLayers - 1).Name = m_LastLayerName Then
Exit Sub
End If
End If
'Otherwise, scroll through each layer til the desired layer is found
Set pEnumLayer = pMap.Layers
Set pLayer = pEnumLayer.Next
End Sub
3
'stop listening for changes to the TOC
Call StopEvents
End Function
End Function
' 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
Set pPoint.SpatialReference = pBasicMap.SpatialReference
End Sub
With pFieldx
.Type = esriFieldTypeDouble
.Name = "Area"
End With
pFClass.AddField pFieldx
End If
5
indexA = pFClass.FindField("Area")
'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
pFeature.Value(indexA) = aarea
pFCursor.UpdateFeature pFeature
' pFeature.Store
Wend
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
6
Private canRun As Boolean
Private lNumFeat As Long
End Sub
' 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
7
.Font.Italic = False
End With
Else
' 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 If
End 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 With
End If
End Sub
8
cmdGo.Enabled = True
End If
End Sub
End Sub
' 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"
End With
9
pFClass.AddField pFieldAcre
indexAcre = pFClass.FindField("ACREAGE")
End If
' 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.NextFeature
Next
pSBar.Message(esriStatusMain) = "Add acreage: Finished updating records. Check the attribute table."
End Sub
10
Sub AddGraphicsCoords()
' --------------------------------------------------------------
' Now we can set some default parameters for ALL callout boxes,
' whether feature or graphic-based.
' --------------------------------------------------------------
' Set these so that the callouts don't appear right over the point
xOffset = pMxDocument.ActiveView.Extent.Width / 8
yOffset = pMxDocument.ActiveView.Extent.Width / 20
11
' 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 If
Wend
End Sub
' Use this code to set the offset for the callout box
Set CalloutLocation = New Point
CalloutLocation.PutCoords xCoord - xOffset, yCoord + yOffset
pCallout.AnchorPoint = param_Pt
End Function
Sub ContourElev_SK()
12
'This macro was compiled by Sudarshan Karki
'with ideas borrowed from many other scripts
'in the ESRI site. (Sudarshan.Karki@nrw.qld.gov.au)
'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
13
lNumberofFeatures = pFeatureClass.FeatureCount(Nothing)
dInterval = lNumberofFeatures / 100
Static i
i = 1
pStepProgressor.MinRange = 1
pStepProgressor.MaxRange = lNumberofFeatures
pStepProgressor.StepValue = dInterval
pStepProgressor.Hide
'Error handler
ErrorHandler:
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
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:
'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)
15
Set pGraphicsContainer = pPageLayout
Set pMapFrame = pGraphicsContainer.FindFrame(pMap)
Set pMapSurroundFrame = pMapFrame.CreateSurroundFrame(pID, Nothing)
pMapSurroundFrame.MapSurround.Name = strName
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.
16
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
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
17
Next h
18
pCalc.ShowErrorPrompt = True
pCalc.Calculate
Unload Me
End Sub
Private Sub CloseWindows()
pWindowSet.Reset
Set pDataWindow = pWindowSet.Next
19
Set pTableWindow = Nothing
Set pDataWindow = Nothing
End Sub
Private 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 pField1
End Sub
Sub Test()
Dim pDWindows As IApplicationWindows
Set pDWindows = Application
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 = Nothing
End Sub
Private Sub ComboBox1_Click()
If ComboBox1.Text = "Short Integer" Then
TextBox2.Visible = False
TextBox3.Visible = True
TextBox4.Visible = False
Label1.Visible = False
Label2.Visible = True
Label3.Visible = False
ElseIf ComboBox1.Text = "Long Integer" Then
TextBox2.Visible = False
TextBox3.Visible = True
TextBox4.Visible = False
Label1.Visible = False
Label2.Visible = True
Label3.Visible = False
ElseIf ComboBox1.Text = "Float" Then
TextBox2.Visible = False
20
TextBox3.Visible = True
TextBox4.Visible = True
Label1.Visible = False
Label2.Visible = True
Label3.Visible = True
ElseIf ComboBox1.Text = "Double" Then
TextBox2.Visible = False
TextBox3.Visible = True
TextBox4.Visible = True
Label1.Visible = False
Label2.Visible = True
Label3.Visible = True
ElseIf ComboBox1.Text = "Text" Then
TextBox2.Visible = True
TextBox3.Visible = False
TextBox4.Visible = False
Label1.Visible = True
Label2.Visible = False
Label3.Visible = False
ElseIf ComboBox1.Text = "Date" Then
TextBox2.Visible = False
TextBox3.Visible = False
TextBox4.Visible = False
Label1.Visible = False
Label2.Visible = False
Label3.Visible = False
End If
End Sub
21
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
End Sub
22
pFeatureSelection.Clear
pPointC.X = X
pPointC.Y = Y
pPointCollection.AddPoint pPointC, 1
Set pFeature.Shape = pPointCollection
pFeature.Store
pFeatureSelection.Add pFeature
ShapeCounter = ShapeCounter + 1
End If
Loop
Else
End If
End Sub
23
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).
pMxDoc.AddLayer pLayer
pMxDoc.ActiveView.PartialRefresh esriViewGeography, pLayer, Nothing
24
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
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
To
pSFilter.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.
Files:
ReadMe_ AddPointsAtCrossings.htm
AddPointsAtCrossings.bas
Data requirements:
Setup:
In ArcMap
Tools>Macros>VB Editor
In VB Editor
In the Project Window…
Click Project to store changes for this map document only or
Click Normal to store changes for all maps you access on your computer
File>Import File...
25
Navigate to AddPointsAtCrossings.bas and click Open
Expand the Modules folder
Double-click the AddPointsAtCrossings module to view the code
Change 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
Credits:
This code was created by ESRI-Team Water.
Your Input:
Please send any comments via email to Michele Lundeen at mlundeen@esri.com.
1)
Option Explicit
Public Sub Example_AddPointsAtCrossings()
Call AddPoints("Water Mains", "Sewer Gravity Mains")
End Sub
26
' 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
On Error GoTo EH
Dim pApp As IApplication
27
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
Dim pSFilter As ISpatialFilter
Dim pPoint As IPoint
Dim pMPoint As IMultipoint
Dim pGeoCol As IGeometryCollection
Dim lGeoTotal As Long
Dim lGeoCount As Integer
' 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
28
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
'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
29
If vbNo = MsgBox("Use all " & pFCLine1.FeatureCount(Nothing) & " features?", vbYesNo, "Add Points") Then
Exit Sub
End If
Set pFCursor1 = pFLayerLine1.Search(Nothing, False)
lTotal = pFLayerLine1.FeatureClass.FeatureCount(Nothing)
End If
'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
30
pRowSubtypes.InitDefaultValues
End If
Next lGeoCount
End If
End If
Exit Sub
EH:
31
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
2)
Option Explicit
Public Sub Example_AddPointsAtCrossings()
Call AddPoints("Water Mains", "Sewer Gravity Mains")
End Sub
32
Set pLayer2 = pSetLayers.Next
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
33
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
34
Set pFLayerCross = pELayers.CurrentLayer
Set pFCCross = pFLayerCross.FeatureClass
'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
'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
35
'Get the geometry for this feature from layer2
Set pCurve2 = pFeature2.Shape
Next lGeoCount
End If
End If
Exit Sub
EH:
36
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.
End Function
37
Public cnnACC As ADODB.Connection 'Access Connection
Public rst As ADODB.RecordSet
Public adoCat As ADOX.Catalog 'Catalog
Public adoTbl As ADOX.Table 'Table
Public Location As String
38
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
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
39
Set pTable = Nothing
Set pFeatws = Nothing
Set pWorkspace = Nothing
Set pFact = Nothing
End Sub
40
rs.MoveNext
Wend
End If
End Sub
End Sub
41
Add Tables from Excel.
'Option Explicit
Dim cnExcel As New ADODB.Connection
Dim rsExcel As New ADODB.RecordSet
Dim ExcelFields As String
'fill the recordset into listview
Sub 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
lst.SubItems(a) = rs.Fields(a).Value
End If
Next
rs.MoveNext
Wend
End If
End Sub
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 Sub
Private Sub getTables(cn As ADODB.Connection, lst As ListBox)
43
Dim tbl As ADOX.Table
Dim cat As New ADOX.Catalog
Set cat.ActiveConnection = cn
End Sub
44
If pTable Is Nothing Then
MsgBox "The table was not found"
Exit Sub
End If
'++ 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
Set pMxDoc = Nothing
Set pStTabColl = Nothing
Set pStTab = Nothing
Set pMap = Nothing
Set ptabWin = Nothing
Set pWorkspace = Nothing
Set pWorkspaceFact = Nothing
Set pPropset = Nothing
End Sub
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
46
Private Sub CommandButton4_Click()
On Error Resume Next
End Sub
End Sub
End Sub
End Sub
End Sub
End Sub
47
Private Sub lvOpen_Click() 'open excel file
dlg.CancelError = True
On Error GoTo FileOpenCancel
Dim ExcelFile As String
ExcelFile = "xxx"
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
48
Set rsExcel = Nothing
If cnExcel.State = adStateOpen Then cnExcel.Close
Set cnExcel = Nothing
End Sub
49
Else
MsgBox "Must first select a Standalone Table or Shapefile."
Exit Sub
End If
frmAddUniqueVal2Table.Show
End Sub
UIButtonControl1_Enabled = bolEnabled
End Function
50
Public cnnACC As ADODB.Connection 'Access Connection
Public rst As ADODB.RecordSet
Public adoCat As ADOX.Catalog 'Catalog
Public adoTbl As ADOX.Table 'Table
51
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
'++ Create a new dataset object for the table you want to load
Dim pDataset As IDatasetName
Set pDataset = pEnumDataset.Next
'++ 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
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
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
End Sub
End Sub
53
Wend
End If
End Sub
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
Public Sub populateListBoxWithTableNames()
54
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
Exit For
End If
Next
55
Dim Path As String
Path = CurDir
'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)
'******************************************
'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
Set pWorkspace = pFact.OpenFromFile(Path, 0)
Set pFeatws = pWorkspace
Set pTable = pFeatws.OpenTable("ExpSample1")
Add_Table_TOC pTable
Exit Sub
EH:
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
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
57
Set pActiveView = Nothing
Set pSelItem = Nothing
Set pStAloneTab = Nothing
End Sub
End Sub
'AB - Check the user meant to run the script and that the selected file is the one they want to work with
Answer = MsgBox("Do you want to work with the selected layer?", vbYesNo, "Are you sure?")
If Answer = vbNo Then
Exit Sub
End If
58
Dim pFeatureClass As IFeatureClass
Set pFeatureClass = pFeatureLayer.FeatureClass
'AB - If the field for the X coordinate does not exist then make one
If pFeatureClass.FindField(strXCoord) = -1 Then
Set pFieldEdit = New Field
pFieldEdit.Type = esriFieldTypeDouble
pFieldEdit.Name = strXCoord
pFeatureClass.AddField pFieldEdit
End If
'AB - If the field for the Y coordinate does not exist then make one
If pFeatureClass.FindField(strYCoord) = -1 Then
Set pFieldEdit = New Field
pFieldEdit.Type = esriFieldTypeDouble
pFieldEdit.Name = strYCoord
pFeatureClass.AddField pFieldEdit
End If
'AB - Set a feature cursor to look at all the features in the layer
Dim pFeatureCursor As IFeatureCursor
Set pFeatureCursor = pFeatureClass.Search(Nothing, False)
'AB - Warn user they are about to run process and inform user of feature count
Answer = MsgBox("There are " & intCount & " features" & vbNewLine _
& "Press Yes to Continue or No to Cancel", vbYesNo, "Run Script?")
If Answer = vbNo Then
Exit Sub
End If
59
x = pArea.Centroid.x
pFeature.Value(pFieldNumberX) = x
y = pArea.Centroid.y
pFeature.Value(pFieldNumberY) = y
pFeature.Store
Next
'AB - Tell user script has finished
MsgBox "Job Finished!", vbInformation, "Finished"
'End Sub
With xfield
.Type = 3
.name = "XFIELD"
End With
With yfield
.Type = 3
.name = "YFIELD"
End With
theFC.AddField xfield
theFC.AddField yfield
60
While Not thefeature Is Nothing
thefeature.Value(indexX) = xcoor
'thefeature.Store
thefeature.Value(indexY) = ycoor
thefeature.Store
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
61
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
62
Dim pFeatCursor As IFeatureCursor
Dim pFeature As IFeature
Dim pPoint As IPoint
Dim pFeatGeo As IGeometry
Dim pFeatSR As ISpatialReference
Dim pShape As IGeometry
'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
63
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
64
' zhao@ies.kyushu-u.ac.jp
' Jan 31, 2002
Dim pMxdoc As IMxDocument
Set pMxdoc = ThisDocument
With pFieldx
.Type = esriFieldTypeDouble
.Name = "Xcoord"
End With
pFClass.AddField pFieldx
End If
With pFieldy
.Type = esriFieldTypeDouble
.Name = "Ycoord"
End With
pFClass.AddField pFieldy
End If
indexX = pFClass.FindField("Xcoord")
indexY = pFClass.FindField("Ycoord")
65
Dim xcoor As Double
Dim ycoor As Double
xcoor = pPoint.X
ycoor = pPoint.Y
pFeature.Value(indexX) = xcoor
pFeature.Value(indexY) = ycoor
pFeature.Store
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.
End Sub
End Function
End Function
66
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
sPath = String(255, 0)
lSize = GetEnvironmentVariable("Temp", sPath, Len(sPath))
If lSize = 0 Then
sPath = "C:"
End If
67
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)
'pnewFeature.Store
pNewFCursor.InsertFeature pNewFBuffer
68
pNewFL.Name = pnewFC.AliasName
pMap.AddLayer pNewFL
MsgBox "Finish"
Exit Sub
myEH:
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.
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()
and
End Sub )
5. Select (click) the layer (Feature Class, Shapefile or Coverage) you want to create labels for in the Table of Contents
7. You will be prompted to select the .lyr file from which you would like to import label symbology.
69
End If
Set pGxDialog = New GxDialog
Set pGxObjFilter = New GxFilterLayers
Set pGxDialog.ObjectFilter = pGxObjFilter
pGxDialog.Title = "Select Layer(.lyr) file"
pGxDialog.ButtonCaption = "Apply Labels"
'**
' @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()
70
Dim lFormID(100) As Long, l As Long
Dim sName As String, sCode As String
'Get Printer
Set pMxApp = Application
Set pPrinter = pMxApp.Printer
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
GoTo Cleanup
ErrHandler:
MsgBox "Error: " & Err.Description, vbCritical
Cleanup:
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
Option Explicit
'-- Graphics 1+ works in data view and tells user to switch to data view
Private Sub AreaCalcGraphplf_Click()
Dim pDoc As IMxDocument
Set pDoc = ThisDocument
Dim pAV As IActiveView
Set pAV = pDoc.ActiveView
Dim pGC As IGraphicsContainerSelect
Set pGC = pAV.GraphicsContainer
Dim pElem As IElement
Dim pPoly As IPolygon
Dim pAcres As Double, pFeet As Double, pMeters As Double
Dim i As Integer, Looper As Integer
i = pGC.ElementSelectionCount
pMeters = dArea
pFeet = pMeters * 10.76391042
pAcres = pFeet / 43560
MsgBox "Acreage = " & Format(pAcres, "##,##0")
End Sub
72
Dim pAcres As Double, pFeet As Double, pMeters As Double
Dim i As Integer, Looper As Integer
Dim pPoly As IFeature
Dim pMap As IMap
Dim pFSelection As IEnumFeature
Dim pActiveView As IActiveView
Dim pContentsView As IContentsView
Do Until Looper = i
Set pPoly = pFSelection.Next
Looper = Looper + 1
Set pArea = pPoly.Shape
pMeters = (pMeters + pArea.Area)
Loop
AREA CALLUCULATION
Dim pMxDoc As IMxDocument
Set pMxDoc = ThisDocument
Dim pMap As IMap
Set pMap = pMxDoc.FocusMap
73
If intArea = -1 Then
Dim pFieldEdit As IFieldEdit
Set pFieldEdit = New Field
pFieldEdit.Name = "NewArea"
pFieldEdit.Type = esriFieldTypeDouble
pFClass.AddField pFieldEdit
End If
iMaxNum = 0
74
Open strAsciiFullFilename For Input As #1
Dim blnIsZValue As Boolean 'Boolean variable dealing with z value
blnIsZValue = IIf(IsMissing(strFieldName) Or strFieldName = "",
False, True)
For i = 1 To iMaxNum
75
With pPoint
.x = xCoor(i)
.y = xCoor(i)
End With
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
End Sub
76
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
77
'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
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
'' zhao@ies.kyushu-u.ac.jp
'' Feb 20, 2002
78
Exit Sub
End If
79
Set pPoint = New Point
Dim i As Long
For i = 1 To iMaxNum
With pPoint
.x = xCoor(i)
.y = yCoor(i)
End With
pInsertFeatureBuffer.Value(indexX) = xCoor(i)
pInsertFeatureBuffer.Value(indexY) = yCoor(i)
pInsertFeatureBuffer.Value(indexZ) = zCoor(i)
Next
pInsertFeatureCursor.Flush 'Flush the cursor one last time
End Sub
On Error GoTo EH
Set createShapefile = Nothing
If strFolder = "" Then Exit Function
80
Set pFields = New esriCore.Fields
Set pFieldsEdit = pFields
Dim xCoor(1 To 100) As Single, yCoor(1 To 100) As Single, zCoor(1 To 100) As Single
Dim iMaxNum As Long
81
Dim strFullAsciiFilename As String
iMaxNum = 0
strFullAsciiFilename = strFilePath + strPeriod + strAsciiFilename
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
pFeature.Value(indexY) = yCoor(i)
pFeature.Value(indexZ) = zCoor(i)
pFeature.Store
Next
End Sub
On Error GoTo EH
Set createShapefile = Nothing
If strFolder = "" Then Exit Function
83
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
84
pOffsetCurveR.ConstructOffset pPolyline, dblOffsetDistR,
esriConstructOffsetRounded + esriConstructOffsetSimple
Dim Pi As Double
Pi = 4 * Atn(1) 'calculate the value of Pi
'angles are in radians (Radians = Degrees * PI/180)
'construct a ring
Dim pRing As IRing
Dim pRingBuffer As ISegmentCollection
Set pRingBuffer = New Ring
pRingBuffer.AddSegmentCollection pPolySegR
pRingBuffer.AddSegment pCurveRL
85
pRingBuffer.AddSegmentCollection pPolySegL
pRingBuffer.AddSegment pCurveLR
pPolygonGeoColl.AddGeometry pRing
pGraphicsContainer.AddElement pElementPoly, 0
End If
Set pFeature = pEnumFeature.Next
Loop
End Sub
Attribute VB_Name = "OffsetBufferCode"
Option Explicit
86
Dim sInput As String
Dim dBufferDistance As Double
Dim dLBufferDistance As Double
Dim dRBufferDistance As Double
Dim k As Integer
87
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
Case esriGeometryPoint
pGeomBag.AddGeometry pOutGeom
Case esriGeometryPolyline
pGeomBag.AddGeometry pOutGeom
Case esriGeometryPolygon
pGeomBag.AddGeometry pOutGeom
End Select
Loop
88
pEnumGeom.Reset
pOutFCursor.InsertFeature pOutFBuffer
pOutFCursor.Flush
pMxDoc.ActiveView.Refresh
End Sub
pSegColl.AddSegment pSegment
pGeomColl.AddGeometry pGeometry
End Function
'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
89
Dim pOffsetpoint As IPoint
Dim pVertexBuffer As IPolygon
Dim k As Integer
pRingPtColl.AddPoint pFR
pRingPtColl.AddPoint pFL
pRingPtColl.AddPoint pTL
pRingPtColl.AddPoint pTR
pRingPtColl.AddPoint pFR
90
pPolygonGC.AddGeometry pRing
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)
MakeGeometrySimple pNewGeom
pGeomBag.AddGeometry pNewGeom
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
MakeGeometrySimple pNewGeom
pGeomBag.AddGeometry pNewGeom
Else
'If polyline is not a polygon boundary, create circle buffers at polyline endpoints
MakeGeometrySimple pNewGeom
pGeomBag.AddGeometry pNewGeom
91
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
pTopoOp.ConstructUnion pIEnumGeom
pTopoOp.Simplify
End Function
'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.
92
Set pFcurve = pFseg
dRadius = dRBufferDistance
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
Case Is = 0
'line segments are inline, don't do anything, the rectangles will merge seamlessly
End Select
93
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
End Function
PointIsLeft = vReturn
End Function
94
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.
pTopoOp2.IsKnownSimple = False
pTopoOp2.Simplify
End Function
'************************************************
Const CzasOds As Integer = 10 '###refresh time in seconds###
Dim i As Integer
Dim Refs
Dim pMxDoc As IMxDocument
Private 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
Loop
End Sub
Public Sub Czekaj(Seconds As Single)
Dim lMilliSeconds As Long
lMilliSeconds = Seconds * 1000
Sleep lMilliSeconds
End Sub
Attribute VB_Name = "AutoAddLines"
Option Explicit
Public Sub Example_AutoAdd_HydrantLaterals()
Call AddLines("Water Mains", "Water Fire Hydrants", False)
End Sub
Public Sub Example_AutoAdd_ServiceLaterals()
Call AddLines("Water Mains", "Water Meters", True)
End Sub
Public Sub UseHighlightedLayers()
95
MsgBox "Must have at least three layers in your map."
Exit Sub
End If
96
End If
Else
MsgBox "You need a point layer and a line layer highlighted." & vbNewLine & _
"Neither of these should be your edit target."
Exit Sub
End If
End Sub
On Error GoTo EH
97
MsgBox "Must have at least three layers in your map."
Exit Sub
End If
'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."
Exit Sub
98
End If
'Get the "to" point for new line (start from selected point)
Set pGeometryPoint = pFeature.Shape
Set pToPoint = pGeometryPoint
99
'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
End Select
End If '--------------------------------------------------------
100
Next lCount
'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
Set pConstTempPt2 = pTempPt2
101
pConstTempPt1.ConstructAlong pLateral1, 0, dDist, False
pConstTempPt2.ConstructAlong pLateral2, 0, dDist, False
End If
'END DOUBLE LATERAL ONLY--------------------------------------------------
102
pMap.ClearSelection
Exit Sub
EH:
103
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
Resume
ErrorHandler:
MsgBox "Error: " & Err.Description, , "GetNearestFeature"
Set GetNearestFeature = Nothing
End Function
End Function
104