Openlayers使用地图数据
[摘要]针对小型应用程序使用地图数据量小的问题,采用基础图层并对影像数据进行数字化。
[关键词] openlayers 地图数据瓦片数据
openlayers是由metacarta公司开发的,用于webgis客户端的javascript包。
它实现访问地理空间数据的方法都符合行业标准,比如opengis的wms和wfs规范, openlayers采用纯面向对象的javascript方式开发,同时借用了prototype框架和rico库的一些组件。
采用openlayers作为客户端不存在浏览器依赖性。
由于openlayers采用javascript语言实现,而应用于web浏览器中的dom(文档对象模型)由javascript实现,同时,web浏览器(比如ie,ff等)都支持dom。
openlayers apis采用动态类型脚本语言javascript编写,实现了类似与ajax功能的无刷新更新页面,能够带给用户丰富的桌面体验(它本身就有一个ajax类,用于实现ajax功能)。
目前,openlayers所能够支持的format有:xml、gml、geojson、georss、json、kml、wfs、wkt(well-known text)。
在openlayers.format名称空间下的各个类里,实现了具体读/写这些format的解析器。
openlayers所能够利用的地图数据资源,在这方面提供给拥护较多的选择,比如wms、wfs、googlemap、kamap、msvirtualearth、worldwind等。
也可以用简单的图片作为源。
在做gis项目时一个地图能使得应用程序变得更漂亮,对于一些小型的应用程序就不必
花大笔的钱去购买地图数据。
我们可以采用以下的方式来实现。
如果想从本地访问瓦片数据的话,首先需要解决的问题是从一些公共地图服务中获取瓦片数据。
在这里将使用工具
/?page_id=66下载地图的瓦片数据。
瓦片数据下载到本地之后,可以看到瓦片的数据命名
“m_14_13519_6253.png”,其中m后面的14代表的目前的缩放级别,“13519”代表的是瓦片数据的横坐标,“6253”代表的是瓦片数据的纵坐标。
对于google maps用的是墨卡托投影方式,将地图投影成了一个40075016.685578488?m的正方形坐标的形式,然后根据缩放级别将这个正方形分割成不不同粒度的小正方形,这种分割的形式采用的是四叉树索引的方式进行。
具体的分割如下图所示。
首先在level 0级别的时候,就是将这个正方形划分为一个256像素的图片,如果化成米的形式的话,就是40075016.685578488
的正方形,从这里可以计算出比例为:40075016.685578488/256 = 156543.033928041(米/像素)。
对于level 1级别时,然后再将这个正方形划分为一个4个256像素的正方形,此时计算出的比例为:40075016.685578488/512 = 78271.51696402(米/像素)。
对于openlayers来说,首先会向wms服务发送一个请求,这个请求会有一个bbox参数,参数的形式是这个box的左上角坐标和右下角坐标的值,对于后来服务来说,就是将这个box的图片发送到前台去显示。
对于要使用本地的瓦片数据,根据上面对于瓦片数
据的命名方式我们可以知道需要求三个参数:缩放级别 zoom、横坐标 x和纵坐标的值 y。
而对于请求来说,只有bbox的值,所以需要根据根据bbox的值来求出x,y和缩放级别的值zoom。
首先从前台来说,展现的总图片应该是一个360°×360°的正方形的图片,这是对于缩放级别为一级的来说的;对于一个bbox中的经纬度,可以计算出缩放级别:
java代码:
double mapunit = 360/(x1-x0);//156543.033929687
double z = math.log(mapunit)/math.log(2);
long zoom = math.round(z);
计算出缩放级别之后,然后根据公式x = ((20037508.343 * 2 * ( x0 + 180 ) / 360 ) / pixelresolution)/256可以计算出x的坐标,同理根据公式y = ((20037508.343 * 2 * ( y0 + 90 ) / 360 ) / pixelresolution)/256可以计算出y的坐标,根据计算结果,可以直接访问到这个缩放级别的的256×256的图片,然后用openlayer将图片展现到前天的界面中来。
关于javascript代码如下:
javascript code :
function init(){
map = new openlayers.map(“map”,{numzoomlevels :
5,minscale:216281.173********,restrictedextent: extent });
map.maxextent = new openlayers.bounds(-180, -90, 180, 270);
var ol_wms = new yer.wms(
“basic map”,
“test”,
{layers: “basic”,format:
“image/png”},{transitioneffect: resize’}
);
map.addlayers([ol_wms]);
selectcontrol = new
openlayers.control.selectfeature(layer);
map.addcontrol(selectcontrol);
selectcontrol.activate();
map.addcontrol(new yerswitcher()); map.zoomtomaxextent();
}
如上述代码所属,在前台添加一个wsm的图层,他会想后台发送一个请求,这个请求参数是一个bbox,然后根据请求过来的参数进行分析,计算出需要返回给前台的图片的名称。
上述过程能够完成一个地图底图的应用,如果需要将显示相关信息的话,可以将点信息存数到数据库中或者是文本文件中,然后在使用openlayer的vector图层添加上去。
var layer = new yer.vector(“pois”, { strategies: [new openlayers.strategy.bbox({resfactor: 1.1})],
protocol: new openlayers.protocol.http({
url:“textlayer”,
format: new openlayers.format.text()
})
});
如果是wgs1984的坐标体系的话,需要将坐标进行简单的转换,对于经度来说,和之前的一样,而对于纬度来说,首先换算成莫非托投影形式,然后将换成[-180,90,180,270]的坐标形式,转换算法如下:
x = math.log(math.tan((90 + latitude) * math.pi / 360)) / (math.pi / 180) * 20037508.343 / 180
x = x+ 20037508.343) * 360 / (20037508.343 * 2)– 90
最后这些都会添加到地图上,形式一个与业务相关的地图信息系统。
这样的实现方式可以满足一些只需要底图数据的系统。
参考文献:
[1]
/webgis8/archive/2010/11/24/1887168 .html.
[2]
/view/eb91573610661ed9ad51f3c5.html .
注:本文中所涉及到的图表、注解、公式等内容请以pdf格式阅读原文。