合并文本和形状

本节内容可以参考文件"\CaseStudy\流程图\纯代码流程图\纯代码绘制之三.Table"

文本通常是显示在形状之上的,所以将草图转换为数据表内容时,可以忽略文本对象,直接将文本内容填入到所属形状的文本列。

这是新的草图,已经去掉了文本对象的坐标:

现在数据表内容变得更为简洁:

绘制代码如下,要比之前的代码稍微复杂点(因为定位箭头的文本位置比较麻烦),另外这里说的合并文本和形状,仅止于数据表,是假合并,文本和形状依然是独立的,真正的合并下一节再介绍:

'初始化地图控件,不是必须的,只是使得地图控件更适合作为流程图控件使用:
Dim
map As GeoMap = e.Form.Controls("Map1").GeoMap
map.UseGallPetersProjection =
True '采用Gall Peters投影方式
map.Viewport.Limits.MaxLat = 60
'排除高纬度地区,因为高纬度地区变形大
map.Viewport.Limits.MinLat = -60
map.Zoom = 12
'缩放指数设置为12,留足够的区间用于放大和缩小
map.CenterTo( - 160, 50)
'中心点设置在有效区域的左上,因为通常都是往右下绘制,同时也留有一定的余地往左上绘制
'
增加矢量层:
Dim
layer As New VectorLayer()
map.Layers.Add(layer)
layer.Style.Stroke.Width = 2
layer.Style.Font =
New Font("微软雅黑", 12)
'
用代码绘制流程图,注意以下定位均采用像素,在绘制时候要转为经纬度,
Dim
xStart As Integer = 50 '本流程图整体是从左到右,所以起点在左中位置
Dim
yStart As Integer = 200
Dim
xStep As Integer = 96 '默认形状宽度,也是箭头的默认长度
Dim
yStep As Integer = 64 '默认形状高度,宽高比大概是3:2, 96*2/3 = 64
For
Each dr As DataRow In DataTables("流程图").DataRows '绘制流程图
   
Dim gps As New List(Of GeoPoint)
   
Dim pts() As String = dr("位置").Split(",")
   
For idx As Integer = 0 To pts.Length - 1 Step 2
       
Dim dx As Integer = xStart + Val(pts(idx)) * xStep
       
Dim dy As Integer = yStart + Val(pts(idx + 1)) * yStep
       
Dim p As New Point(dx, dy)
        gps.Add(map.ToGeoPoint(p))
   
Next
   
Dim item As VectorItem = Nothing
   
'先绘制形状
   
Select Case dr("类型")
       
Case "四边形"
            item = map.CreateRectangle(gps(0), gps(1))
       
Case "菱形"
            item = map.CreateDiamond(gps(0), gps(1))
       
Case "箭头"
            item = map.CreateLineWithArrow(gps)
   
End Select
   
If item IsNot Nothing Then
        item.Tag = dr
'tag设置为对应的数据行,用于响应事件
        layer.Items.Add(item)
   
End If
   
'再绘制文本
   
If dr.IsNull("文本") = False Then
       
Dim txt As New VectorPlacemark()
        txt.Marker.Shape = MarkerShape.Custom
        txt.Marker.CustomShape = map.CreateTextShape(dr(
"文本"))
       
If dr("类型") = "文本" Then '如果类型为文本,也就是独立的文本,不属于任何形状的文本,这个例子其实没有
            txt.Geometry = gps(0)
       
ElseIf item IsNot Nothing Then '如果是其他形状,且已经成功生成形状
           
If dr("类型") = "箭头" Then'箭头可能是折线,取线条第一段的中心作为文本位置
               
Dim dx1 As Integer = xStart + Val(pts(0)) * xStep
               
Dim dy1 As Integer = yStart + Val(pts(1)) * yStep
               
Dim dx2 As Integer = xStart + Val(pts(2)) * xStep
               
Dim dy2 As Integer = yStart + Val(pts(3)) * yStep
               
Dim dx As Integer = dx1 + (dx2 - dx1) / 3 '文本位置不完全在线段中心,而是偏向起点
               
Dim dy As Integer = dy1 + (dy2 - dy1) / 3
               
If dx1 = dx2 Then
                    dx = dx + 15
'如果是垂直线,则文本显示在线条右侧
               
Else
                    dy = dy - 15
'如果是水平线,则文本显示在线条上侧
               
End If
               
Dim p As New Point(dx, dy)
                txt.Geometry = map.ToGeoPoint(p)
           
Else '如果是其他形状(通常是四边形或菱形),取形状中心作为文本文职
               
Dim cp = item.Geometry.Center '获取形状的中心位置坐标,注意用法!!!!
                txt.Geometry =
New GeoPoint(cp.X, cp.Y) '将文本位置设置为形状的中心
           
End If
       
End If
       
If txt IsNot Nothing Then
            txt.Tag = dr
            layer.Items.Add(txt)
       
End If
   
End If
Next


本页地址:http://www.foxtable.com/webhelp/topics/6179.htm