Select to view content in your preferred language

Generating a centroid for a polygon

4055
31
10-13-2011 03:15 AM
YousafHassan
Emerging Contributor
Hi
I am trying to help my colleague who wants to select a polygon and then click a button, which would generate a centroid for that polygon. Ideally, he wants a pop-up to appear which would display a copy&pasteable X and Y. He wants this automation as he wants X and Y to be generated for polygons using the same algorithm.

I was thinking of building a custom tool for him using a model. Could anyone please point me to the tools I need in order to achieve this? If you have already written a tool, would you like share it with me? I am quite comfortable in python and VBA but am not so familiar with Arc tools. I would actually prefer to do this in python as the support for VBA won't be there in future.

Any help would be extremely appreciated.
Thanks.
0 Kudos
31 Replies
AlexanderGray
Honored Contributor
in VBA you need to do 'set' with a pointer.  A pointer is anything not a literal (a literal usually you can write down on a paper).

set pFSelection = pMap.Layer(0)


The part about declaring the variables is useful too since it avoids all kind of errors, you only need it if you put the option explicit at the top of the class (before any methods.)  You should always use option explicit.
0 Kudos
YousafHassan
Emerging Contributor
Thanks for all your help so far. I have now amended the code to the following:

Option Explicit

Sub CreateCentroid()

Dim pDoc As IMxDocument
Dim pMap As IMap

Set pDoc = Application.Document
Set pMap = pDoc.FocusMap

Dim pFCursor As IFeatureCursor
Dim pSelectionSet As ISelectionSet
Dim pFSelection As IFeatureSelection
Set pFSelection = pMap.Layer(0)

Dim pPoly As IPolygon
Dim pArea As IArea
Dim pPoint As IPoint
Dim lat As Long
Dim lon As Long

Dim pFeat As IFeature
Set pFeat = pFCursor.NextFeature
Do Until pFeat Is Nothing
    Set pPoly = pFeat.ShapeCopy
    Set pArea = pPoly
    Set pPoint = pArea.Centroid
    lat = pPoint.X
    lon = pPoint.Y
    Set pFeat = pFCursor.NextFeature
Loop

End Sub



But now I am getting a run-time error:

Run-time error:91 Object Variable or With Block Variable not set

When I click on debug, it takes me to the following line in code:

Set pFeat = pFCursor.NextFeature


Thanks again.
0 Kudos
JamesCrandall
MVP Alum
But now I am getting a run-time error:

Run-time error:91 Object Variable or With Block Variable not set

When I click on debug, it takes me to the following line in code:

Set pFeat = pFCursor.NextFeature


Thanks again.


That's probably because you are not setting pFCursor anywhere (I don't think I provided that in my original post.  sorry I am picking snippets from my own implementation which is different).  See if this helps/completes the code. 

Sub CreateCentroid()

Dim pDoc As IMxDocument
Dim pMap As IMap

Set pDoc = Application.Document
Set pMap = pDoc.FocusMap

Dim pFCursor As IFeatureCursor
Dim pSelectionSet As ISelectionSet
Dim pFSelection As IFeatureSelection
Set pFSelection = pMap.Layer(0)

pSelectionSet = pFSelection.SelectionSet
''set the pfeaturecursor 
pFCursor = Nothing
''Get a cursor from the selected features
pSelectionSet.Search(Nothing, False, pFCursor)
Dim pPoly As IPolygon
Dim pArea As IArea
Dim pPoint As IPoint
Dim lat As Long
Dim lon As Long

Dim pFeat As IFeature
Set pFeat = pFCursor.NextFeature
Do Until pFeat Is Nothing
    Set pPoly = pFeat.ShapeCopy
    Set pArea = pPoly
    Set pPoint = pArea.Centroid
    lat = pPoint.X
    lon = pPoint.Y
    Set pFeat = pFCursor.NextFeature
Loop

End Sub
0 Kudos
YousafHassan
Emerging Contributor
The pSelectionSet.Search(Nothing, False, pFCursor) is appearing in red. I am guessing it should be:

pFCursor = Nothing
pFCursor = pSelectionSet.Search(Nothing, False, pFCursor)
0 Kudos
JamesCrandall
MVP Alum
The pSelectionSet.Search(Nothing, False, pFCursor) is appearing in red. I am guessing it should be:

pFCursor = Nothing
pFCursor = pSelectionSet.Search(Nothing, False, pFCursor)


No the way you have the pFCursor would not work --- the code I posted works just fine for me.  I really don't know why it would appear in red or do I even know what that means.  I am using Visual Studio 2008 with all of the proper SDK's installed, along with ArcGIS v10.
0 Kudos
JamesCrandall
MVP Alum
Also, you have specified the lat and lon variables as LONG data type.  Why?  This would produce a whole number, which I don't know of any Latitude/Longitude coordinate that is a whole number.  Is that what you want?
0 Kudos
YousafHassan
Emerging Contributor
Also, you have specified the lat and lon variables as LONG data type.  Why?  This would produce a whole number, which I don't know of any Latitude/Longitude coordinate that is a whole number.  Is that what you want?


Well, the reason for that is that I wanted Eastings and Northings instead of latitude and longitude. So I take it that this code produces latitude and longitude? I assumed that lat and lon were just variable names and didn't mean that the code was actually producing latitude and longitude.

The thing is that I am running this as a Macro in the VB editor under Customise menu in ArcMap. And you have access to full visual studio environment. Maybe that's why this is not going to work as a macro. I am trying my best to get hold of VS 2008 or above, in order to install the SDK for .net

I wonder if some one can help us run this as a macro in the mean time!
0 Kudos
AlexanderGray
Honored Contributor
In VBA you only use brackets in a method call when you expect a return.  In the case of the ISelectionSet.Search, the cursor variable is passed in the method and returns populated.  It is one of my peeves with ArcObjects, sometimes the method returns the value you want, other times you have to pass in a variable that gets populated by the function.  Both methods are legitimate, I just wish esri picked one and stuck with it.
Dim pFCursor as IFeatureCursor
pFCursor = nothing 
pSelectionSet.Search Nothing, False, pFCursor
0 Kudos
JamesCrandall
MVP Alum
Also, after looking at some older posts I noticed for VBA that pDoc should be set to "ThisDocument" instead of how the OP has it:


Set pDoc = Application.Document


Should this be:


Set pDoc = ThisDocument


Sorry it's been a long time since I've used VBA and just trying to help out as best I can!
0 Kudos
AlexanderGray
Honored Contributor
In VBA, ThisDocument is a shortcut to Application.Document.  Both are equivalent.
0 Kudos