MapObject学习笔记-第六讲 MO中的坐标和坐标系

第六讲 MO中的坐标和坐标系

一、坐标系对象

1、坐标对象概述

MO中提供了一系列坐标系对象(也称为投影对象)来控制和操作地图的坐标系统,如projcoordsys(投影坐标系统)、Geocoordsys(地理坐标系统)、Datum(基准面)、PrimeMeridian(本初子午线)、Projection(投影)、Spheroid(地球椭圆体)、Unit(单位)、Geotransformton(地理坐标转换)等。

这些对象都可以在程序中定义,例如:Dim thePrime As New MapObjects2.PrimeMeridian


投影对象之间的部分关系如图所示。一个Datum对象有Spheroid属性,Geocoordsys对象包括有DatumPrimeMeridian属性。




MO中,坐标系的产生和转换是用POSCPetrochemical open software consortium)模型来管理的,这个模型定义了不同的测量和绘图坐标系与他们之间的关系。在POSC模型下的每个对象都有一个唯一的坐标系编码(利用Type属性操作),它定义了该对象在POSC模型下的坐标系属性(CoordinateSystem)。

设置和改变对象的CoordinateSystem属性,会改变图形的外观。Geotransformton对象可以转换MapLayer的投影方式,也可以转换单个图形对象。

2、地理坐标系和投影坐标系

MO中,每个MAPMapLayer对象都和一个坐标系对象发生联系,这个坐标系对象是地理坐标系对象(Geocoordsys),也可以是投影坐标系(projcoordsys)对象。

地理坐标系(Geocoordsys)是MO中最常用的坐标系对象,它用经纬度描述地面上的位置。描述位置时,Datum属性来设置基准面,用PrimeMeridian属性来设置其本初子午线,用Unit属性设置其坐标系单位

标准的地理坐标系的改变可以通过用Type属性来设置GeographicCoordSys常数完成,通过设置其GeocoordsysPrimeMeridianUnit属性,也可以设置自定义的投影坐标系。

投影坐标系(projcoordsys)用XY坐标来描述地面上的位置,它用地球椭圆体Spheroid模拟地球,用Projctedcoordsys属性表示投影坐标系的来源,用Projection属性表示投影的计算方法,用Unit属性设置其坐标系单位。

标准的投影坐标系的改变可以通过用Type属性来设置ProjectedCoordSys常数来完成,通过设置其ProjctedcoordsysProjectionUnit属性,也可以设置自定义的投影坐标系。

地理坐标系和投影坐标系可以用在MapLayer图层和MAP上,通过使用Transform方法,还可以改变单个图形对象的坐标系。下面的示例程序来判断图层所采用的坐标系,利用到了IsProjected属性:

Option Explicit

Dim dc As New DataConnection

Dim layer As MapObjects2.MapLayer

Private Sub layset()

dc.Database = App.Path + "\..\" + "world"

Set layer = New MapLayer

Set layer.GeoDataset = dc.FindGeoDataset("country")

layer.Symbol.Color = moOrange

Map1.Layers.Add layer

Map1.Refresh

End Sub

 

Private Sub Command1_Click()

Dim coordsys As Object

Dim a As String

Set layer = Map1.Layers(0)

Set coordsys = layer.CoordinateSystem

If coordsys.IsProjected Then

a = MsgBox("图层为投影坐标系", , "坐标信息显示框")

ElseIf Not coordsys.IsProjected Then

a = MsgBox("图层为地理坐标系", , "坐标信息显示框")

End If

End Sub

 

Private Sub Form_Load()

Command1.Caption = "显示坐标信息"

layset

End Sub

3、坐标系的读取和设置

反映其坐标类型的CoordinateSystem属性可以用以下方法来读取:

layer.CoordinateSystem.Name’坐标系名称

layer.CoordinateSystem.Type’坐标系代码

设置MapLayerMapCoordinateSystem时,要先定义一个坐标对象,再设置它的Type属性,最后才可以设置CoordinateSystem。如:

Dim mapGCS As New MapObjects2.GeoCoordSys

mapGCS.Type = moGeoCS_Adindan

