WebGis之OpenLayers学习之路------OpenLayers多源数据展示

数据加载原理

GIS地图加载的一般原理

在web端加载切片地图和矢量地图的原理基本相同

(1)瓦片地图。在web端加载瓦片地图一般有两种方式。一种为直接读取缓存加载,也就是说直接读取硬盘中存储的瓦片图片,另一种为调用瓦片地图接口,例如Arcgis Server、GeoServer等.。

加载原理:通过Ajax请求瓦片地图服务或数据,根据瓦片地图的级数、行列号分别获取对应的瓦片地图,将其按照请求的控件范围组织好,从而形成一张地图进行展示

(2)矢量地图。在web端加载矢量地图,一般也有两种,一种为直接读取矢量地图文件,即存储在硬盘中的GML、KML等格式的矢量地图文件。另一种方式为调用矢量地图服务接口,通过接口加载矢量地图

加载原理:通过Ajax请求矢量地图服务或数据,根据请求到的矢量地图,在Web端实时生成矢量地图并显示在网页中。

基础地图数据

在这里我们是基于ArcGis数据为例进行演示,针对ArcGis的数据,openLayers封装了一个ArcGis瓦片数据源可以直接使用,同时,可以基于OpenLayers现有通用的图层与数据源,加载其瓦片地图或者矢量地图

下面是基于ArcGis Server REST的瓦片地图服务接口

    window.onload = function () {
        var mousePositionControl = new ol.control.MousePosition({
            //坐标格式
            coordinateFormat:ol.coordinate.createStringXY(4),
            //地图投影坐标
            projection:'EPSG:4326',
            //坐标信息显示样式
            className:'custom-mouse-position',
            //显示鼠标位置信息的目标地图容器
            target:document.getElementById('mouse-position'),
            //未定义坐标的标记
            undefinedHTML:'&nbsp'
        });

        //实例化ArcGis Server
        var arcGISSource = new ol.source.TileArcGISRest({
            url: 'http://localhost:6080/arcgis/rest/services/Map/MapServer',//输入自己的服务地址
        });

        var arcGISLayers = new ol.layer.Tile({
            source: arcGISSource
            //extend:[-13884991,2870341,-7455066,6338219]
        });

        //实例化Map对象并加载地图
        var map = new ol.Map({
            //容器div层的ID
            target: 'map',
            //地图容器中加载的图层
            layers: [],
            //地图图视的设置
            view: new ol.View({
                //地图中心点
                center: [117.4250, 39.0890],
                zoom: 15,
                projection: 'EPSG:4326'
            }),
            //加载控件到地图容器中
            controls: ol.control.defaults({}).extend([mousePositionControl])
        });
        map.addLayer(arcGISLayers);
    }

通过调用接口呈现的样子如下图

上面是调用的ArcGis的瓦片地图服务接口,openlayers不仅可以调用切片服务,还可以对ArcGis Serve Rest的矢量地图服务接口和ArcGis Online的瓦片地图服务接口,在这就不演示了,百度一大片

其它地图数据

初次之外,我们还可以使用一些开放数据。包括KML、GML、GPX、GeoJSON等,具体是什么我们可以包都得知,其实我们平常用到最多的就是公共地图数据,包括Bing地图、OpenStreetMap、百度地图、高德地图、谷歌地图等。

下面总结下加载这些地图source

OpenStreetMap

source:new ol.source.OSM()

Bing地图

var key="申请密钥"l
var roads = new ol.layer.Tile({
    source:new ol.source.BingMaps({key:key,imagerySet:'Road'})
})

百度地图

var baidu_source = new ol.source.TileImage({
        projection: projection,
        tileGrid: tilegrid,
        tileUrlFunction: function(tileCoord, pixelRatio, proj){
            if(!tileCoord){
                return "";
            }
            var z = tileCoord[0];
            var x = tileCoord[1];
            var y = tileCoord[2];

            if(x<0){
                x = "M"+(-x);
            }
            if(y<0){
                y = "M"+(-y);
            }

            return "http://online3.map.bdimg.com/onlinelabel/?qt=tile&x="+x+"&y="+y+"&z="+z+"&styles=pl&udt=20151021&scaler=1&p=1";
        }
    });

高德地图

source: new ol.source.XYZ({
                    url: 'http://wprd0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&style=7&x={x}&y={y}&z={z}'
                })

