2.3.1
Symbol对象
Symbol对象是图层中的图元的显示符号,,在跟踪层中,每个几何对象用一个Symbol对象描述,在Map1.Layers的图层中,每个图层一个Symbol属性,全图层的图元共用一个Symbol对象。
1 Symbol.SymbolType属性
Map1.Layers中的矢量图层,一个图层中只能有一种类型的图元,按图元的类型分,图层可以分为三种类型:点、线、面,用图层中的Symbol.SymbolType的值标识,可用如下程序判断矢量图层中图元的类型:
Private Sub Command1_Click()
Dim l As Object
Dim ftype As String
For Each l In Map1.Layers
If l.LayerType = moMapLayer Then
Select Case l.Symbol.SymbolType
Case moFillSymbol ‘2
ftype = “面”
Case moLineSymbol ‘1
ftype = “线”
Case moPointSymbol ‘0
ftype = “点”
End Select
End If
Next l
End Sub
2 Symbol.Style属性
Symbol.Style的值按矢量图层的类型(点、线、面)分成三组,用于点图层,指定点的绘制符号;用于线图层,指定线的类型;用于面图层,指定填充图案。各组的义如下:
Symbol.symbolType = 0 (点) 符号常量 值 符号 moCircleMarker 0 圆 moSquareMarker 1 长方形 moTriangleMarker 2 三角形 moCrossMarker 3 十字线 moTrueTypeMarker 4 文字 |
Symbol.symbolType = 1 (线) 符号常量 值 符号 moSolidLine 0 moDashLine 1 moDotLine 2 moDashDotLine 3 moDashDotDotLine 4
|
Symbol.SymbolType = 2 (面)
符号常量 值 填充方法
moSolidFill 0 Solid
moTransparentFill 1 Transparent
moHorizontalFill 2 Horizontal
moVerticalFill 3 Vertical
moUpwardDiagonalFill 4 Upward Diagonal
moDownwardDiagonalFill 5 Downward Diagonal
moCrossFill 6 Cross
moDiagonalCrossFill 7 Diagonal Cross
moLightGrayFill 8 Light Gray Fill
moGrayFill 9 Gray Fill
moDarkGrayFill 10 DarkGray Fill
请在MapObjects2的帮助中索引 FillStyle Constants LineStyle Constants MarkerStyle Constants查看三组图案
4 Symbol. Color 属性
Color As OLE_COLOR
用Color指定的颜色绘制Symbol.Style指定的符号(线、填充图案)。
例 为点图层、线图层、面图层设置显示风格及颜色.(参见光盘中的Symbol目录中的程序)
Dim sym As MapObjects2.Symbol
Private Sub Form_Load()
Dim strDataPath As String
Dim dc As New MapObjects2.DataConnection
Dim lyr As New MapObjects2.MapLayer ' 创建图层对象
strDataPath = ReturnDataPath("world") ' 数据库目录名
'dc.Database = "d:/mobook/sample/data/world"
dc.Database = strDataPath
If Not dc.Connect Then End
Set lyr.GeoDataset = dc.FindGeoDataset("Country") '面图层
Set sym = lyr.Symbol
sym.Style = moVerticalFill
sym.Color = 255
Map1.Layers.Add lyr '在地图窗口中添加Country图层
Set lyr = New MapLayer
Set lyr.GeoDataset = dc.FindGeoDataset("rivers") '线图层
lyr.Symbol.Style = moSolid
lyr.Symbol.Color = moBlue
Map1.Layers.Add lyr
Set lyr = New MapLayer
Set lyr.GeoDataset = dc.FindGeoDataset("Cities") '点图层
Set sym = lyr.Symbol
sym.Style = moCircleMarker
sym.Color = moYellow
Map1.Layers.Add lyr
Set lyr = New MapLayer
Set lyr.GeoDataset = dc.FindGeoDataset("Lakes") '面图层
Map1.Layers.Add lyr ' 每次运行显示不同的颜色及图案
End Sub
多次运行这些程序可以看出,Map1.Layers.Item(“Lakes”) 图层没有指定Symbol.Color的值,每次运行Lakes层的颜色及图案都不同。
从这个例子的运行结果可见,Map1.Layers.Item(“Lakes”).Symbol是一个图层全部地图要素的共用符号,因此全图层的所有的Lake都显示成同一种颜色。下一节的专题地图制作中,每个图层对应一个Symbol数组,要素用多个Symbol符号绘制。
习题
1 编写程序实现Symbol目录中样例程序的功能,每个图层的Symbol指定各种值,观看显示效果。
2 以习题1为基础,为图层的Symol.Size 、Symol.OutLine、Symol.Rotation设置值。总结出这3个属性的含义。
2.3.2
专题地图制作
在Mapobjects中,描述数据与地图符号之间的映射关系的对象称为Renderer,用于制作专题地图,又称为专题地图制作器。MapObjects可制作九种专题地图,对应的Renderer是:
MapObjects的专题地图制作器对象 |
|
对象名称 |
解释 |
ValueMapRenderer |
唯一值 |
ClassBreaksRenderer |
范围值 |
DotDensityRenderer |
点密度图 |
ChartRenderer |
饼图和棒图 |
LabelRenderer |
文字标签 |
LabelPlacer |
文字标签 |
GroupRenderer |
用于多个Renderer |
EventRenderer |
用于测量数据 |
ZRenderer |
用Z维数据作专题图 |
样例在ThemeMap目录中,样例中地图窗口中Layers(“China”)图层是中国省级行政区划图,图层的属性数据表中Code和uid 字段数据用于制作专题地图。样例显示窗口中的每个按钮制作一种类型专题地图。先运行样例程序获得每种专题地图的感性认识。
图层的Layers(n).Renderer属性是专题地图制作器。以下语句定义了地图数据与制图符号之间的映射关系:
Dim strings As New MapObjects2.strings ‘字符串集合
Set ly = Map1.Layers(“
ly.Renderer.Field = “Code” ‘制作专题地图的数据字段名
ly.Renderer.Value(i) = Val(strings(i)) ‘从Code字段映射
ly.Renderer.Symbol(i).Color = moRed + i * 2 ‘显示的颜色
1 ValueMapRenderer 专题地图
ValueMapRenderer专题地图称为唯一值专题地图,制图属性字段的一个唯一值用一个地图符号表示,即重复的值用同一个符号表示,制图符号与属性值之间是一对多的关系。提取一个字段中的非重复值,MapObjects提供了Strings集合对象,加入到集合中的字符串若与先前加入的字符串重复,则无效。
ValueMapRenderer对象的属性中有两个数组:Symbol与Value;它们定义制图符号与属性值的对应关系,元素个数都是ValueMapRenderer.ValueCount。Value数组储存制图字段的唯一值,是Varant类型。
Private Sub Command1_Click() ‘ValueMapRender制作专题地图
Dim strings As New MapObjects2.strings
Dim ly As MapObjects2.MapLayer
Set ly = Map1.Layers(“
Set recs = ly.Records
‘ 寻找Code字段中的非重复值
Do While Not recs.EOF
strings.Add Str(recs(“Code”).Value)
recs.MoveNext
Set ly.Renderer = New ValueMapRenderer
ly.Renderer.Field = “Code” ‘制作专题地图的数据字段名
‘ add the unique values to the renderer
ly.Renderer.ValueCount = strings.Count ’在使用Value及Symbol数组前执行
For i = 0 To strings.Count – 1 ‘共有Count个非重复值
ly.Renderer.Value(i) = Val(strings(i)) ‘从Code字段映射
ly.Renderer.Symbol(i).Color = moRed + i * 2 ‘显示的颜色
Next i
Map1.Refresh
End Sub
2 ClassBreaksRenderer专题地图
ClassBreaksRenderer对象根据数据的逻辑分组,每组用一个符号(或颜色)显示地图。对于每一种分组方案,必须指定分组数,每组数值的上下界,每组对应的地图符号(或颜色)。常见的数据分组方法有:等间距法、分位数法、标准方差法、自然分割法。
Private Sub Command2_Click() ‘ClassBreakRenderer专题地图
Dim stats As MapObjects2.Statistics
Dim r As MapObjects2.ClassBreaksRenderer
Dim ly As MapObjects2.MapLayer
Set ly = Map1.Layers(“China”) ‘中国省级政区图,面图层
Set ly.Renderer = New MapObjects2.ClassBreaksRenderer
ly.Renderer.Field = “uid” ‘制作专题数据字段
Set r = ly.Renderer
Set stats = ly.Records.CalculateStatistics(“uid”) ‘计算uid字段的统计值
Dim breakVal As Double
breakVal = stats.Min
r.BreakCount = 7 ‘数据分组数
For i = 0 To 6 ‘ 数组的下标从0开始
r.Break(i) = breakVal + (stats.Max - stats.Min) / 7 * i ‘数据分组界限
Next i
r.RampColors moRed, moBlue ‘各组显示颜色渐变
Map1.Refresh
End Sub
RampColors是ClassBreaksRenderer对象的方法,在设置完数据分组数之后,通过此方法提供第一组的起始颜色与最后一组的终止颜色,就可以向所有的分组提供渐变的颜色。
3 DotDensityRenderer专题地图
DotDensityRenderer制作点密度专题地图,原图应该是面要素图层。根据制图字段数据及每点代表的值计算各个区域点数,在区域中布点形成点密度图。因此DotValue、Field字段必须赋值。
Private Sub Command3_Click() ‘制作DotDensityRenderer专题地图
Dim stats As MapObjects2.Statistics
Dim r As New MapObjects2.DotDensityRenderer
Dim ly As MapObjects2.MapLayer
Set ly = Map1.Layers(“China”) ‘中国省级政区图,面图层
ly.Symbol.Color = moWhite ‘面图层的区域填充色
Set stats = ly.Records.CalculateStatistics(“uid”) ‘计算uid字段的统计值
r.Field = “uid” ‘专题数据字段
r.DotValue = (stats.Min + (stats.Max - stats.Min) / 2) / 20
r.DotColor = moRed
r.DotSize = 3
Set ly.Renderer = r
Map1.Refresh ‘刷新显示
End Sub
4 LabelRenderer标注
LabelRenderer用于标注与图层中图元相关联的文字。
(1) 单个Symbol标注
在一个图层中全部文字注记使用一个Symbol标注时,全部文字规格相同,如下段程序所示。
Private Sub Command4_Click() ‘LabelRenderer使用一个Symbol标注文字
Dim r As New MapObjects2.LabelRenderer
Dim ly As MapObjects2.MapLayer
Set ly = Map1.Layers(“China”) ‘中国省级政区图,面图层
ly.Symbol.Color = moWhite ‘面图层的区域填充色
r.Field = “name” ‘省名字段
r.AllowDuplicates = True ‘允许重复文字显示
Set ly.Renderer = r
Map1.Refresh ‘刷新显示
End Sub
(2) Symbol数组标注
在一个图层中文字注记使用Symbol数组标注时,文字可有不同的规格j及显示特性。下段将同China图层文字用不同的颜色标注。
Private Sub Command5_Click() ‘ LabelRenderer2用多个Symbol标注文字
Dim r As New MapObjects2.LabelRenderer
Dim ly As MapObjects2.MapLayer
Set ly = Map1.Layers(“China”) ‘中国省级政区图,面图层
ly.Symbol.Color = moWhite ‘面图层的区域填充色
r.Field = “name” ‘省名字段,标注文字所在字段
r.SymbolCount = 4 ‘赋值后,Symbol属性当数组使用
r.SymbolField = “SymbolIdex” ‘数据库中的Symbol索引号字段名
r.Symbol(1).Color = moRed
r.Symbol(2).Color = moBlue
r.Symbol(3).Color = moGreen
r.AllowDuplicates = True ‘允许重复文字显示
Set ly.Renderer = r
Map1.Refresh ‘刷新显示
End Sub
缺省情况下LabelRenderer.symbol是只有一个元素的数组,等价于简单变量,执行语句
r.SymbolCount = 4
后,Symbol具有4个元素,起始元素的下标是0。语句
r.SymbolField = “SymbolIndex” ‘SymbolIndex是China.dbf中的字段名
建立标注文字字段(Name)的值与Symbol数组元素之间的对应关系,SymbolIndex字段的值是Symbol数组元素的下标。例如,China.dbf表5号记录Name字段的值是”黑龙江”、SymbolIndex的值是2,则标注”黑龙江”时使用Symbol(2)。
(3)比例标注与非比例标注
标注文字的大小随地图的缩放而变化,称为比例标注,用语句
LabelRenderer.Symbol.Height = 1200 ‘采用地图数据的长度单位
设置标注文字的尺寸。
标注文字的大小不随地图的缩放而变化,称为非比例标注,用语句
LabelRenderer.Symbol.Size = 14 ‘ 以屏幕或纸张的点数位单位
设置标注文字的大小。LabelRenderer.Symbol在缺省情况下是非比例标注,文字的大小使用Windows操作系统提供的标准值。
5 LabelPlacer文字标注
MapObjects2.LabelPlacer对象与LabelRenderer基本相同,对地图提供基于属性的标注。LabelPlacer还提供了一LabelRenderer所不具有的功能,主要有以下几点:
可将标注至于文字的上方、下方或要素上。
可对标注进行掩膜处理,让标注文字下层的要素不可见。
具有自动调整重合功能,使标注自动调整位置,避免文字重叠。
Private Sub Command6_Click() ‘LabelPlacer文字标注
Dim r As New MapObjects2.LabelPlacer
Dim ly As MapObjects2.MapLayer
Set ly = Map1.Layers(“China”) ‘中国省级政区图,面图层
ly.Symbol.Color = moWhite ‘面图层的区域填充色
r.Field = “name” ‘省名字段
r.ValueCount = 4 ‘赋值后,Symbol及Value属性当数组使用
r.ValueField = “name” ‘数据库中的Symbol索引号字段名
r.Symbol(0).Font.Size = 16
r.Symbol(1).Color = moRed
r.Symbol(2).Color = moBlue
r.Symbol(3).Color = moGreen
r.Value(0) = “北京” ‘这四个标注使用上面的四个Symbol
r.Value(1) = “*”
r.Value(2) = “黑龙江”
r.Value(3) = “广东”
‘其余的标注使用LabelPlacer.DeFaultSymbol
r.AllowDuplicates = True ‘允许重复文字显示
Set ly.Renderer = r
Map1.Refresh ‘刷新显示
End Sub
6 CharRenderer专题地图
CharRenderer从属性表中取数据制作饼图和柱状图。
(1) 棒图
Private Sub Command7_Click() ‘ChartRenderer制作棒状统计地图
Dim cr As New MapObjects2.ChartRenderer
cr.ChartType = moBar ‘制作棒图
cr.BarHeight = Map1.Height * 0.007
cr.BarWidth = Map1.Width * 0.0015
cr.FieldCount = 3 ‘使用3个作图字段
cr.Field(0) = “gdp
cr.Field(1) = “gdp
cr.Field(2) = “gdp
cr.Color(0) = QBColor(2) ‘棒体颜色
cr.Color(1) = QBColor(3)
cr.Color(2) = QBColor(4)
Map1.Layers(“china”).Symbol.Color = moWhite ‘面图层的区域填充色
Set Map1.Layers(“china”).Renderer = cr
Map1.Refresh
End Sub
(2) 饼图
将棒图程序中的前三条语句替换后可的饼图显示程序如下:
Private Sub Command8_Click() ‘ChartRender制作饼图
Dim cr As New MapObjects2.ChartRenderer
cr.ChartType = moPie ‘制作饼图
cr.MinPieSize = Map1.Height / 400
cr.MaxPieSize = Map1.Height / 200
cr.FieldCount = 3 ‘使用3个作图字段
cr.Field(0) = “gdp
cr.Field(1) = “gdp
cr.Field(2) = “gdp
cr.Color(0) = QBColor(2) ‘棒体颜色
cr.Color(1) = QBColor(3)
cr.Color(2) = QBColor(4)
Map1.Layers(“china”).Symbol.Color = moWhite ‘面图层的区域填充色
Set Map1.Layers(“china”).Renderer = cr
Map1.Refresh
End Sub
7 GroupRenderer专题地图
前面的几种Renderer只能制作单类型的专题地图,有时需要制作复合类型的专题地图,以中国政区图为例,不仅要用不同的颜色表示每个省区,还要表示出每个省区三年的GDP组合柱状图。可用GroupRenderer来完成这一工作,创建一个ValueMapRenderer实例,对省区进行着色,创建一个ChartRenderer实例,制作各省的柱状图,两个实例都加入到GroupRenderer实例中,最后将GroupRenderer实例写入到MapLayers(“china”).Renderer中。
下面的程序给出了实际工作代码:
Private Sub Command9_Click() ‘ GroupRenderer专题图
Dim cr As New MapObjects2.ChartRenderer
cr.ChartType = moBar ‘制作棒图
cr.BarHeight = Map1.Height * 0.007
cr.BarWidth = Map1.Width * 0.0015
cr.FieldCount = 3 ‘使用3个作图字段
cr.Field(0) = “gdp
cr.Field(1) = “gdp
cr.Field(2) = “gdp
cr.Color(0) = QBColor(2) ‘棒体颜色
cr.Color(1) = QBColor(3)
cr.Color(2) = QBColor(5)
Dim strings As New MapObjects2.strings
Dim gr As New MapObjects2.GroupRenderer
Dim vr As New MapObjects2.ValueMapRenderer
Dim ly As MapObjects2.MapLayer
Set ly = Map1.Layers(“
Set recs = ly.Records
‘ 寻找Code字段中的非重复值
Do While Not recs.EOF
strings.Add Str(recs(“Code”).Value)
recs.MoveNext
vr.Field = “Code”
vr.ValueCount = strings.Count
For i = 0 To strings.Count - 1
vr.Value(i) = Val(strings(i))
vr.Symbol(i).Color = moRed + i * 2
Next i
gr.Add vr
gr.Add cr
Set ly.Renderer = gr
Map1.Refresh
End Sub