想起來自己也是學習地理信息系統專業的學生,於是想着還是要做點和地理信息系統有關系的事情才對.
於是想用svg來實現一個小的地理信息系統.
想來應該是很酷的東西~
老師給我介紹了了一個叫做Raphael的開源庫.利用這個可以做出很多svg的漂亮效果,並且添加事件也會很容易。(謝!)
Raphael的網址是:http://raphaeljs.com
大家可以看一下,上面有很多的例子.並且文檔也很詳細.
有一個中文的在線文檔,地址是http://julying.com/lab/raphael-js/docs/
好了。下面來說如何實現:
首先.一個GIS系統,需要地理底圖,這里因為找不到合適的矢量圖,我從網上找了一個柵格圖,然后用inkscape簡單的矢量化了一下.將就用吧~

好了咱們給它命名為mapHB.svg。
然后我們要把這個圖導入成為底圖:
(ps:因為最近使用的是thinkphp的框架做東西,所以這里也是使用的thinkphp框架來做的~)
在php這邊,我們要把svg的信息讀出:
1 $fileName="./Public/Svg/mapHB.svg"; 2 $content=file_get_contents($fileName); 3 //讀出svg文件內容4 //替換掉svg文本中的換行。避免SVGimport出錯。 5 $content=preg_replace( "([\r\n])","", $content); 6 $this->assign("content",$content);
讀出后assign在content上。然后在模板這邊畫上,首先,我們要引入一些庫。
1 <script type="text/javascript" src="__PUBLIC__/Js/raphael.2.1.0.min.js"></script><!--Raphael--> 2 <script type="text/javascript" src="__PUBLIC__/Js/raphael-svg-import.js"></script><!--svg導入--> 3 4 <script type="text/javascript" src="__PUBLIC__/Js/jquery.js"></script> 5 <script type="text/javascript" src="__PUBLIC__/Js/jquery.mousewheel.min.js"></script><!--這個是滾輪事件的jquery庫-->
第一個是raphael的庫,第二個是svg導入的庫。最后一個是鼠標滾輪事件的庫。
好,現在要導入svg圖:
var box=document.getElementById('paper'); //這里是滾輪事件。這里paper是一個全局變量 //paper的_viewBox屬性原本是沒有的,但是在設置setViewBox后就有了。所以要先對paper使用setViewBox //當然縮放過程必須按照比例來。 $('#paper').mousewheel(function(event, delta, deltaX, deltaY) { if(delta>0){ var sX=paper._viewBox[0]; var sY=paper._viewBox[1]; var sW=paper._viewBox[2]; var sH=paper._viewBox[3]; var bili=sH/sW; var H=70*bili; if(sW-70>0&&sH-H>0){ paper.setViewBox(sX+35,sY+H/2,sW-70,sH-H); } }else{ var sX=paper._viewBox[0]; var sY=paper._viewBox[1]; var sW=paper._viewBox[2]; var sH=paper._viewBox[3]; var bili=sH/sW; var H=70*bili; paper.setViewBox(sX-35,sY-H/2,sW+70,sH+H); } }); //這里是設置畫布的大小 需要調整一下。 paper = Raphael("paper",box.clientWidth-20,window.innerHeight-45); //這里就是導入svg圖像。 var newSet = paper.importSVG('{$content}');
導入成功后,我們要給地圖做拖動事件,也就是gis里的漫游,基本思想是:因為在原有的導入的svg上拖動的話,由於填充問題,有的地方不能響應raphael的drag事件,所以我們可以新建一個極大的rect,來覆蓋整個地圖,以及周圍區域。並用透明色填充。這樣可以看見底圖,並且可以響應拖動。
當然我們要做3個功能,漫游,拖框放大,滾輪縮放。區分這三個功能的方法,我是用的鼠標樣式,首先點擊功能按鈕,改變鼠標樣式,然后在和地圖交互的過程中,判斷鼠標的樣式,就可以知道是什么功能。
改變樣式的實現如下:
$('#move').click(function(){
document.getElementById('paper').style.cursor="move";
}).mouseover(function(){
$('#move').animate({
width:30
});
}).mouseout(function(){
$('#move').animate({
width:24
});
});
$('#zoomAll').click(function(){
paper.setViewBox(0,0,box.clientWidth,box.clientHeight,true);
}).mouseover(function(){
$('#zoomAll').animate({
width:30
});
}).mouseout(function(){
$('#zoomAll').animate({
width:24
});
});
$('#zoom').click(function(){
document.getElementById('paper').style.cursor="nw-resize";
}).mouseover(function(){
$('#zoom').animate({
width:30
});
}).mouseout(function(){
$('#zoom').animate({
width:24
});
});
然后,我們就可以根據樣式來做各種功能了。
我們先來看看drag事件的用法:
Element.drag(onmove, onstart, onend, [mcontext], [scontext], [econtext])
前3個函數是必須的,一個是在鼠標拖動過程中的事件,一個是開始拖動的事件,一個是結束拖動的事件。
onmove有5個參數(dx,dy,x,y,event);
分別是x移動距離,y移動距離,鼠標位置x,y。
onstart有3個參數(x,y,event);
就是鼠標的x,y
onend只有一個(event)
首先是move(漫游):
直接在onmove事件添加這個function就可以實現:
if(action=="move"){ x0=paper._viewBox[0]-dx/30; y0=paper._viewBox[1]-dy/30; W=paper._viewBox[2]; H=paper._viewBox[3]; paper.setViewBox(x0,y0,W,H,true); }
然后是拖框放大:
基本思想是,拖框,畫出一個矩形,然后根據矩形的寬度來按照比例調整viewBox大小,這樣就可以實現縮放。
首先開始拖動的時候,記錄下來開始拖動的點。但是要把鼠標的clientx,y轉換成畫布的位置坐標:
if(action=="nw-resize"){ //獲取畫布上的坐標 var box=document.getElementById('paper'); var scrollX; var scrollY; if(window.scrollX||window.scrollY){ scrollX=window.scrollX; scrollY=window.scrollY; }else{ scrollX=document.documentElement.scrollLeft; scrollY=document.documentElement.scrollTop; } var bx=$('#paper').offset().left-scrollX; var by=$('#paper').offset().top-scrollY; //var bx=0; //var by=0; var zoombiliW=originalScaleW/paper._viewBox[2]; var zoombiliH=originalScaleH/paper._viewBox[3].toFixed(0); var mx=((event.clientX-bx)/zoombiliW+paper._viewBox[0]); var my=((event.clientY-by)/zoombiliH+paper._viewBox[1]); DstartX=mx; DstartY=my; }
然后在onmove中就要畫rect了:
if(action=="nw-resize"){ var zoombiliW=originalScaleW/paper._viewBox[2]; var zoombiliH=originalScaleH/paper._viewBox[3].toFixed(0); //存在area的話先remove,這樣才能有拖框的效果 if(area){ area.remove(); area=paper.rect(DstartX,DstartY,dx/zoombiliW,dy/zoombiliH); } else{ area=paper.rect(DstartX,DstartY,dx/zoombiliW,dy/zoombiliH); } }
最后在onend里,就要根據rect來放大了:
if(action=="nw-resize"){ var x=area.attrs.x; var y=area.attrs.y; var width=area.attrs.width; var sW=paper._viewBox[2]; var sH=paper._viewBox[3]; var bili=sH/sW; var height=width*bili; paper.setViewBox(x,y,width,height); //最后還是把框remove掉咯。 area.remove(); }
好了,到這里,三個功能就都實現了(漫游,滾輪縮放,拖框放大)。地圖操作的基本功能有了。以后還准備做一點打點,加入地理信息的功能。等做好了再弄上來。
