最近一段时间里,又做了一个跟openlayers相关的项目,但是到目前为止,我对openlayers还是不怎么了解,做东西也只是参考了openlayers的例子,以及自己的一些对openlayers用法的一些猜测。openlayers是一个用js实现的GIS前端框架,我的js目前还是打酱油的水平,要是没有jquery,那就基本写不了几行js代码了。js那是相当的强大,再加上VML\SVG、HTML5以及很多js rich框架等等,感觉js在浏览器端真是无所不能啊

目前这个项目主要功能就是在某城市的地图上标示电缆、光缆、井盖、光缆接头、线杆、建筑物形状和位置、各分级单位的位置以及快速定位等等,要求的功能很简单,而且有前段时间做学校电子地图的一些积累,所以大概在两周左右就做完了这个项目。

感觉openlayers的资料很少,自己也没有太多的时间和精力去读它的源码,目前我都是通过看openlayers自带的那些example和api文档来摸索的,下面简单总结一下openlayers的相关用法,欢迎大家拍砖。
(以下均以OpenLayers-2.9.1为例说明,完整的项目代码在这里下载,地图图片http://121.193.130.68/list/

1、我只用到了openlayers里面的tilecache接口,其它的例如WMS,google map等等都没有用到。原因是这样的。tilecache接口是用来从tilecache服务器上请求图片的。通过观察google map或者一些其它的地图服务,发现他们都是使用256x256像素大小的图片(也就是tile)来拼接地图的,通常的做法是在gis服务器之间架设一个tilecache服务器,这样,gis生成的图片就可以缓存在tilecahe服务器上,而tilecache服务器仅仅提供简单http服务即可,如果请求的图片(tile)不在tilecache服务器上,那么tilecache服务器会想gis服务器请求,把把gis生成的图片缓存在tilecache服务器上。
通过观察tilecache服务器的目录结构,发现缓存图片按照这样的模具结构存放:{缩放级别}/{横坐标}/{纵坐标}.{图片格式后缀名},注意这个坐标系的原点在屏幕的左下角。观察到这个规律以后,就可以直接把一张大的地图按照256x256的大小切割,并按照上述的目录结构存放,值得注意的是,每个缩放级别要一定满足2^n的规律,即第一级整个地图大小若为1,那么第二级整个地图大小应为2,第三级应为4,依次类推。这里需要简单修改一下openlayers的tilecache接口代码,文件位于OpenLayers-2.9.1\lib\OpenLayers\Layer\TileCache.js,修改如下:

1 var components = [
2 this.layername,
3 zeroPad(tileZ, 2),
4 //zeroPad(parseInt(tileX / 1000000), 3),
5 //zeroPad((parseInt(tileX / 1000) % 1000), 3),
6 zeroPad((parseInt(tileX) % 1000), 3),
7 //zeroPad(parseInt(tileY / 1000000), 3),
8 //zeroPad((parseInt(tileY / 1000) % 1000), 3),
9 zeroPad((parseInt(tileY) % 1000), 3) + ‘.’ + this.extension
10 ];

同样,由于只使用tilecache,所以openlayers里面其它的代码也可删除,以减小openlayers的代码量,最后通过自带的python写的工具,压缩openlayers代码即可。

2.地图初次加载的时候,向服务器请求所有数据信息,并在地图上绘出相应的点线面。如何画出建筑的轮廓?用透明的就行了。
a.显示点信息,包括画点、用图标显示点,代码如下。

1 /*
2 * 在地图上画出所有的点并保存点的相关信息到字典中
3 */
4 function initFeaturePoint(vectorLayer,categoryId){
5 //get point json
6 point_data = getFeatureData(‘point’,categoryId);
7 var target_info = [];
8 // create a point feature
9 for(index in point_data){
10 single_point = point_data[index].point.split(" “);
11 pointX = single_point[0];
12 pointY = single_point[1];
13
14 //画点
15 var point = new OpenLayers.Geometry.Point(Number(pointX), Number(pointY));
16
17
18 var style_point = {
19 strokeColor: point_data[index].strokeColor,
20 strokeWidth: 2,
21 strokeDashstyle: “solid”,
22 pointRadius: 6,
23 strokeOpacity: 0.8,
24 fillOpacity: 0.8,
25 //label:point_data[index].title,
26 fontSize:‘12px’,
27 fontFamily:‘宋体’,
28 labelXOffset:0,
29 labelYOffset:-15,
30 labelAlign:’m’,
31 fillColor: point_data[index].strokeColor
32 };
33
34 //显示标记文字,把文字放在底下一层,这样上面的就不会选不上了
35 var pointText = new OpenLayers.Geometry.Point(Number(pointX), Number(pointY));
36 showPointTextTips(pointText, point_data[index].title);
37
38 pointFeature = new OpenLayers.Feature.Vector(point, null, style_point);
39 vectorLayer.addFeatures([pointFeature]);
40
41 /收集点的信息/
42 id = point_data[index].id;
43 titles = point_data[index].title;
44 description = point_data[index].description;
45 strokeColor = point_data[index].strokeColor;
46 iconUrl = point_data[index].iconUrl;
47 iconUrl2 = point_data[index].iconUrl2;
48 array_index = pointFeature.id;
49 target_info[array_index] = {“id”:id,“title”:titles,“description”:description,“strokeColor”:strokeColor,“iconUrl”:iconUrl,“iconUrl2”:iconUrl2,“pointX”:pointX,“pointY”:pointY};
50 //alert(target_info[array_index]);
51 }
52 return target_info;
53 }

1 /*
2 * 在地图上画出所有的点并保存点的相关信息到字典中
3 */
4 function initFeatureImagePoint(vectorLayer,categoryId,imageUrl){
5 //get point json
6 point_data = getFeatureData(‘point’,categoryId);
7 var target_info = [];
8 // create a point feature
9 for(index in point_data){
10 single_point = point_data[index].point.split(” “);
11 pointX = single_point[0];
12 pointY = single_point[1];
13
14 //画点
15 var point = new OpenLayers.Geometry.Point(Number(pointX), Number(pointY));
16
17
18 var style_point = {
19 graphicWidth : 32,
20 graphicHeight: 32,
21 externalGraphic:imageUrl,
22 graphicTitle:point_data[index].title
23 };
24
25
26 pointFeature = new OpenLayers.Feature.Vector(point, null, style_point);
27 vectorLayer.addFeatures([pointFeature]);
28
29 /收集点的信息/
30 id = point_data[index].id;
31 titles = point_data[index].title;
32 description = point_data[index].description;
33 strokeColor = point_data[index].strokeColor;
34 iconUrl = point_data[index].iconUrl;
35 iconUrl2 = point_data[index].iconUrl2;
36 array_index = pointFeature.id;
37 target_info[array_index] = {“id”:id,“title”:titles,“description”:description,“strokeColor”:strokeColor,“iconUrl”:iconUrl,“iconUrl2”:iconUrl2,“pointX”:pointX,“pointY”:pointY};
38 //alert(target_info[array_index]);
39 }
40 return target_info;
41 }

b.画线

1 /**
2 在地图上画出所有的线并保存点的相关信息到字典中
3 */
4 function initFeatureLine(vectorLayer,categoryId)
5 {
6
7 linestring_data = getFeatureData(’line’,categoryId);
8 var target_info = [];
9 // create all line features from a list of points
10 for(index in linestring_data){
11 var pointList = [];
12 linestring_points = linestring_data[index].point.split(”,");
13 for(inner_index in linestring_points){
14 single_point = linestring_points[inner_index].split(" “);
15 pointX = single_point[0];
16 pointY = single_point[1];
17 newPoint = new OpenLayers.Geometry.Point(Number(pointX), Number(pointY));
18 pointList.push(newPoint);
19 }
20 var linestring = new OpenLayers.Geometry.LineString(pointList);
21 var style_line = {
22 strokeColor: linestring_data[index].strokeColor,
23 strokeOpacity: 0.8,
24 strokeWidth: linestring_data[index].strokeWidth,
25 pointRadius: 20,
26 //label:linestring_data[index].title,
27 fontSize:‘12px’,
28 fontFamily:‘宋体’,
29 labelXOffset:30,
30 labelYOffset:10,
31 labelAlign:‘rm’
32 };
33 lineFeature = new OpenLayers.Feature.Vector(linestring,null,style_line);
34 vectorLayer.addFeatures([lineFeature]);
35
36 //显示标记文字
37 single_point = linestring_points[0].split(” “);
38 pointX = single_point[0];
39 pointY = single_point[1];
40 var pointText = new OpenLayers.Geometry.Point(Number(pointX), Number(pointY));
41 showPointTextTips(pointText, linestring_data[index].title);
42
43 /收集路的信息/
44 id = linestring_data[index].id;
45 titles = linestring_data[index].title;
46 linelength = linestring_data[index].linelength;
47 description = linestring_data[index].description;
48 strokeColor = linestring_data[index].strokeColor;
49 strokeWidth = linestring_data[index].strokeWidth;
50 iconUrl = linestring_data[index].iconUrl;
51 iconUrl2 = linestring_data[index].iconUrl2;
52 array_index = linestring.id;
53 target_info[array_index] = {“id”:id,“title”:titles,“linelength”:linelength,“description”:description,“strokeColor”:strokeColor,“strokeWidth”:strokeWidth,“iconUrl”:iconUrl,“iconUrl2”:iconUrl2};
54 }
55 return target_info;
56 }

c.画面

1 /**
2 在地图上画出所有的多边形区域路并保存点的相关信息到字典中
3 */
4 function initFeaturePolygon(vectorLayer,categoryId)
5 {
6 polygon_data = getFeatureData(‘polygon’,categoryId);
7 var target_info = [];
8 for(index in polygon_data){
9 var pointList = [];
10 polygon_points = polygon_data[index].point.split(”,");
11 for(inner_index in polygon_points){
12 single_point = polygon_points[inner_index].split(" “);
13 pointX = single_point[0];
14 pointY = single_point[1];
15 newPoint = new OpenLayers.Geometry.Point(Number(pointX), Number(pointY));
16 pointList.push(newPoint);
17 }
18 var linearRing = new OpenLayers.Geometry.LinearRing(pointList);
19 var polygon = new OpenLayers.Geometry.Polygon([linearRing]);
20 var style_polygon = {
21 strokeColor: polygon_data[index].strokeColor,
22 strokeWidth: 2,
23 strokeOpacity: 0.8,
24 fillOpacity: 0.8,
25 //label:polygon_data[index].title,
26 fontSize:‘12px’,
27 fontFamily:‘宋体’,
28 labelXOffset:0,
29 labelYOffset:-15,
30 labelAlign:’m’,
31 fillColor: polygon_data[index].strokeColor
32 };
33 polygonFeature = new OpenLayers.Feature.Vector(polygon,null,style_polygon);
34 vectorLayer.addFeatures([polygonFeature]);
35
36
37 //显示标记文字
38 single_point = polygon_points[0].split(” “);
39 pointX = single_point[0];
40 pointY = single_point[1];
41 var pointText = new OpenLayers.Geometry.Point(Number(pointX), Number(pointY));
42 showPointTextTips(pointText, polygon_data[index].title);
43
44 /收集图形的信息/
45 id = polygon_data[index].id;
46 titles = polygon_data[index].title;
47 description = polygon_data[index].description;
48 type_id = polygon_data[index].type_id;
49 strokeColor = polygon_data[index].strokeColor;
50 iconUrl = polygon_data[index].iconUrl;
51 iconUrl2 = polygon_data[index].iconUrl2;
52 array_index = polygon.id;
53 //alert(array_index);
54 target_info[array_index] = {“id”:id,“title”:titles,“description”:description,“type_id”:type_id,“strokeColor”:strokeColor,“iconUrl”:iconUrl,“iconUrl2”:iconUrl2};
55 }
56 return target_info;
57 }

d.复制一条线

1 /**
2 *
3 * 复制线到某一层
4 * @param desvectors
5 * @param linestring
6 * @return
7 */
8 function cloneLine(vectorLayer,linestring)
9 {
10 linestring_points = linestring.substring(“LINESTRING”.length + 1,linestring.length - 1);
11 //alert(linestring_points);
12 var pointList = [];
13 line_points = linestring_points.split(”,");
14 for(inner_index in line_points){
15 single_point = line_points[inner_index].split(" “);
16 pointX = single_point[0];
17 pointY = single_point[1];
18 newPoint = new OpenLayers.Geometry.Point(Number(pointX)+0.2, Number(pointY)+0.2);
19 pointList.push(newPoint);
20 }
21 var linestringtmp = new OpenLayers.Geometry.LineString(pointList);
22 var style_line = {
23 strokeColor: “red”,
24 strokeOpacity: 1,
25 strokeWidth: 6,
26 pointRadius: 20
27 };
28 //var tmpVector = vectorLayer == ’lightlinelayer’ ? lightlinelayer : linelayer;
29 var tmpVector;
30 if(vectorLayer == ’lightlinelayer’)
31 tmpVector = lightlinelayer;
32 else if(vectorLayer == ’linelayer’)
33 tmpVector = linelayer;
34 else
35 tmpVector = policelightlinelayer;
36
37 lineFeature = new OpenLayers.Feature.Vector(linestringtmp,null,style_line);
38 tmpVector.addFeatures([lineFeature]);
39 }

e.计算一条线的长度

1 /计算线的长度/
2 function getLengthOfALine(linestring)
3 {
4 //alert(linestring);
5 linestring_points = linestring.substring(“LINESTRING”.length + 1,linestring.length - 1);
6 //alert(linestring_points);
7 var pointList = [];
8 line_points = linestring_points.split(”,");
9 lineLength = 0;
10 for(inner_index in line_points){
11 if(inner_index > 0)
12 {
13 single_point = line_points[inner_index].split(" “);
14 pointX = Number(single_point[0]);
15 pointY = Number(single_point[1]);
16
17 old_single_point = line_points[inner_index - 1].split(” “);
18 old_pointX = Number(old_single_point[0]);
19 old_pointY = Number(old_single_point[1]);
20
21 lineLength = lineLength + Math.sqrt((pointX - old_pointX) * (pointX - old_pointX) + (pointY - old_pointY) * (pointY - old_pointY));
22 }
23 }
24 return lineLength.toFixed(4);
25 }

f.删除一个地图元素

1 function deleteFeature(featureId)
2 {
3
4 if(!confirm(“您确定要删除这个地图标记吗?”))
5 return;
6 var feature = null;
7 //alert(lightlinelayer.getFeatureById(featureId));
8 feature = lightlinelayer.getFeatureById(featureId);
9 //alert(feature);
10 if(feature != null)
11 {
12 if(lineDataList[feature.geometry.id])
13 {
14 deleteFeatureByIdAndType(lineDataList[feature.geometry.id].id,’line’);
15 }
16 map.removePopup(feature.popup);
17 feature.popup.destroy();
18 feature.popup = null;
19 lightlinelayer.destroyFeatures([feature]);
20 return;
21 }

地图图片是从google map下载的。