Cycle through Shapes, Parts and Vertices

For all of the significant power that geometries provide, from doing overlay calculations to buffers and convex hulls, they consume extra memory and are significantly slower for simple tasks. When all you need is access to the shapes, parts and coordinates (as is the case for drawing) or even if you just need to determine if two shapes intersect, you can rely on the FeatureSet.ShapeIndices. The code below demonstrates how this works in VB.Net. Point and MultiPoint shapes only have one part per shape, but in the case of MultiPart, that part may have more than one vertex. For Lines, each part represents the vertices connected by straight lines, while separate parts are not connected. For polygons, the parts may be islands or holes. According to the ArcGIS shapefile specification, each part of a polygon is a simple polygon and the vertices of the polygons are ordered clockwise. (Effectively so that the inside of the shape is on the right side of the line segments.) Holes should be ordered counter clockwise. For rendering with MapWindow 6, as long as the winding order of a hole is the opposite from the islands it will still draw correctly.


ShapeRange.png

Private Sub CycleThroughVertices()
    ' The feature set class works directly with vector data
    Dim fs As New FeatureSet()
    ' Opening a shapefile from disk loads data in "Index" mode by default.
    fs.Open("filename.shp")
    
    ' ShapeRanges can also be created from envelopes.
    Dim bounds As New ShapeRange(map1.Extents)
    
    ' The shapes rely on an array of double precision interleaved
    ' [X1, Y1, X2, Y2, ... Xn, Yn] coordinates.
    Dim x1 As Double = fs.Vertex(0)
    Dim y1 As Double = fs.Vertex(1)
    
    ' The shaperange indexes values based on the coordinate index,
    ' not the position in the double array.
    ' Do access the coordinate directly from the Vertex, multiply by 2.
    x1 = fs.ShapeIndices(2).StartIndex * 2
    y1 = fs.ShapeIndices(2).StartIndex * 2 + 1
    
    ' You can use the startindex and count in order to cycle values manually,
    ' but it can be confusing.  To make things simpler, the ShapeIndices support an 
    ' enumeration that allows cycling though the shapes, parts and the vertices.
    For Each shape As ShapeRange In fs.ShapeIndices
        If shape.Intersects(bounds) Then
            For Each part As PartRange In shape.Parts
                For Each vertex As Vertex In part
                    If vertex.X > 0 AndAlso vertex.Y > 0 Then
                        ' do something
                    End If
                Next
            Next
        End If
    Next
End Sub

Last edited Mar 5, 2010 at 6:05 PM by Shade1974, version 4

Comments

No comments yet.