svg+JS 实现 的一个小GIS

本文介绍如何使用SVG和Raphael JavaScript库创建一个简单的地理信息系统(GIS),包括地图的导入、拖动、缩放及框选放大等功能的实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

想起来自己也是学习地理信息系统专业的学生,于是想着还是要做点和地理信息系统有关系的事情才对.

于是想用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();
                        
                    }

好了,到这里,三个功能就都实现了(漫游,滚轮缩放,拖框放大)。地图操作的基本功能有了。以后还准备做一点打点,加入地理信息的功能。等做好了再弄上来。

转载于:https://www.cnblogs.com/XHuangX/archive/2013/05/05/3057820.html

/* *author:XudongChen *Date:2010-03-09 *QQ:233828249 81023617(不才) *Email:xznd@163.com */ 2009-8-13 1.加载分块地图 2.添加全景标记窗体 2009-8-14 1.增加控制条 2.增加全景标记、公交车标记显示层 3.解决地图定位问题 4.增加经纬度层功能 5.未修正图标层的定位 2009-8-15 1.已修正8.14地图定位错误,还存在放大缩小时定位不准 2.存在ie内存泄漏问题 2009-8-16 1.已修正8.15 ie内存泄漏问题,chrome下可能还存在内存泄漏 2.增加图标定位功能 3.增加鼠标滚轮事件(http://yongzhi.blog.hexun.com/5057947_d.html) 4.通过jquery加载json数据文件(图标显示层数据) 2009-8-17 1.增加建筑物高亮显示(还需完成鼠标mouseover和mouseout事件) 2009-8-18 1.完成建筑物高亮显示,有点小bug 2009-8-19 1.增加记录原始缩放比例的全局变量 2.解决建筑物高亮显示bug 2009-8-20 1.增加三维全景展示功能 2.浏览建筑详细功能 2009-8-21 1.引入jqueryAlert插件,美化弹出窗体 2009-8-23 1.增加搜索功能 2.清理建筑信息显示页和公交信息页多余数据 2009-10-22 1.增加小沙盘拖动类(鹰眼视图) BirdEye.js 完成小沙盘到地图的同步,同步方法:检测mouseup事件触发->修改url->request->计算坐标->同步行为 2.增加小沙盘样式表BirdEye.css 地图图片路径birdeyemap 3.完成window.parent地图->小沙盘的同步 问题:小沙盘->window.parent地图存在bug,可以尝试开启 2009-10-23 1.在小沙盘中增加浮动绿色框 2009-11-6 1.实现“鹰眼地图”不需移动,一幅可以看到见全景, 当主场景移动时,“鹰眼地图”只有小框在移动。 同时“小框” 主场景也在移动。 2009-12-17 1.测距功能事件配置 2009-12-21 1.完成测距功能 2009-12-22 1.配置搜索功能,后台改用s2sh框架 2.完成hessian+spring+hibernate整合,提供建筑信息和公司信息hessian查找服务 2009-12-23 1.配置hessian服务端缓存 2.配置hessian日志记录,输出到文件/log/wzucxd/html 3.完成建筑信息显示页,配置2级缓存 4.配置oscache 5.配置新闻信息模块 2010-1-13 1.完成chrome和ff下的搜索功能 2.搜索功能支持ie6.0+ //设置Theodolite$setPoint var cpointtmp = new CPoint(this.holder.offsetLeft + evt.clientX - this.mvl.offsetLeft, this.mvl.offsetTop + evt.clientY - this.mvl.offsetTop); Theodolite$setPoint(cpointtmp);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值