一般的切图都是基于GIS平台,这种方式编程简单,但效率不高。通过MITab在内存中切图,可极大的提高效率。实现切图的步骤:
1、空间对象的读取。
2、空间对象的分块。
3、空间对象在GDI中的映射。
4、空间对象在GDI中的绘制。
我们重温下使用MITab读取MapInfo的TAB文件代码:
'/************************************************************************/
'/* ReadFile */
'/************************************************************************/
Sub ReadFile(ByVal pszFilename As String)
Dim dataset As Long = mitab_c_open(pszFilename)
If (dataset = 0) Then
sTmp = Space$(255)
i1 = mitab_c_getlasterrormsg_vb(sTmp, 255)
MsgBox ("mitab_c_open: " & pszFilename & " failed." & vbCrLf & Left$(sTmp, i1))
Exit Sub
End If
feature_id As Long = mitab_c_next_feature_id(dataset, -1)
Do While feature_id <> -1
'/* -------------------------------------------------------------------- */
'/* Read next feature object */
'/* -------------------------------------------------------------------- */
feature = mitab_c_read_feature(dataset, feature_id)
If (feature = 0) Then
sTmp = Space$(255)
i1 = mitab_c_getlasterrormsg_vb(sTmp, 255)
MsgBox ("Failed to read feature " & Str$(feature_id) & vbCrLf & Left$(sTmp, i1))
Exit Sub
End If
feature_type = mitab_c_get_type(feature)
num_parts = mitab_c_get_parts(feature)
'/* -------------------------------------------------------------------- */
'/* ... and coordinates. */
'/* In real applications, we would probably want to handle each */
'/* object type differently but we won't do it here. */
'/* -------------------------------------------------------------------- */
For partno = 0 To num_parts - 1
num_points = mitab_c_get_vertex_count(feature, partno)
For pointno = 0 To num_points - 1
dX = mitab_c_get_vertex_x(feature, partno, pointno)
dY = mitab_c_get_vertex_y(feature, partno, pointno)
Next
Next
mitab_c_destroy_feature (feature)
feature_id = mitab_c_next_feature_id(dataset, feature_id)
Loop
mitab_c_close (dataset)
End Sub
地图的分块可以参考谷歌地图的金字塔模型的地图瓦片技术。
映射根据地图所在块的大小和图像尺寸进行换算,如:(X坐标 - 空间对象所在块左上角X坐标) / 块大小 * 图像大小, (空间对象所在块左上角Y坐标 - Y坐标) / 块大小 * 图像大小)。其中空间坐标系的Y坐标向上为正,而图像坐标系的Y坐标向下为正。
绘制代码:
'区域
Sub DrawPolygon(ByVal feature As Long, ByVal partno As Long, ByVal block As Rectangle, ByVal g As Graphics)
Dim num_points As Long = mitab_c_get_vertex_count(feature, partno)
Dim ps(0 To num_points - 1) As Drawing.PointF
For pointno As Long = 0 To num_points - 1
dX = mitab_c_get_vertex_x(feature, partno, pointno)
dY = mitab_c_get_vertex_y(feature, partno, pointno)
ps(i) = New PointF((dX - block.Left) / block.Width * 256, (block.Top - dY) / block.Height * 256)
Next
Dim fc As Color = Color.FromArgb(mitab_c_get_brush_fgcolor(feature))
fc = Color.FromArgb(fc.R, fc.G, fc.B)
Dim bc As Color = Color.FromArgb(mitab_c_get_brush_bgcolor(feature))
bc = Color.FromArgb(bc.R, bc.G, bc.B)
g.FillPolygon(New Drawing.SolidBrush(fc), ps)
Dim c As Color = Color.FromArgb(mitab_c_get_pen_color(feature))
c = Color.FromArgb(c.R, c.G, c.B)
g.DrawPolygon(New Drawing.Pen(c, mitab_c_get_pen_width(feature)), ps)
End Sub
'线
Sub DrawLine(ByVal feature As Long, ByVal partno As Long, ByVal block As Rectangle, ByVal g As Graphics)
Dim num_points As Long = mitab_c_get_vertex_count(feature, partno)
Dim ps(0 To num_points - 1) As Drawing.PointF
For pointno As Long = 0 To num_points - 1
dX = mitab_c_get_vertex_x(feature, partno, pointno)
dY = mitab_c_get_vertex_y(feature, partno, pointno)
ps(i) = New PointF((dX - block.Left) / block.Width * 256, (block.Top - dY) / block.Height * 256)
Next
Dim c As Color = Color.FromArgb(mitab_c_get_pen_color(feature))
c = Color.FromArgb(c.R, c.G, c.B)
g.DrawLines(New Drawing.Pen(c, mitab_c_get_pen_width(feature)), ps)
End Sub
浙公网安备 33010602011771号