1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > proj4经纬度bl转换xy_在Web客户端中基于Proj4实现坐标转换

proj4经纬度bl转换xy_在Web客户端中基于Proj4实现坐标转换

时间:2024-06-06 12:48:00

相关推荐

proj4经纬度bl转换xy_在Web客户端中基于Proj4实现坐标转换

当鼠标滑过地图,我们会扫一眼鼠标的地理位置,至少要能看到经纬度,好确认当前的范围和地物是否处在正常的位置。这对于C/S应用来说,是最为常见的辅助功能,即使是在B/S中,这似乎也不是难事,比如谷歌地图等都能提供这个功能,但是我们也知道,这些地图数据是固定投影的,获取经纬度坐标的途径是单一的,而这也不是本文要考虑的内容。

在系统应用中,B/S结构的GIS系统会发布具有不同投影类型的地图数据,而在客户端系统中为了显示鼠标的当前地理位置信息,通常我们会有三种解决办法:第一种,直接将鼠标的屏幕坐标转换为经纬度坐标并显示——仅限于发布的地图采用了经纬度坐标系;第二种,鼠标MouseMove过程中与服务器进行实时通信,将鼠标坐标转换为经纬度后返回给客户端显示——这要取决于网络是否稳定;第三种,则是在客户端进行坐标投影转换,相对来说,前两种解决办法都有一定的限制,而第三种解决办法则相对通用,也就是本文所讨论的话题。

当然,在开始讨论前,先明确一下有关的背景知识。坐标投影转换的资料,参考LionGG的文章/liongg/blog/item/81d7b48f8bdfb0ebf01f36fd.html,内容很详尽。有关Proj4/proj/,是著名的开源C语言投影库,现在也包括了Javascript版(proj4js),ActionScript版(proj4as)等语言的实现。有关各种投影的参数定义,可参考,如果已经有定义,例如EPSG:2334:Xian 1980,可以搜索并查看其定义,我们能看到投影信息的多种表述,如proj4类型的表述为/ref/epsg/2334/proj4/)。

本文主要针对客户端坐标投影转换的实现,通过实践SuperMap iClient for Flex与Openscales-proj4as,整理该流程如下:

1、获取openscales-proj4as-1.2.1.swc,当然现在以后会有更新版本,或者直接获取openscales的整个库——有API文档和源码,本文中直接使用源代码进行调试;

2、获取SuperMap iClient for Flex,当然也要有配套的SuperMap iServer,为了配合本次实践,这里发布了一个China400的地图,采用了Lambert Conformal Conic投影,中央经线104°,第一标准纬线24°,第二标准纬线40°,单位米;

1

234

效果如下图

3、现在利用Label显示鼠标的坐标位置看看效果。

1privatefunctioninit():void

2{3this.myMap.addEventListener(MouseEvent.MOUSE_MOVE,mouseMoveHandler);4}5privatefunctionmouseMoveHandler(event:MouseEvent):void6{7varpoint:Point=newPoint(event.stageX,event.stageY);8varpoint2D:Point2D=this.myMap.screenToMap(point);9this.coordInfo.text=point2D.x+""+point2D.y;10}

效果如图

这个坐标的单位是米,对于我们来说这个坐标没能带来实际意义,我们还是要靠经纬度坐标来判断地理位置的。

4、现在我们使用openscales-proj4as来实现坐标转换的工作。想要熟悉openscales-proj4as的接口不是那么容易,API接口文档轻描淡写,如果不是GIS或测绘专业的人,是较难理解其含义的。现有的两个Package中,org.openscales.proj4as是主要的投影基础类定义,而org.openscales.proj4as.proj则是一些预定义的投影,见下表:

Package

Class

Description

org.openscales.proj4as

Datum

大地基准面,例如北京54

Proj4as

主类,提供静态方法做投影转换,transform方法是将一种投影类型的坐标转换为另一种投影类型的坐标值

ProjConstants

常量,其中有一些很实用

ProjPoint

坐标点

