基于OpenLayers的四川境内电站WebGIS分布
3.2.1 制作电子地图
数据获取:
登陆国家基础地理信息网站(http://nfgis.nsdi.gov.cn/)通过提交基本信息后,下载全国河流数据,全国地级市数据,到网上求购下载全国电站数据。
数据处理制图:
将我们下载好的数据首先解压,利用MapInfo软件打开,在打开的图层上,通过选择工具选择出四川省的地图,然后重新打开一个New Mapper窗口,将我们选择的数据保存为MIF格式的数据,然后Tools工具里面的Universal Translator命令将MIF格式数据转化成shp格式的文件。
数据裁剪和合并并制图:
打开我们强大的ArcMap软件,打开我们刚刚下载好的全国河流数据,全国地级市数据,全国电站数据,还有刚刚制作成功的四川行政图面数据。选择我们的Data Management Tools工具集里面的Extraction类下的clip命令,我们右键单击选择批处理,我们可以执行对多幅图的一次性裁剪。根据弹出的参数设置页面,将我们待裁剪的数据加入到输入要素框,将四川省面数据作为裁剪标准,最后分别设置好输出文件路径和名称,最后执行操作。数几十秒后就完成了我们的数据裁剪工作。
裁剪完成后,我们需要将不同等级的河流合并为一个线文件,我们利用merge函数来实现,函数位置在ArcToolbox→Data Management Tools→ General→merge。到此为止我们的数据处理已基本完成了一大半了。此时得到的都是按图层来分的四川省行政图,四川省河流,四川省地级市,四川省水电站分布数据,都是shp格式。
将我们的制作好的数据用MapInfo打开进行一下效果预览,将四个图层同时打开到一个工工作空间,效果展示图如下:
3.2.2 配置地图服务器发布地图
安装JDK:
因为geoserver是基于java开发的,必须运行在在JRE的环境。所以要保证geoserver安装之前你的电脑已经安装了JDK比较高的版本,我选择的是1.6version版本的。安装JDK必须首先下载JDK(可以到Sun公司的官方主页下载,现在已经归属于Oracle了),下载完成后,进行安装并配置环境变量。设置环境变量时候,可用DOS窗口用set命令设置,也可以选择配置环境变量值。
JAVA_HOME C:\Program Files\Java\jdk1.6.0_07
CLASSPATH .%JAVA_HOME%lib
然后在path变量里再追加一条值:
path %JAVA_HOME%/bin; 这条路径指向geoserver运行所需要的class库文件。
然后在DOS环境中测试一下A安装是否成功,我们用javac 和java来测试,当没有错误提示并输出一连串的帮助信息时就证明我们的配置已经成功,而后就可以进行我们的geoserver的安装了。
安装geoserver:
到geoserver官方(http://geoserver.org/display/GEOS/Welcome) DownLoad页面下载一款比较新比较稳定的windows版本.我下载的是2.1.0版本的,下载完成后解压安装,我们选择默认的应用服务器jetty(类似于tomcat的内置的应用服务器),选择我们刚好安装好的JDK环境,我们可以选择设置8082端口(默认的8080已经被我的tomcat占用,这样设置可以避免端口冲突),一路next安装成功。
配置数据源发布地图:
1) 首先我们要Start GeoServer来启动我们的地图服务器;然后登录到服务器管理页面,localhost:8082/geoserver/web/或者(http://cesar:8082/geoserver/web/以计算机名字方式登录)。输入默认用户名admin,密码geoserver。
2) 在配置数据源之前我们需要将我们要进行发布shapefile格式的数据文件夹的地图数据拷贝到geoserver的数据目录文件夹下面的data文件夹下,作为一个子数据文件夹而存在。
3) 配置我们的数据源,根据项目规模的实际情况,我们并没有将shapefile文件导入数据库,而是直接选用配置ESRI shapefile格式的数据源,登陆界面后,我们首先我们选择新建一个工作空间,命名为cesar,然后配置数据源,Store——>add new Store,立刻会弹出到一个新的界面,我们选择 Vector Data Store目录下的Shapefile.根据提示为我们的数据源命名一个有意义的名字,保存,然调转到另一个页面。
4) 发布我们配置好的数据。点击Publish,进入到发布数据设置页面。进入这个页面最重要的设置就是对投影的设置了,在Declared SRS选框中输入【EPSG:4326】,表示的意思就是声明的空间参考系统为EPSG代号为4326的也就是对应我们平时所熟悉的WGS84地理参考系统。接下来的Bounding Boxes就是设置绑定的范围,由于我们已经设置好了空间参考系统,第一个Native Bounding Box,我们直接点解Compute from data,第二个Lat/Lon Bounding Box,我们照样点解Compute from native bounds。这样我们就准确的得到了绑定图幅的坐标范围了,表示的是这个电子地图四个方向的范围了。接着点击保存命令。在publishing页面,我们选择样式为polygon.然后再save.
5) 以同样的方式,将其他三个shapefile数据源加入到cesar工作空间。我们可以通过图层预览得到刚刚成功发布的数据,我们可以看看刚发布的数据。
依次是面数据四川省和线数据四川境内河流:
点数据地级市和点数据电站:
以上我们就已经完成了geoserver中地图的发布,下一步我们要做的就是进行WEBGIS前台页面的开发了。
3.2.3 WebGIS前端展示页面的开发
要进行WebGIS客户端的开发,我们需要首先拥有OpenLayers这个javascipt库才行,我们首先得到OpenLayer的官方网站下载这个框架,参考里面的API文档。同时我们还要下载Apache http server用来作为Web服务器。
下载安装配置apache http server:
登陆网站http://httpd.apache.org/; 下载一款最新的比较稳定的windows版本,然后安装,在安装过程中需要输入我的网站服务器地址www.cesar.com,由于我们的这个项目还没计划挂到公网上去,只是用于测试项目,所以只需要一个匿名的服务器地址就OK了,端口我们就用默认的80端口就行了,如果80端口被占用了就另外设置一个1024后面的一个自由端口号。按照常规的windows软件安装过程完成后,我们需要对服务器进行配置。在我们的安装目录里面,我们找到conf文件夹下的httpd.conf文件,用文本编辑器打开,找到DocumentRoot这个参数,对这个参数的映射路径改成我们项目的全路径,(或者将我们的整个项目拷贝到安装目录的htdocs文件夹里面)。完成后,确保我们的http server处于running状态,我们就在浏览器输入127.0.0.1:80来检测我们的安装是否已经成功。当页面输出为it works!证明安装配置OK了。
建立客户端项目:
将我们下载好的OpenLayers框架解压,配置我们需要的文件,将里面的lib文件夹和img文件夹以及OpenLayers.js一起拷贝到安装目录的htdocs文件目录里面。这里我们采取的是第二种简单的方法,针对单个项目比较实用,但是随着项目的增加,就必须配置DocumentRoot的映射值了。
客户端页面开发:
我们选用UltraEdit多格式文本编辑器来编写我们客户端页面。当然我们也可以选择Dreamveaver 来进行页面编写,可以适当地提高开发效率。我们选用开发语javascript,html和CSS(层叠演示表)来进行开发。
定义并加载地图图层(用重要代码说明):
var options={
allOverlays:true,
controls: [],
projection: new OpenLayers.Projection("EPSG:900913"),
units: "m",
numZoomLevels: 18,
maxResolution: 1220,
maxExtent: new OpenLayers.Bounds(-20037508.34, -20037508.34, 20037508.34, 20037508.34)
}
var map,wsc,wcity,wriver,westation;
var geographic = new OpenLayers.Projection("EPSG:4326");
var mercator = new OpenLayers.Projection("EPSG:900913");
map = new OpenLayers.Map('map',options);
var gphy = new OpenLayers.Layer.Google(
"Google 地形数据",
{type: google.maps.MapTypeId.TERRAIN,
visibility:true,
'sphericalMercator': true,
numZoomLevels: 20,
isBaseLayer:false
}
);
OpenLayers.Projection.addTransform("EPSG:3857", "EPSG:900913",
OpenLayers.Projection.nullTransform);
wsc=new OpenLayers.Layer.WMS("四川行政地图",
"http://localhost:8082/geoserver/wms/",
{layers:"cesar:sc_region",
transparent:true},
{isBaseLayer:true,
numZoomLevels:15});
wsc.setOpacity(0.618);
wcity=new OpenLayers.Layer.WMS("省内地级市",
"http://localhost:8082/geoserver/wms/",
{layers:"cesar:regionalCity_chip",
transparent:true},
{isBaseLayer:false,
numZoomLevels:15}
);
wriver=new OpenLayers.Layer.WMS("主要河流水域",
"http://localhost:8082/geoserver/wms/",
{layers:"cesar:river_chip",
transparent:true},
{isBaseLayer:false,
numZoomLevels:15});
westation=new OpenLayers.Layer.WMS("发电站一览",
"http://localhost:8082/geoserver/wms/",
{layers:"cesar:eSation_chip",
transparent:true},
{isBaseLayer:false,
numZoomLevels:15});
map.addLayers([wsc,gphy,wriver,wcity,westation]);//面线点的顺序叠加进去。
map.zoomToExtent(extent.transform(geographic,mercator));
将我们的地图以WebGIS的形式加载到http server上,通过我们的浏览器,打开地址栏,输入http://127.0.0.1/scsurvey.html ,将看到下面的效果显示。
当我们可以进行页面展示的时候,我们需要进行简单的查询功能,我们可以通过对map对象的事件注册来处理。我们需要添加一下代码就可以实现。我们参照OGC标准进行查询功能的代码编写。
map.events.register('click', map, function (e) {
var url = "http://localhost:8082/geoserver/wms/"
+ "?REQUEST=GetFeatureInfo"
+ "&EXCEPTIONS=application/vnd.ogc.se_xml"
+ "&BBOX=" + map.getExtent().toBBOX()
+ "&X=" + e.xy.x
+ "&Y=" + e.xy.y
+ "&INFO_FORMAT=text/html"
+ "&QUERY_LAYERS=cesar:eSation_chip,cesar:river_chip"
+ "&LAYERS=cesar:eSation_chip,cesar:river_chip"
+ "&FEATURE_COUNT=50"
+ "&SRS=EPSG:900913"
+ "&STYLES="
+ "&WIDTH=" + map.size.w
+ "&HEIGHT=" + map.size.h;
window.open(url,
"getfeatureinfo",
"status=no,toolbar=no,menubar=no,titelbar=no,width=600,height=150"
);
});
经过编写代码,我们来测试,直接点解map,对南充北部的那个电站和河流进行查询,得到查询结果:电站名称:盘龙电站;河流为:西河和嘉陵江。效果截图为:
我们还需要一些基本的测量功能,比如说长度和面积测量,在OpenLayers这个框架中提供了这个函数,可以实现。我们给出重要代码。
var measureControls = {
line: new OpenLayers.Control.Measure(
OpenLayers.Handler.Path, {
persist: true,
handlerOptions: {
layerOptions: {styleMap: styleMap}
}
}
),
polygon: new OpenLayers.Control.Measure(
OpenLayers.Handler.Polygon, {
persist: true,
handlerOptions: {
layerOptions: {styleMap: styleMap}
}
}
)
};
上面定义了测量控件要测量的类型是线和面。通过Hashtable的(键值对)方式存入到mesureControls数组里面。
var control;
for(var key in measureControls) {
control = measureControls[key];
control.events.on({
"measure": handleMeasurements,
"measurepartial": handleMeasurements
});
map.addControl(control);
}
document.getElementById('noneToggle').checked = true;
}
通过for循环取出measureControls数组中的对象,用on()范围内的代码段作为事件的监听程序,然后将这个控件添加到地图对象。
function handleMeasurements(event) {
var geometry = event.geometry;
var units = event.units;
var order = event.order;
var measure = event.measure;
var element = document.getElementById('output');
var out = "";
if(order == 1) {
out += "measure: " + measure.toFixed(3) + " " + units;
} else {
out += "measure: " + measure.toFixed(3) + " " + units + "<sup>2</" + "sup>";
}
element.innerHTML = out;
}
提供了函数用来实现测量和输出测量结果。对上面的代码我们可以测试效果:比如我们要测量成都到南充的距离:首先选择测量距离单选框,在上图分别点解成都,南充:
由上图可知成都到南充距离为229.442km。而实际上南充到成都就200多km。但是不同地图选择的投影方式不同,测量的结果有一定的出入。
我们在测试一下南充嘉陵江中坝的面积。选择测量面积,就找到中坝的位置,将其边界勾勒出,然后双击确定,得到以下结果。
当前图中中坝的面积为1.776平法公里。可能由于季节不同会影响成图,自然会影响到成图的测量面积,存在一定的误差。因此本项目所提供的测距和测量面积功能只能提供大概的参考数据。
水电站位置地形查看示例。比如我们选择电站分布密集的西昌地区安宁河小高乡某个电站群来分析一下:
从整体看来,这三个电站都分布在地势较低的河谷地区,在这里多条河流汇集,存储了巨大的势能,适合构建大坝来利用水电资源。我们甚至可以进一步放大查看电站的大概高程值,比如说普荫寺那个点的电站,我们进一步查询查看,可得这电站名叫小高桥电站。高程大概为1350m.在川西的山区地势来看,处于河谷地带,可以累积足够多的势能,利于发电站的建立。

浙公网安备 33010602011771号