I wish to count the number of segments of a polygon that has a length less than 25 meters when the angle between two vertices is not close to 180 degrees i.e. if the angle is between 178 to 182 degrees I want to ignore this case even though the segment length is less than 25 meters. I note the basic part of the code below is in VBA. Could anybody help me please to find why I get the wrong results? Thanks.

     Dim pFCursor As IFeatureCursor
Set pFCursor = pFeatureClass.Update(Nothing, True)

Dim pFeature As IFeature
Set pFeature = pFCursor.NextFeature

Dim pGeomColl As IGeometryCollection
Dim pSegColl As ISegmentCollection
Dim pCurve As ICurve
Dim pLine1 As ILine
Dim pLine2 As ILine
Dim dVtxAng As Double
Dim i As Long, j As Long
Dim pi As Double
pi = Atn(1) * 4

Dim counter As Integer
counter = 0
Dim angleDeg As Double

Do Until pFeature Is Nothing
FID = pFeature.Value(intPosFID)

pFilter.WhereClause = "FID=" & FID
pActiveView.PartialRefresh esriViewGeoSelection, Nothing, Nothing

Set pSelection = pLayer
pSelection.SelectFeatures pFilter, esriSelectionResultNew, True
'******************Code for measuring angles and minimum lenghts

    ' Get all disjoint paths
    Set pGeomColl = pFeature.Shape

    ' Loop thru the paths
    For i = 0 To pGeomColl.GeometryCount - 1
        ' Get all segments that make up this path
        Set pSegColl = pGeomColl.Geometry(i)
        Set pCurve = pSegColl

        ' Loop thru the segments
        For j = 0 To pSegColl.SegmentCount - 2

            ' Get the next two lines
            Set pLine1 = pSegColl.Segment(j)
            Set pLine2 = pSegColl.Segment(j + 1)

            ' Calculate the left side angle (in degrees)
            dVtxAng = CalcAngleBetweenLines(pLine1, pLine2)
             angleDeg = dVtxAng * 57.2957795

            If angleDeg >= 178 And angleDeg <= 182 Then
            counter = counter
            'if angle is close to 180 degrees then ignore the points and its vertices
    GoTo Nextsegment
            End If

            'if angle is not close to 180 degrees and lenght of segment is less than 25m then count the segment
    If angleDeg < 178 Or angleDeg > 182 And pLine1.Length < 25 Then
             counter = counter + 1

            End If

Nextsegment: Next j

Next i

'Store number of points in the field
pFeature.Value(intPosminLenght) = counter
pFCursor.UpdateFeature pFeature

counter = 0
Set pFeature = pFCursor.NextFeature

End Sub
  • 1
    It sounds like your purpose might be related to polygon generalization. Have you looked into that at all? – Anthony -GISCOE- Jun 21 '11 at 13:07
  • 1
    Each segment in a polygon has two vertices and therefore two angles. In light of this, I cannot make sense of your selection criterion for the segments. Do you need both angles to be non-straight, or at least one, or something else? – whuber Jun 21 '11 at 14:16
  • Firstly,generilisation is not my purpose. Secondly, I use segments to measure the angle in each point of the polygon.Simply, when an angle is considered as close to a straight i.e. its value its something between 178 and 182 degrees then in this case I do not want to get the minimum lenght i.e. 25 meters for both vertices of a segment. In my mind, a segment has two vertices that their intersection creates a point in the polygon hence one angle. Is that right? – Demetris Jun 21 '11 at 15:37
  • 1
    @Demetris I don't follow: the two vertices of a single segment never intersect at all. Let's look at this another way: suppose the angle at a vertex is 179 degrees. How would this affect how you count each of the two segments adjacent to that angle? – whuber Jun 21 '11 at 16:22
  • @Whuber. I am really sorry for the confusing I caused. Let me explain it with this way. In the Figure you provided in this link gis.stackexchange.com/questions/10860/… AB and BC are two lines that form an angle of 130 degrees. I want to check each such angle of a polygon and if that angle is close to 180 degrees i.e. from 178 to 182 then I will ignore this angle-polygon point and go to the next polygon point; Else I want to measure the lenght of AB and BC lines to find if it is less than 25m.Then I will continue to next angle etc... – Demetris Jun 21 '11 at 18:15

Regarding this line :

'if angle is not close to 180 degrees and lenght of segment is less than 25m then count the segment
If angleDeg < 178 Or angleDeg > 182 And pLine1.Length < 25 Then
counter = counter + 1

It seems like there's an operator precedence error in it. Your condition should be like

If (angleDeg < 178 Or angleDeg > 182) And pLine1.Length < 25 Then
counter = counter + 1
  • Believe or not, the problem in that cose was that I ignored the parentheses in the if statement. I checked results for several polygons manually. So, thanks Goldorak84 for the right answer. – Demetris Jun 22 '11 at 4:37

I'm going to use (possibly) amazing psychic powers here and say that the problem lies in the function "CalcAngleBetweenLines".

  1. There's no source provided for it, and the rest of the code looks semi-reasonable, ignoring the GOTO which is a lot like fingernails down a chalkboard.

  2. Odds are really good that you're using ATAN in there, which can do unexpected things in VBA, not the least of which is returning all results in the the fourth and first quadrant.

  • 1
    Good guess about ATan, but it actually misses the mark: the code is here – whuber Jun 21 '11 at 14:18
  • That code works very well. I just want to add this new thing i.e. after measuring an angle measure the lenght of each line including that constraint with the value of an angle i.e. ignore angles with 178-282 degrees. – Demetris Jun 21 '11 at 15:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.