谷歌地图

 source: new ol.source.XYZ({  
                    url:'http://www.google.cn/maps/vt?lyrs=t@189&gl=cn&x={x}&y={y}&z={z}'
//                  url: 'http://www.google.cn/maps/vt/pb=!1m4!1m3!1i{z}!2i{x}!3i{y}!2m3!1e0!2sm!3i380072576!3m8!2szh-CN!3scn!5e1105!12m4!1e68!2m2!1sset!2sRoadmap!4e0!5m1!1e0'
//                  url:'http://mt0.google.cn/maps/vt?lyrs=s@773&gl=cn&x={x}&y={y}&z={z}'
//                    url:'http://www.google.cn/maps/vt?lyrs=m@189&gl=cn&x={x}&y={y}&z={z}'
//                    url:'http://www.google.cn/maps/vt?lyrs=s@189&gl=cn&x={x}&y={y}&z={z}'
//                    url:'http://www.google.cn/maps/vt?lyrs=h@189&gl=cn&x={x}&y={y}&z={z}'

                })

天地图

 new ol.layer.Tile({
                  source: new ol.source.XYZ({
                    url: 'https://t0.tianditu.gov.cn/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=天地图密钥',
                  }),
                  isGroup: true,
                  name: '天地图路网'
                }),
                new ol.layer.Tile({
                  source: new ol.source.XYZ({
                    url: 'https://t0.tianditu.gov.cn/DataServer?T=cia_w&x={x}&y={y}&l={z}&tk=天地图密钥'
                  }),

图形绘制

图形交互绘制原理

图形表现的内容十分丰富,有基本的几何图形,即点、线、圆、矩形、多边形等;也有方向图形,即各种各样的方向箭头;还有标识某一内容的图形,如指北针、小旗子等。

交互式图形绘制的原理:先初始化一个矢量地图对象并添加到地图容器,然后加载交互式图形绘制控件,最后通过交互式图形控件在地图上绘制相应的几何图形,也可以通过交互式编辑控件来修改已经绘制好的几何图形。其中,在绘制几何图形时,可以根据需求设置不同的图形样式。在openLayers中,矢量地图为ol.layer.Vector,交互式图形绘制控件为ol.interaction.Draw,交互式编辑控件为ol.interaction.Modify,另外,在进行在编辑时,通常需要先选择某个目标,openLayers提供的选择要素控件为ol.interaction.Select。

图形绘制

除了点、线、圆、多边形直接可以设置类型,其它(正方形、长方形)需要自行编写,在设置绘图类型,代码如下:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <link rel="stylesheet" href="../css/ol.css" type="text/css">
    <script type="text/javascript" src="../javascript/ol.js"></script>
    <script type="text/javascript" src="../javascript/jquery-3.4.1.min.js"></script>
    <style type="text/css">
        #map {
            width: 100%;
            height: 90%;
            position: absolute;
        }
    </style>
</head>
<body>
<div id="menu">
    <label>几何图形类型:&nbsp;</label>
    <select id="type">
        <option value="None">无</option>
        <option value="Point">点</option>
        <option value="LineString">线</option>
        <option value="Polygon">多边形</option>
        <option value="Circle">圆</option>
        <option value="Square">正方形</option>
        <option value="Box">长方形</option>
    </select>
</div>
<div id="map"></div>

<script>
    var map = new ol.Map({
        target: 'map',
        layers: [
            new ol.layer.Tile({
                source: new ol.source.OSM()
            })
        ],
        view: new ol.View({
            center: [0, 0],
            zoom: 3
        })
    });

    var typeSelect = document.getElementById('type');       //绘制类型选择对象
    var draw;                          //ol.Interaction.Draw类的对象

    //实例化一个矢量图层Vector作为绘制层
    var source = new ol.source.Vector();
    var vectorLayer = new ol.layer.Vector({
        source: source,
        style: new ol.style.Style({
            fill: new ol.style.Fill({               //填充样式
                color: 'rgba(255, 255, 255, 0.2'
            }),
            stroke: new ol.style.Stroke({           //线样式
                color: '#ffcc33',
                width: 2
            }),
            image: new ol.style.Circle({            //点样式
                radius: 7,
                fill: new ol.style.Fill({
                    color: '#ffcc33'
                })
            })
        })
    });
    //将绘制层添加到地图容器中
    map.addLayer(vectorLayer);

    //用户更改绘制类型触发的事件
    typeSelect.onchange = function(e){
        map.removeInteraction(draw);        //移除绘制图形控件
        addInteraction();                   //添加绘制图形控件
    };

    function addInteraction(){
        var typeValue = typeSelect.value;       //绘制类型
        if(typeValue !== 'None'){
            var geometryFunction, maxPoints;
            if(typeValue === 'Square'){                 //正方形
                typeValue = 'Circle';               //设置绘制类型为Circle
                //设置几何信息变更函数,即创建正方形
                geometryFunction = ol.interaction.Draw.createRegularPolygon(4);
            }else if(typeValue === 'Box'){              //长方形
                typeValue = 'LineString';           //设置绘制类型为LineString
                maxPoints = 2;                      //设置最大点数为2
                //设置几何信息变更函数,即设置长方形的坐标点
                geometryFunction = function(coordinates, geometry){
                    if(!geometry){
                        geometry = new ol.geom.Polygon(null);       //多边形
                    }
                    var start = coordinates[0];
                    var end = coordinates[1];
                    geometry.setCoordinates([
                        [
                            start,
                            [start[0], end[1]],
                            end,
                            [end[0], start[1]],
                            start
                        ]
                    ]);
                    return geometry;
                };
            }
            console.log(typeValue);
            //实例化图形绘制控件对象并添加到地图容器中
            draw = new ol.interaction.Draw({
                source: source,
                type: typeValue,                                //几何图形类型
                geometryFunction: geometryFunction,             //几何信息变更时的回调函数
                maxPoints: maxPoints                            //最大点数
            });
            map.addInteraction(draw);
        }else{
            //清空绘制的图形
            source = null;
            vector.setSource(source);
        }
    }
</script>
</body>
</html>

图形交互编辑

提到交互编辑不就要先对几何图形要素进行绘制,如何添加编辑几何图形要素呢,如下所示

        //绘制的几何图形要素
        var pointFeature = new ol.Feature(new ol.geom.Point([117.192, 39.878]));
        var lineFeature = new ol.Feature(new ol.geom.LineString([[117.192, 39.878], [117.142, 39.858]]));
        var polygonFeature = new ol.Feature(
            new ol.geom.Polygon([[[117.172, 39.878], [117.132, 39.878], [117.152, 39.888], [117.182, 39.838], [117.192, 39.858]]])
        );
        //实例化一个矢量图层Vector作为绘制层
        var source = new ol.source.Vector({
            features: [pointFeature, lineFeature, polygonFeature]
        });
        var vector = new ol.layer.Vector({
            source: source,
            style: new ol.style.Style({
                fill: new ol.style.Fill({
                    color: "rgba(255, 255, 255, 0.2)"
                }),
                stroke: new ol.style.Stroke({
                    color: "#ffcc33",
                    width: 2
                }),
                image: new ol.style.Circle({
                    radius: 7,
                    fill: new ol.style.Fill({
                        color: "#ffcc33"
                    })
                })
            })
        });
        map.addLayer(vector);                   //将绘制层添加到地图容器中

在地图中容器中创建一个交互式编辑控件需要使用ol.interaction.Modify来实现几何编辑功能。在此,综合选择要素控件(ol.interaction.Select)实现,选中要素后进行编辑功能操作

        //定义修改几何图形的功能控件
        var Modify = {
            init: function(){
                //初始化一个交互选择控件,并添加到地图容器中
                this.select = new ol.interaction.Select();
                map.addInteraction(this.select);
                //初始化一个交互编辑控件,并添加到地图容器中
                this.modify = new ol.interaction.Modify({
                    features: this.select.getFeatures()           //选中的要素集
                });
                map.addInteraction(this.modify);
                //设置激活状态变更的处理
                this.setEvents();
            },
            setEvents: function(){
                var selectedFeatures = this.select.getFeatures();       //选中的要素集
                //添加选中要素变更事件
                this.select.on("change:active", function(){
                    //遍历选择要素集,返回当前第一个要素(即移除的要素)
                    selectedFeatures.forEach(selectedFeatures.remove, selectedFeatures);
                });
            },
            setActive: function(active){
                this.select.setActive(active);                  //激活选择要素控件
                this.modify.setActive(active);                  //激活修改要素控件
            }
        };
        Modify.init();                          //初始化几何图形修改控件
        Modify.setActive(true);                 //激活几何图形修改控件

说明:为实现选中要素后编辑几何图形的功能,封装了一个Modify控件,分别实现初始化init方法,设置事件的setEvents方法、设置是否激活控件的setActive方法。在调用时先调用Modify的init方法进行初始化,然后调用setActive方法激活控件。

    1 init:在初始化时首先加载交互选择要素的控件(ol.interaction.Select),然后加载一个交互编辑控件(ol.interaction.Modify),在实例化交互编辑控件时设置修改的features为当前选中的要素,最后调用setEvents方法进行选择控件激活状态变更的处理。

    2 setEvents:在此方法中为当前选择控件添加激活变更事件,在其事件处理函数中返回当前选择要素集的第一个要素。

    3 setActive: 在此方法中分别调用选择控件和编辑控件的setActive方法,对这两个控件的是否激活状态进行控制。

以上内容参考WebGIS之openLayers全面解析书籍

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值