最近一段時間里,又做了一個跟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下載的。