绘制复杂的标记

本节内容可以参考CaseStudy目录下的文件"地图.Table"的示例三十一。

本节使用了一些GDI+的知识,如果忘记了,可以参考:GDI+快速入门

本节的任务是实现手工"勾选"城市,且为被勾选的城市绘制一个特别的标记:

1、将Map控件的"地图来源"属性设置为"None"

2、将窗口的AfterLoad事件代码设置为:

Dim map As GeoMap = e.Form.Controls("Map1").GeoMap
Dim
layer As New VectorLayer()
map.Layers.Add(layer)
layer.Style.Stroke.Color = Color.Gray
layer.LabelVisibility = LabelVisibility.AutoHide
layer.LabelStyle.ForeColor = Color.Green

'
绘制省级行政区域
For
Each dr As DataRow In DataTables("行政区域").Select("level= 1")
    layer.Items.Add(map.CreatePolygon(dr(
"geometry"), 5))
Next

'
绘制城市
Vars(
"MarkIndex") = 0 '用一个Var变量记录自定义形状的当前序号
For
Each dr As DataRow In DataTables("").DataRows
   
Dim mark As New VectorPlacemark()
    mark.Tag = dr(
"") '将城市名作为标记的Tag
    mark.Geometry =
New GeoPoint(dr("经度"), dr("纬度"))
    mark.Marker.Shape = MarkerShape.Circle
'默认标记为圆圈
    mark.Marker.Caption = dr(
"")
   
If dr("标记") Then
        mark.Marker.LabelPosition = LabelPosition.Bottom
'自定义标记的标题位置靠下
        Vars(
"MarkIndex") = Vars("MarkIndex") + 1 '递增序号
        mark.Marker.Size =
New SizeF(20, 27.32f) '设置标记大小
        mark.Marker.Shape = MarkerShape.Custom
'指定标记采用使用自定义形状
       
Dim ShapeTag As String = CExp("{'name':'{0}','index':{1}}", dr(""), Vars("MarkIndex")) 'json格式传递城市名和序号
        mark.Marker.CustomShape = map.CreateMarkShape(ShapeTag)
'创建自定义形状,将城市名和序号作为形状的tag
        mark.Style.Stroke.Color = Color.DarkGray
'设置边框颜色
        mark.Style.BackColor = Color.FromArgb(192, 128 + Rand.Next(127), 128 + Rand.Next(127), 128 + Rand.Next(127))
'生成随机背景色
   
Else
        mark.Marker.LabelPosition = LabelPosition.Right
'普通标记的标题靠右
        mark.Marker.Size =
New Size(8, 8) '设置普通标记的大小
   
End If
   
If dr("省会") = False And dr("标记") = False Then
        mark.Lod =
New Lod(0, 0, 4, 20) '未勾选的非省会城市在缩放比例达到4以后才显示       
   
End If
    layer.Items.Add(mark)

Next

提示:这里演示了如何用json传递多个数据,关于json可参考: json解析

3、将Map控件的MouseClick事件代码设置为:

Dim map As GeoMap = e.Sender.GeoMap
Dim
ifo As HitTestInfo = map.HitTest(e.Sender.MousePosition)
If
ifo IsNot Nothing AndAlso ifo.Vector IsNot Nothing Then
   
If TypeOf ifo.Vector Is VectorPlacemark Then
       
Dim mark As VectorPlacemark = ifo.Vector
       
Dim dr As DataRow = DataTables("").Find(" = '" & mark.Tag & "'")
       
If dr IsNot Nothing Then
            dr(
"标记") = Not dr("标记")|
           
If dr("标记") Then
                mark.Marker.LabelPosition = LabelPosition.Bottom
'标题靠下
                mark.Marker.Size =
New SizeF(20, 27.32f)
                Vars(
"MarkIndex") = Vars("MarkIndex") + 1 '递增序号
               
Dim ShapeTag As String = CExp("{'name':'{0}','index':{1}}", dr(""), Vars("MarkIndex")) 'json格式传递城市名和序号
                mark.Marker.Shape = MarkerShape.Custom
'指定采用标记使用自定形状
                mark.Marker.CustomShape = map.CreateMarkShape(ShapeTag)
'创建自定义形状,将城市名和序号作为tag
                mark.Style.Stroke.Color = Color.DarkGray
'设置边框颜色
                mark.Style.BackColor = Color.FromArgb(192, 128 + Rand.Next(127), 128 + Rand.Next(127), 128 + Rand.Next(127))
'生成随机背景色
                mark.Lod =
New Lod(0, 0, 0, 20) '始终显示已经勾选的城市
           
Else '未勾选的标记恢复默认设置:
                mark.Marker.LabelPosition = LabelPosition.Right
                mark.Marker.Size =
New SizeF(8, 8)
                mark.Marker.Shape = MarkerShape.Circle
                mark.Marker.CustomShape =
Nothing
                mark.Style.Stroke.Color = Color.Gray
                mark.style.BackColor = Color.Transparent
               
If dr("省会") = True Then
                    mark.Lod =
New Lod(0, 0, 0, 20) '省会城市始终显示
               
Else
                    mark.Lod =
New Lod(0, 0, 4, 20) '未勾选的非省会城市,缩放比例达到4才显示
               
End If
           
End If
       
End If
   
End If
End
If

4、将Map控件的GetDrawingBounds事件代码设置为:

e.Bounds = New RectangleF(e.Bounds.X , e.Bounds.Y - e.Bounds.Height/2, e.Bounds.Width, e.Bounds.Height)

提示:

5、将Map控件的OwerDrawMark事件代码设置为:

Dim jo As JObject = JObject.Parse(e.ShapeTag)
Dim
city As String = jo("name") '获得城市名,可以用于从数据表中找到对应的数据
Dim
index As Integer = jo("index") '获得自定义标记的序号
'
要绘制的形状比较复杂,所以下面的绘制代码使用了GraphicsPath,理解不了 也没有关系,直接套用就行:
Dim
path As New GraphicsPath()
Dim
rect As RectangleF = New RectangleF(e.bounds.Location, New SizeF(20, 20))
path.AddArc(rect, 120, 300)
rect =
New RectangleF(e.bounds.Right - 10, e.bounds.Bottom - 10, 20, 20)
path.AddArc(rect, - 120, - 60)
rect =
New RectangleF(e.bounds.Left - 10, e.bounds.Bottom - 10, 20, 20)
path.AddArc(rect, 0, - 60)

Using
path
   
Using brush As New SolidBrush(e.style.BackColor)
        e.Graphics.FillPath(brush, path)
   
End Using
   
Using pen As New Pen(e.style.Stroke.Color, e.style.Stroke.Width)
        e.Graphics.DrawPath(pen, path)
   
End Using
    rect =
New RectangleF(e.bounds.Location, New SizeF(20, 20))
   
Using brush As New SolidBrush(e.style.ForeColor)
       
Using sf As New StringFormat()
            sf.Alignment = StringAlignment.Center
            sf.LineAlignment = StringAlignment.Center
            e.Graphics.DrawString(index.ToString(), e.style.Font, brush, rect, sf)
       
End Using
   
End Using
End
Using

提示:

用GDI+绘制复杂的形状很灵活,但如果形状较为复杂,则需要你具备一些几何知识,对于普通用户可以考虑接用绘图软件绘制形状,保存为一个图片文件,然后:

1、在Map控件中直接使用图片文件作为标记,参考:使用图片标记,下一节就会使用图片实现类似的标记功能。

2、或在OwerDrawMark事件中用DrawImage方法为标记绘制图片 和(或)标题,这是最灵活的。

 


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