使用LayerInfo object 在map中添加栅格图层
对于一副栅格图像,在Mapinfo里配准后就会发现在原来的.bmp或者.jpg文件的基础上会新生成一个同名的.tab文件。
mapX支持的栅格格式还是比较多的,包括:
l TIFF (*.tif)
l MrSID (*.sid)
l ECW (*.ecw)
l Spot (*.bil)
l Jpeg (*.jpg)
l PCX (*.pcx)
l GIF (*.gif)
l Windows Bitmap (*.bmp)
l PNG (*.png)
l Photoshop (*.psd)
l Targa (*.tga)
l Windows Metafile (*.wmf)
l JPEG200 (*.jp2)
如果是未配准的栅格图像,用LayerInfo object加载图层时需要将LayerType设为miLayerInfoTypeRaster,如果是做了配准的图像,即拥有.tab文件,就可以通过LayerType为miLayerInfoTypeTab来添加。这里需要指定一个类型为miLayerInfoTypeTab的LayerInfo,然后在AddParameter里指定文件路径即可。如下例:
DimAs Object
LInfo = New
LInfo.Type = miLayerInfoTypeTab
LInfo.AddParameter("FileSpec", App.Path + "/MAP/TEST.TAB")
Map.Layers.Add(LInfo)
LInfo = Nothing
这里需要注意的是栅格图像的配准至少要有四个控制点,因为在mapInfo下加三个控制点就能显示,但这并不意味着在mapX下也可以这样做。可以将raster的TAB文件用记事本打开,其基本内容很简单,主要信息就是控制点和投影、地图单位等信息。如下例:
!table
!version 300
!charset WindowsSimpChinese
Definition Table
File "d.jpg"
Type "RASTER"
(96686758.790000007,147368076) (0,0) Label "Pt 1",
(97313387.459999993,147467938.80000001) (636,464) Label "Pt 2",
(97101838.840000004,146804580.19999999) (18,460) Label "Pt 3",
(96987043.680000007,147744129.69999999) (624,22) Label "Pt 4",
(96980018.010000005,147320946.59999999) (318,212) Label "Pt 5",
(96995695.459999993,147086037.90000001) (154,310) Label "Pt 6"
CoordSys Earth Projection 8, 104, "m", -57, 0, 0.9996, 500000, 10000000
Units "m"
*注意:最后一个控制点记录后没有逗号。
做测试时,可以随便拿一个jpg或者bmp文件在mapInfo里做简单的配准,只要能和矢量叠加显示即可,但要保证至少4个控制点,否则mapX加载栅格时会出现Unexpected error in MapX(Error N10011),No source field specified(Error N1017),或者Invalid datum错误。
以下VB代码允许用户在地图框里通过拖绘矩形动态地生成一个栅格图层,栅格图像的位置及大小与拖绘的矩形一样。栅格文件使用bmp格式,用矩形的四个角的坐标为控制点,这里是人为生成对应于该栅格图层的.tab文件,然后把这个栅格图层加载进来,实现拖框画矩形栅格的功能。bmp文件是借助一个不可见的PictureBox来生成的,其中LoadPicture()和SavePicture()是VB自己的函数。其中Picture1.Picture = LoadPicture()把PictureBox的图片清空,CreateRasterBlock(Picture1.hdc, Rw, Rh)是自定义的函数,用于生成bmp位图。如果是VB.NET那么位图可以不借助picbox来做,这里借用Pixbox主要是为了在内存中生成一个bimap并且把它存储出来。另外pg是FoMain里的一个状态条,即ProgressBar。
PrivateSub Map_MouseUp(ByVal Button As Integer, ByVal Shift As Integer, ByVal x As Single, ByVal y As Single)
If Me.Map.CurrentTool = CREATE_RASTER_BLOCK_TOOL And mDown Then
Dim legth As Long
Me.Map.MapUnit = miUnitMeter
SBRX = x
SBRY = y
MBRX = MapX
MBRY = MapY
legth = Me.Map.Distance(MTLX, MTLY, MBRX, MBRY)
If
Dim Rh As Long, Rw As Long, Rn As Boolean 'Raster height,raster width ,raster name
Rw = Map.Distance(MTLX, MTLY, MBRX, MTLY) / RASTER_RESOLUTION
Rh = Map.Distance(MTLX, MTLY, MTLX, MBRY) / RASTER_RESOLUTION
Picture1.Width = Rw 如果Form的scalemode使用twip,而Picturebox使用Pixel,则存在像素于提的转换问题
Picture1.Height = Rh ' '1像素=20twip
Picture1.Picture = LoadPicture()
Rn = CreateRasterBlock(Picture1.hdc, Rw, Rh)
StatusBar.Panels.Item(2).Text = "Raster size:" + Str(Rw) + "x"
'—输出栅格文件
SavePicture(Picture1.Image, App.Path + "/MAP/TEST.BMP")
'生成对应的.tab文件
Dim FileNum As Integer, s As String
s = ""
s = "!table" + Chr$(13) + Chr$(10) + "!version 300"
s = s + vbCrLf + "!charset WindowsSimpChinese"
s = s + vbCrLf + vbCrLf
s = s + "Definition Table"
s = s + " File " + Chr$(34) + "TEST.BMP"
s = s + " Type " + Chr$(34) + "RASTER"
s = s + " (" + Left$(Trim$(Str$(MTLX)), 10) + "," + Left$(Trim$(Str$(MTLY)), 9) + ")" + " (" + Trim$(Str$(0)) + "," + Trim$(Str$(0)) + ") Label " + Chr$(34) + "Pt 1" + Chr$(34) + ","
s = s + " (" + Left$(Trim$(Str$(MBRX)), 10) + "," + Left$(Trim$(Str$(MBRY)), 9) + ")" + " (" + Trim$(Str$(Rw)) + "," + Trim(Str$(Rh)) + ") Label " + Chr$(34) + "Pt 2" + Chr$(34) + ","
s = s + " (" + Left$(Trim$(Str$(MTLX)), 10) + "," + Left$(Trim$(Str$(MBRY)), 9) + ")" + " (" + Trim$(Str$(0)) + "," + Trim$(Str$(Rh)) + ") Label " + Chr$(34) + "Pt 3" + Chr$(34) + ","
s = s + " (" + Left$(Trim$(Str$(MBRX)), 10) + "," + Left$(Trim$(Str$(MTLY)), 9) + ")" + " (" + Trim(Str$(Rw)) + "," + Trim$(Str$(0)) + ") Label " + Chr$(34) + "Pt 4"
s = s + " CoordSys Earth Projection 1, 104"
s = s + " Units " + Chr$(34) + "degree"
FileNum = FreeFile
Open App.Path + "/MAP/TEST.TAB" For Output As
Print #FileNum, s
Close #FileNum
'-- 变量复原
mDown = False
Map.CurrentTool = miPanTool
'加载栅格图
Dim LInfo As Object
LInfo = New
LInfo.Type = miLayerInfoTypeTab
LInfo.AddParameter("FileSpec", App.Path + "/MAP/TEST.TAB")
Map.Layers.Add(LInfo)
LInfo = Nothing
End If
End If
EndSub
以下是生成位图的代码:
DeclareFunction SetPixel Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal crColor As Long) As Long
DeclareFunction GetPixel Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long) As Long
GlobalAs Byte 'Raster Arry
GlobalAs Long 'Pixel color Arry
PublicFunction CreateRasterBlock(ByVal hdc As Long, ByVal BiW As Long, ByVal BiH As Long) As Boolean
ReDimTo 3, 1 To BiW, 1 To BiH) 'vb 定义数据A(2,3) 表示三行四列矩阵
ReDimTo BiW, 1 To
InitializeRasterValue(BiW, BiH)
'给位图点阵指定颜色
Dim j As Long, k As Long
For j = 1 To
For k = 1 To
PiArry(j, k) = RGB(RaArry(1, j, k), RaArry(2, j, k), RaArry(3, j, k))
'SetPixel hDCMem, j, k, PiArry(j, k)
SetPixel(hdc, j - 1, k - 1, PiArry(j, k))
Next
FoMain.pg.Value = j * 100 / BiW
Next
FoMain.pg.Value = 0
CreateRasterBlock = True
EndFunction
PublicSub InitializeRasterValue(ByVal Col As Long, ByVal Row As Long)
Dim r As Integer, g As Integer, b As Integer, j As Long, k As Long
For j = 1 To
For k = 1 To
RaArry(1, j, k) = 0 'GetR()
RaArry(2, j, k) = (2 * j + k) Mod 255 '(255 - (j + k) * (j - k) Mod 255) Mod 255 'GetG()
RaArry(3, j, k) = 0 'GetB()
Next
FoMain.pg.Value = j * 100 / Col
Next
FoMain.pg.Value = 0
EndSub
PublicFunction GetR() As Integer
Dim r As Integer
'r = Int(Rnd * 255)
r = 200
GetR = r
EndFunction
PublicFunction GetG() As Integer
Dim g As Integer
g = 10 'Int(Rnd * 255)
GetG = g
EndFunction
PublicFunction GetB() As Integer
Dim b As Integer
b = 0 'Int(Rnd * 255)
GetB = b
EndFunction
这里补充一点,mapX支持矢量图的显示,通过栅格格式句柄(Raster Format Handler)来自动地检查栅格的格式并且显示。Raste Format Handler以动态链接库的形式安装在mapX的安装目录里,当加载栅格图像时mapX通过检索动态链接库(.dll)来进行测试,一旦一个.dll可以读该文件,并且返回是(yes),那么mapX就可以确定用该dll来处理当前的栅格格式。格式句柄文件以“.RHx”做后缀,不同的栅格格式由第三个字符x来确定,可以是A-Z的任意字符。mapX检索栅格句柄时从A开始往后检索,并且通过检索建立优先级顺序,后续的加载都先用之前的可用句柄来测试可处理性。比如spot影像是一种原始数据,易于与其他格式混淆,因此要先检测是否是spot影像,其格式句柄的扩展名为“.RHD”。安装mapX时要安装相应的动态库和格式句柄。具体可查看mapX帮助文档中的“Installing RasterFormat Handlers”主题。