Map1.CoordinateSystem = mapGCS

图层文件在制作时带有一个坐标系的信息文件,即.prj文件。下面这个例子是显示一个带有坐标系文件的图层,再设置一个不带有坐标系文件的图层的坐标系信息。示例代码:

Option Explicit

Dim dc As New DataConnection

Dim layer As MapObjects2.MapLayer

Dim mapPCS  As MapObjects2.ProjCoordSys

Dim mapgCS As New MapObjects2.GeoCoordSys

Private Sub layset()

dc.Database = App.Path + "\..\" + "world"

Set layer = New MapLayer

Set layer.GeoDataset = dc.FindGeoDataset("country")

layer.Symbol.Color = moOrange

Map1.Layers.Add layer

Set layer = New MapLayer

Set layer.GeoDataset = dc.FindGeoDataset("cities")

layer.Symbol.Color = moGreen

layer.Symbol.Size = 3

Map1.Layers.Add layer

Map1.Refresh

 

 

End Sub

 

Private Sub Command1_Click()

Set layer = Map1.Layers(0)

If Map1.Layers(1).CoordinateSystem.IsProjected Then

mapPCS.Type = Map1.Layers(1).CoordinateSystem.Type

layer.CoordinateSystem = mapPCS

ElseIf Not Map1.Layers(1).CoordinateSystem.IsProjected Then

mapgCS.Type = Map1.Layers(1).CoordinateSystem.Type

layer.CoordinateSystem = mapgCS

End If

List1.Clear

addlist

layset

 

 

End Sub

 

Private Sub addlist()

Dim curlayer As MapObjects2.MapLayer

For Each curlayer In Map1.Layers

If Not curlayer.CoordinateSystem Is Nothing Then

List1.AddItem curlayer.Name & ":" & curlayer.CoordinateSystem.Name

Map1.Layers(curlayer.Name).Visible = True

Else

List1.AddItem curlayer.Name & ":坐标系没有设置!"

Map1.Layers(curlayer.Name).Visible = False

End If

Next curlayer

List1.AddItem "Map控件:" & Map1.CoordinateSystem.Name

End Sub

 

Private Sub Form_Load()

layset

Command1.Caption = "改变"

If Map1.CoordinateSystem Is Nothing Then

If Map1.Layers(1).CoordinateSystem.IsProjected Then

Dim mapPCS As New MapObjects2.ProjCoordSys

mapPCS.Type = Map1.Layers(1).CoordinateSystem.Type

Map1.CoordinateSystem = mapPCS

ElseIf Not Map1.Layers(1).CoordinateSystem.IsProjected Then

Dim mapgCS As New MapObjects2.GeoCoordSys

mapgCS.Type = "4326"

Map1.CoordinateSystem = mapgCS

End If

End If

addlist

End Sub

4、坐标系的改变

当改变坐标系时,地图的形状也会发生改变,下面是一个世界地图转换的例子:

Dim dc As New DataConnection

Dim layer As MapObjects2.MapLayer

 

Private Sub Command1_Click()

Dim csmap As New MapObjects2.ProjCoordSys

 

'Map1.Layers(0).CoordinateSystem = Map1.Layers(1).CoordinateSystem

csmap.Type = moProjCS_World_WinkelI

Map1.CoordinateSystem = csmap

End Sub

 

Private Sub Command2_Click()

Map1.CoordinateSystem = Map1.Layers(1).CoordinateSystem.Type

End Sub

 

Private Sub Form_Load()

Command1.Caption = "投影坐标系"

Command2.Caption = "地理坐标系"

layset

End Sub

Private Sub layset()

dc.Database = App.Path + "\..\" + "world"

Set layer = New MapLayer

Set layer.GeoDataset = dc.FindGeoDataset("country")

layer.Symbol.Color = moBlue

Map1.Layers.Add layer

Set layer = New MapLayer

Set layer.GeoDataset = dc.FindGeoDataset("latlong")

layer.Symbol.Color = moBlack

layer.Symbol.Size = 1

Map1.Layers.Add layer

Map1.Refresh

