使用 MapWinGIS 将 ESRI Shape 文件转换为 Google Earth KML






4.67/5 (3投票s)
一组简单的函数,用于将 Shape 文件多边形转换为 KML 多边形
引言
Google Earth 可能是目前可用的最佳 GIS 数据可视化工具。 唯一的问题是,您必须将 GIS 数据转换为 Google Earth 的 Keyhole Markup Language (KML),才能让 Google Earth 显示它。
ESRI Shape 文件通常用于表示 GIS 数据,并且有很多工具可用于可视化它们,其中最受欢迎的开源工具之一是 Mapwindow。 但是,Mapwindow 目前没有内置的 Google Earth Keyhole Markup Language (KML) 导出选项,尽管有付费插件可用。
幸运的是,Google 已经使创建 KML 变得非常简单,因此编写一组简单的函数(使用 MapWinGIS 类)将多边形 Shapefile 转换为 KML 相对容易。
为了说明在 MapWindow 和 Google Earth 中查看 Shapefile 数据之间的区别,请比较以下两个屏幕截图。 左侧显示在 MapWindow 中查看的 Shapefile,而右侧显示在 Google Earth 中叠加的相同数据。 在此示例中,数据显示了伦敦市中心的建筑物。
使用代码
ESRI 标准中有 13 种 Shape 类型(不包括 NullShape),但此示例中的代码仅处理多边形。 但是,由于这些是最常用的 Shape 类型,因此这并不是一个很大的限制。 可以通过在下面的 Case 语句中添加相关函数来轻松扩展代码,以支持其他 Shape 类型。 目前,任何非多边形 Shape 都会被干净地跳过,并且会在 Visual Studio 调试控制台中显示一条通知给用户。
'Loop through the shape file, shape by shape
Dim ShapeIndex As Integer, ConvertedShapeCount As Integer
For ShapeIndex = 0 To SF.NumShapes - 1
'Process each shape depending on ShapeType
Select Case SF.Shape(ShapeIndex).ShapeType
Case ShpfileType.SHP_POLYGON
Call AddPolygonKML(SF.Shape(ShapeIndex), KMLFile, CStr(ShapeIndex))
ConvertedShapeCount = ConvertedShapeCount + 1
Case Else
Debug.Print("Shape # " & ShapeIndex & " of type " & SF.Shape(ShapeIndex).ShapeType & " not supported yet.")
End Select
Next ShapeIndex
在 KML 中创建多边形
KML 具有 Polygon 函数,因此要将 Shape 转换为 KML,您只需要从 Shape 中读取点,并应用适当的 KML 语法即可。
在 KML 中定义的 Polygon 如下所示:
<Polygon>
<extrude>1</extrude>
<altitudeMode>relativeToGround</altitudeMode>
<outerBoundaryIs>
<LinearRing>
<coordinates>
-0.10615258,51.51241061,26.0
-0.10617222,51.51241083,26.0
-0.10617112,51.51248367,26.0
-0.10599687,51.51248266,26.0
-0.10599709,51.51247534,26.0
-0.10599741,51.51246417,26.0
-0.10606998,51.51246500,26.0
-0.10615098,51.51246545,26.0
-0.10615258,51.51241061,26.0
</coordinates>
</LinearRing>
</outerBoundaryIs>
</Polygon>
坐标定义为包含经度(度)、纬度(度)和高度(米)的元组。 高度可以相对于地面、海洋、海底等。 这由高度模式定义,因此请确保为您的高度数据使用适当的高度模式!
<altitudeMode>relativeToGround</altitudeMode>
将所有这些放在一起,下面显示了一个将 Shape 多边形转换为 KML 多边形的简单函数。 此函数忽略了多边形可能具有多个部分的事实,因此多部分多边形可能无法正确显示。 注意:我可能会在以后添加此功能。
Private Sub AddPolygonKML(ByRef Shape As MapWinGIS.Shape, _
ByRef oWrite As System.IO.StreamWriter, _
ByVal ShapeID As String)
'The key parameters for defining the KML Polygon's points are:
Dim LatDeg As Double
Dim LonDeg As Double
Dim Height As Double 'Note: depending on whether this is AGL or ASL, change the KML setting below accordingly
'Create a Placemark with no label to wrap the Polygon in
oWrite.WriteLine(" <Placemark>")
'Use the Shapes ID as a Name (optional)
oWrite.WriteLine(" <name>Shape " & ShapeID & "</name>")
'Pick up the Style we wish to use (otional, but allows for nice colours etc)
oWrite.WriteLine(" <styleUrl>Shape Style</styleUrl>")
'Start the Polygon KML object
oWrite.WriteLine(" <Polygon>")
'The <extrude> tag extends the line down to the ground
oWrite.WriteLine(" <extrude>1</extrude>")
'Note there are two common options for Altitude:
' "relativeToGround" for Above Ground Level
' "absolute" for Above Sea Level
' See https://developers.google.com/kml/documentation/altitudemode
oWrite.WriteLine(" <altitudeMode>relativeToGround</altitudeMode>")
'A Polygon is defined by a ring of coordinates
oWrite.WriteLine(" <outerBoundaryIs>")
oWrite.WriteLine(" <LinearRing>")
oWrite.WriteLine(" <coordinates>")
'Loop through the points one by one
Dim PointIndex As Integer
For PointIndex = 0 To Shape.numPoints - 1
'Extract the 3D coordinates for the Point
LonDeg = Shape.Point(PointIndex).x
LatDeg = Shape.Point(PointIndex).y
Height = Shape.Point(PointIndex).Z
'create KML coordinate string is <lon,lat,height> {space} <lon,lat,height>
'Note: Any space next to a ',' will create a new coordinate!
oWrite.Write(" ")
oWrite.Write(FormatNumber(LonDeg, 8) & ",")
oWrite.Write(FormatNumber(LatDeg, 8) & ",")
oWrite.Write(FormatNumber(Height, 1) & " ")
oWrite.WriteLine()
Next PointIndex
'Close the relevant folders in reverse order
oWrite.WriteLine(" </coordinates>")
oWrite.WriteLine(" </LinearRing>")
oWrite.WriteLine(" </outerBoundaryIs>")
oWrite.WriteLine(" </Polygon>")
oWrite.WriteLine(" </Placemark>")
End Sub
使用源代码
源代码包含一组独立的函数,它将接受 Shapefile 并将其转换为 KML 文件。 主函数头如下所示
Public Sub ConvertShapeFileToKML(ByVal ShapeFileName As String, _
ByVal KMLFileName As String)
关注点
编写 KML 的最佳技巧是记住,在列出坐标时,不要在经度、纬度和高度之间的逗号周围留有任何空格,否则 GE 会假定它们是单独的坐标,您将花费大量时间弄清楚为什么 KML 不起作用<coordinates>-1.1,-2.2,100</coordinates> 'works fine
<coordinates>-1.1, -2.2, 100</coordinates> 'will not work as expected!
历史
版本 1.0,2012 年 9 月 4 日