我有 C# 应用程序,它使用 GMap.NET 来呈现世界地图和我的其他数据。我有要渲染的 Graphics 对象。我还需要在我的地图上将 ESRI 形状文件显示为半透明形状。我该如何渲染它?可用的库看起来就像它们会吸引到自己的 Windows 控件中。另外,当我能够渲染它时,如何准确同步地图和形状坐标?
感谢:D。
GMap.Net 不支持直接读取 ESRI 形状文件,但您可以使用像MapTools这样的第 3 方库,它是 (ShapeLib) 库的 .Net 包装器。
您必须首先使用 (MapTools) 库读取形状文件,并为每个几何图形(点、线、多边形)循环,然后使用Proj4Net库转换几何投影,并将每个几何图形添加到 GMapControl 上的适当叠加层。
您可以从此链接下载 (MapTools) 的最新版本
这是一个读取填充了路线的形状文件的示例函数,它将返回 GMapRoutes 列表,然后您必须在地图上绘制它们。
Public Function ReadRoutesFromShapefile(ByVal filename As String) As List(Of GMapRoute)
Dim basePath As String = Path.GetDirectoryName(filename) & AscW(Path.DirectorySeparatorChar) & Path.GetFileNameWithoutExtension(filename)
If Not File.Exists(basePath & ".prj") Then
Throw New Exception("Could not find the projection file!")
End If
'Get info from WKT-File:
Dim wkt As String = File.ReadAllText(basePath & ".prj")
Dim gcs As ICoordinateSystem = TryCast(CoordinateSystemWktReader.Parse(wkt), ICoordinateSystem)
Dim doTransformation = Not gcs.AuthorityCode = 4326
Dim wgs84 As GeographicCoordinateSystem = GeographicCoordinateSystem.WGS84
Dim ctfac As New CoordinateTransformationFactory()
Dim trans As ICoordinateTransformation = ctfac.CreateFromCoordinateSystems(gcs, wgs84)
'Open shape-file
Dim shapeFile As IntPtr = ShapeLib.SHPOpen(basePath, "rb")
Dim numOfRecords As Integer = 0
'Check type and get number of entries
Dim shapeType As ShapeLib.ShapeType = 0
ShapeLib.SHPGetInfo(shapeFile, numOfRecords, shapeType, Nothing, Nothing)
If Not shapeType.Equals(ShapeLib.ShapeType.PolyLine) Then
Throw New Exception("The shape type is not polyline but " & shapeType)
End If
Dim lstRoutes As New List(Of GMapRoute)(numOfRecords)
'Get info from shapefile and save data:
For i As Integer = 0 To numOfRecords - 1
'Add all GPS-Points:
'Get pointer to object
Dim ptrPolyline As IntPtr = ShapeLib.SHPReadObject(shapeFile, i)
'Create actual object:
Dim polyline As New ShapeLib.SHPObject()
Marshal.PtrToStructure(ptrPolyline, polyline)
If polyline.nParts = 1 Then
'Get number of points and arrays of X and Y values:
Dim numPoints As Integer = polyline.nVertices
Dim lstpoints As New List(Of PointLatLng)(numPoints)
Dim xCoord(numPoints - 1) As Double
Dim yCoord(numPoints - 1) As Double
'Fill the arrays:
Marshal.Copy(polyline.padfX, xCoord, 0, numPoints)
Marshal.Copy(polyline.padfY, yCoord, 0, numPoints)
'Add all Points
For j As Integer = 0 To numPoints - 1
Dim latitude As Double = 0.0R
Dim longitude As Double = 0.0R
If doTransformation Then
'Convert from original coordinate system to wgs84
Dim fromPoint() As Double = {xCoord(j), yCoord(j)}
Dim toPoint() As Double = trans.MathTransform.Transform(fromPoint)
'Get point from polyline
longitude = toPoint(0)
latitude = toPoint(1)
Else
longitude = xCoord(j)
latitude = yCoord(j)
End If
lstpoints.Add(New PointLatLng(latitude, longitude))
Next j
lstRoutes.Add(New GMapRoute(lstpoints, "Route" & (i + 1).ToString()))
End If
polyline = Nothing
ShapeLib.SHPDestroyObject(ptrPolyline)
Next i
ShapeLib.SHPClose(shapeFile)
Return lstRoutes
End Function