天地图不久前在gis界炒得热闹,某些专业人士分析并证明了,其web端很大一部分内容即使用的Openlayers,但将OpenLayers Javascript文件中所有OpenLayers的字眼抠去,换成自己的名称,楼主对此不作评价。我就花了一点时间来看了一看Openlayers,试验并测试了一种简单的地图发布办法,可以简单的将web目录下的瓦片发布为webgis地图。与各位分享,欢迎拍砖。
一、展示案例:http://www.daogle.com/map/index.html(使用的稻歌软件工作室网站空间)
二、实现原理:用脚本语言(asp.net、php或jsp)代替GIS数据服务器的WMS接口,来反馈给web客户端地图瓦片。
三、案例解释:
1、目标:我有从google map上下载的瓦片,希望在普通网站上发布成webgis,也没有自己的gis数据服务器,所以瓦片文件只能以文件方式存在web目录下。
2、技术手段:OpenLayers开源库、php。
3、解决方法:用php脚本解析WMS请求字串,反回文件目录下的瓦片即可。
4、OpenLayers Web客户端说明:
WMS无非就是通过http请求参数来获取瓦片,因此将常规的WMS请求改为对php页面的请求即可实现对本地图片的访问, 例如原来的WMS层代码这样写
layer = new OpenLayers.Layer.WMS( "OpenLayers WMS","http://vmap0.tiles.osgeo.org/wms/vmap0", {layers: 'basic'} );
现在将请求地址变更为php文件地址
layer = new OpenLayers.Layer.WMS( "卫星本地","picwms.php", {layers: 's'} );
picwms.php文件用来解析OpenLayers通过wms接口发送的http请求串,返回对应编号的瓦片即可。
例如一个瓦片的WMS请求串为
http://www.daogle.com/map/picwms.php?LAYERS=s&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&STYLES=&EXCEPTIONS=application%2Fvnd.ogc.se_inimage&FORMAT=image%2Fjpeg&SRS=EPSG%3A4326&BBOX=90,90,180,180&WIDTH=256&HEIGHT=256
经过picwms.php通过对其url参数的解析后,反馈对应的瓦片如下:
http://www.daogle.com/map/data/s/2/s_2_3_1.jpg
5、php脚本说明:
picwms.php的代码则非常明确和简单,通过解析url参数中的经纬度,地图类型等,反馈对应的瓦片文件地址即可,具体内容在此不再详叙。
后来不少朋友问我这个解析的代码,我将此代码帖在这里,图源是我用的“稻歌Google Map截获器”工具截取的。
6、坐标与投影的说明:
Openlayers默认的坐标系为经纬网,所以大部分采用Openlayers的webgis都采用的是地理经纬网坐标地图切的瓦片,天地图也是如此,这么做的好处是可以在客户端直接算出地图上任意一点的经纬度坐标,但是其形变太大,尤其是角度变形失真严重,所以天地图相比Google Map,尤其是在显示街道地图时失真有些严重,街道方向不准,而Google Map所采用的EPSG:3785投影(或称EPSG:900913)则没有角度变形。
在我的地图案例中,则鼠标显示的是Google Map投影坐标系下的坐标,当然这个是采用变通的办法实现的。Google Map的地图范围是一个正方形,而OpenLayers经纬网默认的地图范围是一个x:y为2:1的矩形,因此为了显示Google Map瓦片,我先将OpenLayers的地图范围改为:
map.maxExtent = new OpenLayers.Bounds(-180, -90, 180, 270);
这样就刚好是一个正方形了,同时,其瓦片数目、显示级别也与Google Map对应了起来。然后picwms.php解析wms请求时,通过经纬度范围算出瓦片编号,再映射瓦片文件命名,然后返回图片即可。
另外,实时显示地图上鼠标的坐标也是一个映射关系:
//获取Map上鼠标位置的经纬度(非真实坐标)//转换成Google投影坐标,单位为m
var lonlat = map.getLonLatFromViewPortPx(e.xy);
var x0 = lonlat.lon;//经度
var y0 = lonlat.lat;//纬度
//从范围-180, -90, 180, 270转换到Google投影坐标系 //Google投影上边界20037508.343 m //x坐标,单位m var x1 = 20037508.343 * 2 * ( x0 + 180 ) / 360 - 20037508.343; //y坐标,单位m var y1 = 20037508.343 * 2 * ( y0 + 90 ) / 360 - 20037508.343; //地图像素分辨率,单位m/像素 var pixelResolution = 156543.033929687/ Math.pow(2,map.getZoom());
四、总结:
(1)对于没有专有服务器,又想发布地图的盆友们来说,此种办法是比较方便的。但其性能上当然比不上采用专门gis数据服务器的办法,所以,只有玩一玩可以的。
(2)文章较为简单,也没有太多技术含量,只是一个简单实现的描述,欢迎盆友们拍砖。
本文引用地址:http://www.cnblogs.com/webgis8/archive/2010/11/24/1887168.html
giswei
www.daogle.com
稻歌软件工作室