ProjProjection

投影类,任何投影的定义都可以继承该类,defs静态常量可以通过键值定义投影类型,forward方法是将经纬度坐标转换为投影坐标,inverse方法是将投影坐标转换为经纬度坐标

org.openscales.proj4as.proj

ProjParams

投影参数类,用于初始化各种预定义的投影

ProjLcc

预定义的兰伯特投影类

其他投影类

基于上表的描述就可以定义投影了,这里定义兰伯特投影的方式有两种,如下

1privatestaticvarprojLcc:Object;

1/**

2*通过投影参数定义北京54兰伯特投影3**/4privatefunctiondefsProjLcc1():void5{6if(!projLcc)7{8//使用系统常量的定义Datum(大地基准面),Krassovsky19429varkrass:Object=ProjConstants.Ellipsoid["krass"];10varprojLccData:ProjParams=newProjParams();11//椭球长半轴12projLccData.a=krass.a;13//扁率14projLccData.rf=krass.rf;15//椭球长半轴,这里必须设置b,究其原因是功能接口没有利用a、b、rf关系做相互计算16projLccData.b=projLccData.a*(1-1/projLccData.rf);17//投影坐标系单位18projLccData.units="m";19//投影原点纬线20projLccData.lat0=0.00000000;21//投影中央经线22projLccData.long0=104*Math.PI/180;23//第一标准纬线24projLccData.lat1=24*Math.PI/180;25//第二标准纬线26projLccData.lat2=40*Math.PI/180;27//水平偏移量28projLccData.x0=0.000;29//垂直偏移量30projLccData.y0=0.000;31//使用投影参数实例化投影对象32projLcc=newProjLcc(projLccData);33//初始化投影参数,必须执行该接口34projLcc.init();35}36}

1/**

2*定义北京54兰伯特投影,3*ProjProjection.defs[]静态常量定义键值对,4*10010为自定义的EPSG值5*键值内容参考投影参数6**/7privatefunctiondefsProjLcc2():void8{9if(!projLcc)10{11if(!ProjProjection.getProjProjection("10010"))12{13ProjProjection.defs["10010"]="+title=Beijing1954+proj=lcc+towgs84=0.0000,0.0000,0.0000+a=6378245.0000+rf=298.3+lat_0=0.00000000+lon_0=104.000000000+lat_1=24.000000000+lat_2=40.000000000+x_0=0.000+y_0=0.000+units=m+no_defs";14}15projLcc=ProjProjection.getProjProjection("10010");16}17}

接着获取鼠标的当前坐标信息,并转换为地理坐标,并采用投影转换的方法进行坐标转换,如下

privatefunctionmouseMoveHandler(event:MouseEvent):void

{

varpoint:Point=newPoint(event.stageX,event.stageY);

varpoint2D:Point2D=this.myMap.screenToMap(point);

varsourceP:GeoPoint=newGeoPoint(point2D.x,point2D.y);

vardestP:GeoPoint=coordTransform(sourceP);this.coordInfo.text=destP.x.toPrecision(8)+""+destP.y.toPrecision(8);

}

1privatefunctioncoordTransform(sourceP:GeoPoint):GeoPoint2{3if(sourceP&&projLcc)4{5varsourceP2:ProjPoint=newProjPoint(sourceP.x,sourceP.y);6vardestP:ProjPoint=projLcc.inverse(sourceP2);7varrp:GeoPoint=newGeoPoint(destP.x*180/Math.PI,destP.y*180/Math.PI);8returnrp;9}1011returnnull;

12}

转换后的效果如下图

5、至此,本文就完成了基本的坐标转换,同时经过简单的测试,发现连续转换10000000对坐标点(兰伯托投影)共耗时17.689s,1000对则耗时2ms,性能适中,可以考虑做客户端地图动态投影。

结束之前,插上一句,不论是投影之间的坐标转换实现动态投影,还是投影的经纬度转换,都有应用价值,也希望各种客户端应用系统都能结合Proj4实现坐标转换。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。