摘 要:在批量多边形净面积计算中,按毛面积进行排序,从毛面积最小多边形开始处理计算,可以高效、准确的计算多边形的净面积。
关键词:毛面积 净面积 面积排序
中图分类号:P271 文献标识码:A 文章编号:1672-3791(2012)11(a)-0033-02
在地籍调查、工程测量等工作中,经常需要批量计算多边形的净面积(多边形毛面积是指本多边形拐点所围成的面积;多边形净面积是指多边形的毛面积扣除其内部全部岛的净面积。多边形内部无岛时毛面积和净面积相等)。如果孤立的随机的逐个多边形的净面积计算,即使采用编程方式进行,编程过程也会变得较为复杂。如图1,预计算多边形A的净面积,首先获得多边形A的毛面积,通过搜索可以获取多边形A内有3个岛,因为不知道每个岛的净面积是否已计算,则需要计算每个岛的净面积,计算每个岛的净面积时还要考虑其内部是否还有岛,如此循环、递归下去,编程的难度偏大,程序的运行效率也会较低。
1 多边形毛面积排序法进行净面积计算的原理
在对多变形面积进行计算前,多边形是经过拓扑检查的,即多边形之间的关系只存在包含、邻接和相离的关系,不存在多边形相交或重复的情况。在多边形净面积计算前,计算每个多变形的毛面积,按毛面积的大小对多边形进行排序。在计算多边形的净面积时,从面积最小的多边形开始计算,依次进行。在计算一个多边形时,搜索其内部的多边形,读取每个内部多边形的净面积,并求取内部多边形的净面积之和,则本多边形的净面积为本多边形毛面积减去其内部多边形的净面积之和,然后将本多边形的净面积作为本多边形的属性,赋值在本多边形上。采用本方法计算多边形净面积时,不用考虑其内部多边形是否还存在岛,只要简单读取其内部多边形的净面积即可,因为本多边形内部的多边形,面积一定比本多边形要小,所以其一定在本多边形净面积计算之前就已经计算了净面积,直接读取,无需再计算,即使其内部还用多层嵌套。如图1中,预计算多边形C的净面积,首先计算多边形C的毛面积,因其内部没有岛,所以其毛面积即为净面积,作为属性赋值给其本身;预计算多边形B的净面积,首先计算多边形B的毛面积,因多边形B的毛面积比多边形C的毛面积大,所以多边形C的毛面积必然在多边形B之前计算,所以直接扣除其内部岛多边形C的净面积,作为属性赋值给其本身;预计算多边形A的净面积,首先计算多边形C的毛面积,因多边形B、C、D的净面积已经计算,所以直接扣除其内部岛多边形B、C、D的净面积之和,作为属性赋值给其本身。
2 多边形毛面积排序法进行净面积计算程序设计原理
根据这一原理,采用VB2010和AutoC AD2008设计了多边形净面积计算程序,主要步骤如下。
Dim Reg1 As RegAppTable = trans.GetObject(db.RegAppTableId, OpenMode.ForWrite)
Dim App1 As New RegApp TableRecord
If Not Reg1.Has("Area") Then
App1.Name="Area"
Reg1.Add(App1)
trans.AddNewlyCreatedDBObject(App1,True)
End If
Dim Val1 As TypedValue=New TypedValue(DxfCode.Start,"Polyline,Lwpolyline")
Dim Val() As TypedValue={Val1}
Dim Filter1 As New SelectionFilter(Val)
Dim Optsel As New PromptSelectionOptions
Dim Ss1,Ss2 As SelectionSet
Dim Res1 As PromptSelectionResult =Ed.GetSelection(Optsel,Filter1)
If Res1.Status<>PromptStatus.OK Then
Exit Sub
End If
Ss1=Res1.Value
Dim I As Long
Poly2d=CType(trans.GetObject(PolyId1.Item(I),OpenMode.ForRead), Polyline2d)
Len1=Poly2d.Length
Catch
End Try
Try
Poly=CType(trans.GetObject(PolyId1.Item(I),OpenMode.ForRead), Polyline)
Len1=Poly.Length
Catch
End Try
Try
Cur1=CType(trans.GetObject(PolyId1.Item(I),OpenMode.ForWrite),Curve)
Catch
End Try
Area1=Cur1.Area
PtC1=SubFun.Ptc3DOfCollection(PolyId1.Item(I))
Pt1=Cur1.GeometricExtents.MinPoint
Pt2=Cur1.GeometricExtents.MaxPoint
Pt1=New Point3d(Pt1.X-1,Pt1.Y-1,0)
Pt2=New Point3d(Pt2.X+1,Pt2.Y+1,0)
Tools.ZoomWindow(Pt1,Pt2)
Res2=Ed.SelectWindowPolygon(PtC1,Filter1)
If Res2.Status<>PromptStatus.OK Then
GoTo Skip1
End If
Ss2=Res2.Value
For J=0 To Ss2.Count-1
Area3=0
If Ss2.Item(J).ObjectId=PolyId1.Item(I) Then
Area2=Area2+Area3
Next
Area1=Area1-Area2
Dim DxfArea As New ResultBuffer
DxfArea.Add(New TypedValue(CInt(1001),"Area"))
DxfArea.Add(New TypedValue(CInt(1040),Area1))
Cur1.XData=DxfArea
3 多边形毛面积排序法进行净面积计算的示例
如图1所示,采用多边形毛面积排序法进行净面积计算的结果如表1。
4 结语
多边形毛面积排序法进行净面积计算,从面积最小的多边形开始进行,所以多边形内部岛的净面积计算一定在本多边形之前进行,所以在计算本多边形时就无需考虑岛的净面积计算,而直接读取所有岛的净面积即可,免去了原本复杂的循环、递归运算,使得程序的原理简单,设计方便,运行高效。
参考文献
[1](美)Bill Evjen,Rockford Lhotka,Billy Hollis等,著. Visual Basic2005高级编程[M].杨浩,吴雷译.北京:清华大学出版社,2006.
[2] (美)David F,Rogers,著.计算机图形学的算法基础[M].北京:机械工业出版社,2002.
[3]曾洪飞,张帆,卢择临.AutoCAD VBA &VB.NET开发基础教程与实例[M].北京:中国电力出版社,2008.