• OpenLayers 3 地图控件(control)详解


    2015-05-14 08:43  958人阅读  评论(7)  收藏  举报
    0
      分类:
    WebGIS(28) 
    0
    OpenLayers(17) 
    0
    版权声明:本文为博主原创文章,未经博主允许不得转载。
    目录(?)[+]
          每一个地图应用都应该有一些工具方便用户控制地图的行为,比如缩放,全屏,坐标控件等等,在 OpenLayers 中怎么添加这些工具呢?下面我给大家介绍一下 OpenLayers 中包含的控件种类,并介绍其使用方法。对控件的定制化,和对 OpenLayers 增加控件和优化控件等超出了本文范围。
    一、control 类
          OpenLayers 中的控件是由 control 类定义的,这是一个虚基类,不负责实例化特定的控件,它的主要作用是让其他具体的种类的控件类实现继承。OpenLayers 中包含的控件有:
    • controldefaults,地图默认包含的控件,包含缩放控件和旋转控件;
    • fullscreencontrol,全屏控件,用于全屏幕查看地图;
    • mousepositioncontrol,鼠标位置控件,显示鼠标所在地图位置的坐标,可以自定义投影;
    • overviewmapcontrol,地图全局视图控件;
    • rotatecontrol,地图旋转控件;
    • scalelinecontrol,比例尺控件;
    • zoomcontrol,缩放控件;
    • zoomslidercontrol,缩放刻度控件;
    • zoomtoextentcontrol,缩放到全局控件。
    下面我们来分别介绍各种控件的使用方法。
    二、控件举例介绍
    1. fullscreen control - 全屏控件
          地图全屏控件,该控件提供一个全屏按钮,当点击的时候,地图充满整个屏幕(注意是整个屏幕,而不是整个浏览器窗口);当在全屏模式时,在屏幕的右上角会出现一个退出按钮,用于退出全屏模式,同时按 Esc 按钮也可以退出全屏模式。在 map 对象中添加如下代码:
    controls: ol.control.defaults().extend([ new ol.control.FullScreen() ]),
    • 1
    • 2
    • 3
    刷新浏览器运行代码,结果如下图: 
    0
     
    点击全屏后,全屏按钮变成退出按钮,点击即可退出全屏模式,同时点击 ESC也可以退出全屏模式: 
    0
     
    2. mouseposition control - 鼠标位置控件
          鼠标位置控件,用于显示鼠标指针 2D 坐标,默认情况下,它显示的是地图的 view 对象中设置的投影,但是可以修改为任意投影。鼠标位置控件是加载在地图右上角的位置,如,我们在以上全屏控件的基础上加如下代码:
    controls: ol.control.defaults().extend([ new ol.control.FullScreen(), new ol.control.MousePosition() ]),
    • 1
    • 2
    • 3
    • 4
    刷新浏览器,得到结果截图如下: 
    0
     
          这个默认的鼠标位置控件,连全屏按钮都遮盖了,为了避免遮盖,我们将鼠标位置控件移动到别的地方,右下角是一个不错的地方,那么怎么修改位置呢?
     
          有两种解决方法,一种是修改 ol.control.MousePosition 的可选参数的默认值;二是覆盖其默认的 CSS 样式类,这种方法我们后面会讲到。
    这里我们用第一种方法做例子,控件的可选参数如下:
    /** * @typedef {{className: (string|undefined), * coordinateFormat: (ol.CoordinateFormatType|undefined), * projection: ol.proj.ProjectionLike, * render: (function(ol.MapEvent)|undefined), * target: (Element|undefined), * undefinedHTML: (string|undefined)}} * @api stable */
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    重要的参数如下:
    • className,显示坐标的 HTML 元素的 class 值,如果不设置,就会默认 ol-mouse-position,也就是默认动态生成的;
    • coordinateFormat,设置坐标显示的格式,保留小数点后几位等;
    • projection,投影信息,表示显示的坐标的投影坐标系。
    知道用法后,我们就先定义将要显示坐标的 HTML 元素:
    <div id="mouse-position" class="mouse-position-wrapper"> <div class="custom-mouse-position">div> div>
    • 1
    • 2
    • 3
    我们要将该 div元素悬浮在地图之上,而默认情况下,map 的 z-index值很大,要悬浮在 map 之上,就要定义更大的 z-index。定义如下:
    .mouse-position-wrapper{ 300px; height:29px; color:#FFFFFF; position:absolute; right:20px; bottom:6px; z-index:999; }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    该CSS将控件放在右下角的位置,然后修改 MousePosition 对象:
    controls: ol.control.defaults().extend([ new ol.control.FullScreen(), new ol.control.MousePosition({ coordinateFormat: ol.coordinate.createStringXY(4), projection: 'EPSG:4326', className: 'custom-mouse-position', target: document.getElementById('mouse-position') }) ]),
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    再次运行代码,得到如下效果: 
    0
     
    3. overviewmap control - 全局地图控件
    全局地图控件,显示当前视口中的地图位于全局地图的哪一部分,可选的参数如下:
    /** * @typedef {{collapsed: (boolean|undefined), * collapseLabel: (string|Node|undefined), * collapsible: (boolean|undefined), * label: (string|Node|undefined), * layers: (Array.<ol.layer.Layer>|ol.Collection|undefined), * render: (function(ol.MapEvent)|undefined), * target: (Element|undefined), * tipLabel: (string|undefined)}} * @api */
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    参数的意义为:
    • collapsed,收缩选项;
    • collapseLabel,收缩后的图标按钮;
    • collapsible,是否可以收缩为图标按钮,默认为 true;
    • label,当 overviewmapcontrol 收缩为图标按钮时,显示在图标按钮上的文字或者符号,默认为 »;
    • layers,overviewmapcontrol针对的图层,默认情况下为所有图层;
    • render,当 overviewmapcontrol 重新绘制时,调用的函数;
    • target,放置的 HTML 元素;
    • tipLabel,鼠标放置在图标按钮上的提示文字。
    以上参数都为可选,添加如下代码:
    new ol.control.OverviewMap({})
    • 1
     
    0
     
    默认情况下,控件为收缩状态,点击即可打开,打开后如下图所示:
     
    0
     
    4. rotate control - 地图旋转控件
    地图旋转控件,主要作用是当地图角度不为 0 时,默认显示,点击,使地图恢复旋转角度为 0。可选参数如下:
    /** * @typedef {{duration: (number|undefined), * className: (string|undefined), * label: (string|Node|undefined), * tipLabel: (string|undefined), * target: (Element|undefined), * render: (function(ol.MapEvent)|undefined), * autoHide: (boolean|undefined)}} * @api stable */
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    参数的意义为:
    • duration,在开始角度和目标角度转动特效的持续时间,毫秒为单位,默认 240;
    • className,表示图标的样式,默认为ol-rotate;
    • label,旋转按钮中显示的符号,默认为⇧;
    • tipLabel,鼠标在按钮上时的提示文字,默认为Reset rotation;
    • target,按钮放置的 HTML 元素的 ID ;
    • render,当控件重新绘制的时候,调用的函数;
    • autoHide,当选择角度为 0 的时候,控件是否自动隐藏,默认值为true,也就是默认隐藏。
          默认情况下,该控件不会显示;当地图旋转角度不为 0 时,才会显示,原因是该控件为地图默认添加控件。当该控件显示时候,其默认的位置和全屏控件重合,所以如果想要显示该按钮,那么全屏按钮就会被覆盖。
    有两种方法可以解决该问题:
    1. 按照mousepositioncontrol的方式,将其默认位置放于其它地方;
    2. 覆盖其原有的 CSS 样式,最好不要修改原文件,因为其它地方如果使用的话,就会同样改变。
    这里采用第二种方法,在自己的 CSS 样式表中添加如下代码(因为自己的CSS文件样式优先级比外部链接引入的样式优先级高):
    /* rewrite the default css in `ol.css` */ .ol-rotate{ right:40px; }
    • 1
    • 2
    • 3
    • 4
    添加如下代码:
    new ol.control.Rotate({ autoHide:false })
    • 1
    • 2
    • 3
     
    0
     
    5. scaleline control - 比例尺控件
          比例尺控件,显示当前地图的分辨率,也就是比例尺,默认的位置和 overviewmap control位置重合,要移动位置避免覆盖,同样覆盖默认样式:
    /* rewrite the default css in `ol.css` */ .ol-scale-line { #left:100px; }
    • 1
    • 2
    • 3
    • 4
    添加代码:
    new ol.control.ScaleLine({ }),
    • 1
     
    0
     
    6. zoom control - 缩放控件
          缩放控件,包含两个按钮,一个放大,一个缩小,是默认加载的控件之一,默认的 CSS样式类分别为 .ol-zoom-in和.ol-zoom-out。
     
    0
     
    7. zoomslider control - 缩放条控件
    缩放条控件,主要显示当前的分辨率对应的刻度,给予一个直观的显示,其默认的条没有刻度,如果需要有刻度的,需要自己定制。可选的参数有:
    /** * @typedef {{className: (string|undefined), * duration: (number|undefined), * maxResolution: (number|undefined), * minResolution: (number|undefined), * render: (function(ol.MapEvent)|undefined)}} * @api */
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • maxResolution,表示其最大的分辨率;
    • minResolution,表示最小分辨率。
    其它的选项类似于以上的控件,添加该控件到地图中:
    new ol.control.ZoomSlider({ }),
    • 1
    效果如下: 
    0
     
    8. zoomtoextent control - 缩放到图层控件
    缩放到图层控件,将地图缩放到视口可以容纳整个地图的合适尺度,可选的参数如下:
    /** * @typedef {{className: (string|undefined), * target: (Element|undefined), * label: (string|Node|undefined), * tipLabel: (string|undefined), * extent: (ol.Extent|undefined)}} * @api stable */
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    这个控件也没有什么特殊的选项,除了 extent,表示缩放到范围的大小。需要注意的是该控件位置和 zoomslidercontrol 位置会有部分重叠,同样,我们需要覆盖zoomslidercontrol的样式类: .ol-zoomslider:
    .ol-zoomslider{ top:100px; left: 9px; }
    • 1
    • 2
    • 3
    • 4
    添加如下代码:
    new ol.control.ZoomToExtent({ })
    • 1
    效果如下图: 
    0
     
    我们看一下点击之前和之后的效果对比: 
    0
     
     
    0
     
    点击之后其实已经到了合适的尺寸,但是地图配置为连贯显示,也就是左右不间断,重复拼接在一起,所以会有这样的效果。
    三、总结
          到此为止,我们将 OpenLayers 3 的所有能用的控件都试了一遍,代码最后是这样的:
    map = new ol.Map({ //init map controls: ol.control.defaults().extend([ new ol.control.FullScreen(), new ol.control.MousePosition({ coordinateFormat: ol.coordinate.createStringXY(4), projection: 'EPSG:4326', className: 'custom-mouse-position', target: document.getElementById('mouse-position') }) , new ol.control.OverviewMap({ }), new ol.control.Rotate({ autoHide:false }), new ol.control.ScaleLine({ }), new ol.control.ZoomSlider({ }), new ol.control.ZoomToExtent({ }) ]), target: 'map', layers: [ new ol.layer.Tile({ source: new ol.source.MapQuest({layer: 'sat'}) }), vectorLayer ], view: new ol.View({ center: ol.proj.transform([37.41, 8.82], 'EPSG:4326', 'EPSG:3857'), zoom: 2 }) });
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    我们的地图也变成了这样:
    0
          这幅地图包含了缩放控件、缩放到图层控件、缩放标尺、地图全景控件、比例尺、旋转控件和全屏控件 7 个控件,希望对大家有帮助!
    分类: 学习笔记 Web开发 2012-10-25 17:44  1211人阅读  评论(0)  收藏  举报
    控制器可以使用在地图上,也可以使用在地图之外的元素如
    中。
    添加控制器有两种方式:
    1.在map对象初始化时以js数组的形式把OpenLayers控制器传入
    2.在map对象初始化后,调用addControl()来添加单个控制器或者addControls()传入一个控制器数组对象
    当一个map对象被初始化后,默认会有4种控制器:
    1.OpenLayers.Control.Navigation: 
        用来控制地图与鼠标事件的互动,如拖曳,缩放,滚动,双击。
    2.OpenLayers.Control.PanZoom:
       在地图的左上方添加一个平移与缩放的工具条
    3.OpenLayers.Control.ArgParser:
       使地图可以在缩放到指定大小时根据URL参数打开或关闭一些图层
    4.OpenLayers.Control.Attribution:
       允许通过layer向map添加属性
    如果想要创建一个不包含任何控制器的地图,则在创建map对象时使用下面代码
     
    1. map = new OpenLayers.Map('map_element', {  
    2.   controls: []  //设置一个空的控制器数组以清除默认控制器  
    3. });  
     
    示例:向地图添加控制器
    0
    代码:
     
    1. >  
    2. <html< span=""> lang='en'>  
    3.   
    4.     <meta< span=""> charset='utf-8' />  
    5.      
    6.     <script< span=""> type='text/javascript' src='OpenLayers.js'>  
    7.     <script< span=""> type='text/javascript'>  
    8.   
    9.         var map;  
    10.   
    11.        function init() {  
    12.        //创建控制器数组  
    13.            var navigation_control = new OpenLayers.Control.Navigation({});  
    14.            var controls_array = [  
    15.                                   navigation_control,  
    16.                                   new OpenLayers.Control.PanZoomBar({}),  
    17.                                   new OpenLayers.Control.LayerSwitcher({}),  
    18.                                   new OpenLayers.Control.Permalink(),  
    19.                                   new OpenLayers.Control.MousePosition({})  
    20.                                 ];  
    21.   
    22.            map = new OpenLayers.Map('map_element', {  
    23.               controls: controls_array  
    24.             });//初始化map时加入定义的控制器  
    25.   
    26.   
    27.   
    28.            var wms_layer = new OpenLayers.Layer.WMS(  
    29.                       'WMS Layer Title',  
    30.                       'http://vmap0.tiles.osgeo.org/wms/vmap0',  
    31.                       {layers: 'basic'},  
    32.                       {}  
    33.                     );  
    34.   
    35.            map.addLayer(wms_layer);  
    36.   
    37.            map.addControl(new OpenLayers.Control.ScaleLine());//使用对象方法添加控制器  
    38.   
    39.            var overview_map = new OpenLayers.Control.OverviewMap();//创建一个预览控制器  
    40.              
    41.            map.addControls([  
    42.                   overview_map,  
    43.                   new OpenLayers.Control.KeyboardDefaults()  
    44.                 ]);  
    45.   
    46.            if(!map.getCenter()){  
    47.                map.zoomToMaxExtent();  
    48.            }  
    49.        }  
    50.   
    51.       
    52.   
    53.   
    54. <body< span=""> onload='init();'>  
    55.     <div< span=""> id='map_element' style=' 500px; height: 500px;'>  
    56.     
      
    •   
    •   
     
    可以在http://dev.openlayers.org/docs/files/OpenLayers/Control-js.html 查看所有支持的控制器。
     
    移除控制器
          使用map.removeControl()方法,有两种调用方式:
    1.调用map.removeControl(map.controls[x]),其中x代表控制器数组的索引值。
         但并不推荐这种调用方式,因为一旦使用该方法去掉控制器,其他控制器的索引就会移动使得原来的索引值发生变化
    2.调用 map.removeControl(control_object),其中control_object代表控制器对象本身
    控制器的类型
    Panel(面板)
    面板控制器是一个容器,它允许把其他控制器添加并组织在面板中。
    每个在面板中的控制器都会用一个图标来表示,当点击图标时会调用该控制器的activateControl方法,这一点很重要,因为有很多控制器不会自动转换到active状态。
    面板中的每个控制器都是以下三种类型之一:
    1.OpenLayers.Control.TYPE_BUTTON:
       这是一种按钮类型的控制器,当点击时会触发事件。例如在ZoomPanel控制器中的ZoomIn和ZoomOut按钮
    2.OpenLayers.Control.TYPE_TOGGLE:
      这种类型的控制器当点击后可用,再次点击又可关闭。这类控制器不会互相影响,你可以打开任意多个。
    3.OpenLayers.Control.TYPE_TOOL:
      这种类型的控制器与toggle类型一样,唯一的区别是这类控制器同一时间只能有一个是打开的。如ZoomBox
    面板示例:
    0
    代码:
     
    1. >  
    2. <html< span=""> lang='en'>  
    3.   
    4.     <meta< span=""> charset='utf-8' />  
    5.      
    6.     <script< span=""> type='text/javascript' src='OpenLayers.js'>  
    7.     <script< span=""> type='text/javascript'>  
    8.   
    9.         var map;  
    10.   
    11.        function init() {  
    12.            map = new OpenLayers.Map('map_element', {});  
    13.            var wms = new OpenLayers.Layer.WMS(  
    14.                'OpenLayers WMS',  
    15.                'http://vmap0.tiles.osgeo.org/wms/vmap0',  
    16.                {layers: 'basic'},  
    17.                {}  
    18.            );  
    19.   
    20.            map.addLayer(wms);  
    21.   
    22.            var navigation_control = new OpenLayers.Control.Navigation();  
    23.   
    24.            var control_panel = new OpenLayers.Control.Panel({//创建面板控制器  
    25.               div: document.getElementById('panel_div'),  
    26.               defaultControl: navigation_control  
    27.             });  
    28.   
    29.            control_panel.addControls([//向面板中添加其他控制器  
    30.               navigation_control,  
    31.               new OpenLayers.Control.ZoomBox(),  
    32.               new OpenLayers.Control.ZoomToMaxExtent()  
    33.             ])  
    34.   
    35.            map.addControl(control_panel);//将面板控制器添加到map上  
    36.   
    37.            if(!map.getCenter()){  
    38.                map.zoomToMaxExtent();  
    39.            }  
    40.        }  
    41.   
    42.       
    43.   
    44.     <style< span=""> type='text/css'>   
    45.     /*Navigation Control*/   
    46.     #panel_div .olControlNavigationItemActive {   
    47.       background: #226699 url('http://dev.openlayers.org/releases/OpenLayers-2.9.1/theme/default/img/pan_on.png');   
    48.         22px;    
    49.       height: 22px;   
    50.     }   
    51.     #panel_div .olControlNavigationItemInactive {   
    52.       background: #996622 url('http://dev.openlayers.org/releases/OpenLayers-2.9.1/theme/default/img/pan_off.png');   
    53.         22px;    
    54.       height: 22px;   
    55.     }   
    56.     /*Zoom Box Control*/   
    57.     #panel_div .olControlZoomBoxItemInactive {   
    58.         22px;    
    59.       height: 22px;   
    60.       background:#999933 url('http://dev.openlayers.org/releases/OpenLayers-2.9.1/img/drag-rectangle-off.png');   
    61.     }   
    62.     #panel_div .olControlZoomBoxItemActive {   
    63.         22px;    
    64.       height: 22px;   
    65.       background:#999966 url('http://dev.openlayers.org/releases/OpenLayers-2.9.1/img/drag-rectangle-on.png');   
    66.     }   
    67.         /*Zoom to Max Extent Control*/   
    68.     #panel_div .olControlZoomToMaxExtentItemInactive {   
    69.         18px;    
    70.       height: 18px;   
    71.       background:#333399 url('http://dev.openlayers.org/releases/OpenLayers-2.9.1/img/zoom-world-mini.png');   
    72.     }   
    73.   
    74.   
    75. <body< span=""> onload='init();'>  
    76.     <div< span=""> id='map_element' style=' 500px; height: 500px;'>  
    77.     
      
    •     <div< span=""> id='panel_div'>  
    •   
    •   
     
    自定义控制器
     
    使用控制器的子类OpenLayers.Control.Button创建一个自定义的按钮控制器
    步骤如下:
    1.设置该按钮控制器的displayClass属性以设定一种样式
    2.创建一个函数作为按钮触发器
    3.把按钮添加到面板并把面板添加到map中
    示例--创建一个简单的自定义按钮控制器
    0
    代码:
     
    1. >  
    2. <html< span=""> lang='en'>  
    3.   
    4.     <meta< span=""> charset='utf-8' />  
    5.      
    6.     <script< span=""> type='text/javascript' src='OpenLayers.js'>  
    7.     <script< span=""> type='text/javascript'>  
    8.   
    9.         var map;  
    10.   
    11.        function init() {  
    12.            map = new OpenLayers.Map('map_element', {});  
    13.            var wms = new OpenLayers.Layer.WMS(  
    14.                'OpenLayers WMS',  
    15.                'http://vmap0.tiles.osgeo.org/wms/vmap0',  
    16.                {layers: 'basic'},  
    17.                {}  
    18.            );  
    19.   
    20.            map.addLayer(wms);  
    21.   
    22.            var custom_button_func = function(){   
    23.               //Get a random coordinate from -90 to 90  
    24.                var random_lon = Math.floor(Math.random() * 360) - 180;  
    25.                var random_lat = Math.floor(Math.random() * 180) - 90;  
    26.                if(map.layers[0].opacity === 1){   
    27.                     //If the layer opacity is 1 (fully opaque), then change it and zoom  
    28.                     map.layers[0].setOpacity(.5);   
    29.                     map.setCenter(new OpenLayers.LonLat(random_lon,random_lat), 3);   
    30.                }   
    31.                else{   
    32.                     //If the layer opacity is anything but 1, change it and zoom   
    33.                     map.layers[0].setOpacity(1);   
    34.                     map.setCenter(new OpenLayers.LonLat(random_lon,random_lat), 3);   
    35.                }   
    36.         };   
    37.             
    38.            var my_button = new OpenLayers.Control.Button({  
    39.                   displayClass: 'olControlCustomButton', //添加样式  
    40.                   trigger: custom_button_func//添加触发器  
    41.                 });  
    42.           
    43.            var control_panel = new OpenLayers.Control.Panel({});//直接在map上创建面板  
    44.   
    45.            control_panel.addControls([my_button]);  
    46.   
    47.            map.addControl(control_panel);  
    48.   
    49.            control_panel.moveTo(new OpenLayers.Pixel(450,0));//移动面板到指定位置,也可用CSS调整  
    50.   
    51.            if(!map.getCenter()){  
    52.                map.zoomToMaxExtent();  
    53.            }  
    54.        }  
    55.   
    56.       
    57.   
    58.     <style< span=""> type='text/css'>   
    59.         /*Custom Button*/   
    60.         .olControlCustomButtonItemInactive {   
    61.             background:#22dd22;   
    62.             border:5px solid #202020;   
    63.             cursor: pointer;   
    64.             height: 28px;   
    65.               28px;    
    66.         }   
    67.        
    68.   
    69.   
    70. <body< span=""> onload='init();'>  
    71.     <div< span=""> id='map_element' style=' 500px; height: 500px;'>  
    72.     
      
    •   
    •   
     
     
     
     
  • 相关阅读:
    (转)ios限制控制器旋转
    iOS NSMutableURLRequest 上传图片
    iOS中UIWebView使用JS交互
    Cocoa pods的安装和使用
    NSThread/NSOperation/GCD 三种多线程技术
    动画效果-基础动画设置(改变大小,改变透明度,翻转,旋转,复原)
    动画效果一风火轮加载效果/动态图展示
    Swift代理和传值
    Swift基础(类,结构体,函数)
    IOS面试问题总结
  • 原文地址:https://www.cnblogs.com/devgis/p/16542825.html
Copyright © 2020-2023  润新知