End Sub

二、地图上坐标单位及其转换

1、在地图上显示经纬度

点击地图查看坐标时,如果不作任何的坐标转换,在Map1_MouseDown过程中XY的显示坐标为控件的原始坐标(twips)。用ToMapDsitanceToMapPoint方法,可以把点击坐标转换成地图坐标。

ToMapDsitance是地图控件的成员函数之一,其功能是将屏幕坐标的距离值转换为地图坐标系的距离值,语法为object.ToMapDistance distance,返回值是地图坐标系的距离值,distance为屏幕坐标的距离值。

下面程序是将世界地图进行图上坐标向经纬度转换的示例,用ToMapDsitance方法时,地图从左到右为0360度,从上到下为0180度。用ToMapPoint方法时,考虑了DatumPrimeMeridian属性,从伦敦开始向右为正(0180),向左为负(-1800),从赤道向上为090,向下为-900。代码如下:

Dim dc As New DataConnection

Dim layer As MapObjects2.MapLayer

 

Private Sub Command1_Click()

Dim mapGCS As New MapObjects2.GeoCoordSys

mapGCS.Type = Map1.Layers(1).CoordinateSystem.Type

MsgBox "datum = " & mapGCS.Datum.Name & " ,primemridian= " & mapGCS.PrimeMeridian.Name

 

End Sub

 

Private Sub Form_Load()

Label1.Caption = "点击地图显示经纬度"

layset

Command1.Caption = "显示坐标信息"

Option1.Caption = "ToMapDsitance"

Option2.Caption = "ToMapPoint"

End Sub

Private Sub layset()

dc.Database = App.Path + "\..\" + "world"

Set layer = New MapLayer

Set layer.GeoDataset = dc.FindGeoDataset("country")

layer.Symbol.Color = moBlue

Map1.Layers.Add layer

Set layer = New MapLayer

Set layer.GeoDataset = dc.FindGeoDataset("latlong")

layer.Symbol.Color = moBlack

layer.Symbol.Size = 1

Map1.Layers.Add layer

Map1.Refresh

End Sub

 

Private Sub Map1_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)

Dim str1 As String

Dim p1 As MapObjects2.Point

If Not Option1 Then

Set p1 = Map1.ToMapPoint(X, Y)

str1 = "x=" & Format(p1.X, "0.000") & ",y=" & Format(p1.Y, "0.000")

Else

str1 = "x=" & Format(Map1.ToMapDistance(X), "0.000") & ",y=" & Format(Map1.ToMapDistance(Y), "0.000")

End If

Label1.Caption = str1

Dim rec As MapObjects2.Rectangle

If Button = 1 Then

Set Map1.Extent = Map1.TrackRectangle

Else

Map1.Pan

Map1.Refresh

End If

End Sub

2、在地图上显示公里

地球的赤道直径为40075.7km,因此可以近视用Dx=40075.7/360表示度数向公里的转换系数。示例代码如下:

Dim dx As Single

Dim dc As New DataConnection

Dim layer As MapObjects2.MapLayer

 

Private Sub Form_Load()

dx = 40075.7 / 360

Label1.Caption = "点击地图显示公里"

layset

 

End Sub

Private Sub layset()

dc.Database = App.Path + "\..\" + "world"

Set layer = New MapLayer

Set layer.GeoDataset = dc.FindGeoDataset("country")

layer.Symbol.Color = moBlue

Map1.Layers.Add layer

Set layer = New MapLayer

Set layer.GeoDataset = dc.FindGeoDataset("latlong")

layer.Symbol.Color = moBlack

layer.Symbol.Size = 1

Map1.Layers.Add layer

Map1.Refresh

End Sub

 

Private Sub Map1_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)

Dim str1 As String

str1 = "x=" & Format(Map1.ToMapDistance(X) * dx, "0.000") & ",y=" & Format(Map1.ToMapDistance(Y) * dx, "0.000")

Label1.Caption = str1

End Sub

posted on 2007-05-22 16:49  GIS云中飞鹏  阅读(3973)  评论(4编辑  收藏  举报

导航