• Openlayers 使用天地图Web服务


    OpenLayers 教程

    天地图作为广大 GISer 使用频繁的服务之一,除了应用众多的底图服务(影像、地形、矢量),还有很多 Web 服务接口。

    比如:地名搜索、地理编码查询、地理逆编码查询、行政区划、路径公交规划等,可以根据项目的实际需求调用接口。

    本文介绍在前端使用 ajax 发起请求,获取天地图服务数据,并且在地图渲染。

    包括: 地名搜索(获取列表)、地理编码查询(地名查询坐标)、地理逆编码查询(坐标查询地名)、行政区别、路径规划(导航)

    PS:其他服务也类型,前端发起请求,获取数据,通过 Openlayers 渲染即可!

    放上官网地址: 天地图 Wep API

    在这里插入图片描述

    Openlayers 使用天地图Web服务

    <html lang="en">
    <head>
        <meta charSet="utf-8">
        
        <link rel="stylesheet" href="http://openlayers.vip/examples/css/ol.css" type="text/css">
        <style>
            /* 注意:这里必须给高度,否则地图初始化之后不显示;一般是计算得到高度,然后才初始化地图 */
            .map {
                height: 400px;
                width: 100%;
                float: left;
            }
        style>
        
        <script src="http://openlayers.vip/examples/resources/ol.js">script>
        <script src="http://openlayers.vip/examples/resources/jquery-3.5.1.min.js">script>
        <script src="http://openlayers.vip/examples/resources/layer.js">script>
    
        <script src="./tiandituLayers.js">script>
        <title>OpenLayers exampletitle>
    
    head>
    <body>
    <h2>OpenLayers tianditu webh2>
    
    <div id="map" class="map">div>
    
    <script type="text/javascript">
        var map = new ol.Map({
            // 地图容器
            target: 'map',
            // 地图图层,比如底图、矢量图等
            layers: [
                getIMG_CLayer(),
                getIBO_CLayer(),
                getCIA_CLayer(),
            ],
            // 地图视野
            view: new ol.View({
                projection: "EPSG:4326",
                // 定位
                center: [115.67724700667199, 37.73879478106912],
                // 缩放
                zoom: 6,
                maxZoom: 18,
                minZoom: 1,
                // 注意,天地图地图等级 level 参数,需要设置为整数,否则会出错
                //1.设置缩放级别为整数
                constrainResolution: true,
                //2.关闭无级缩放地图
                smoothResolutionConstraint: false,
            })
        });
    
        // 初始化图层
        var layerVector = initVectorLayer();
    
        /**
         * @todo 矢量图层
         * @returns {VectorLayer}
         * @constructor
         */
        function initVectorLayer() {
            //实例化一个矢量图层Vector作为绘制层
            let source = new ol.source.Vector();
            //创建一个图层
            let customVectorLayer = new ol.layer.Vector({
                source: source,
                zIndex: 2,
            });
            //将绘制层添加到地图容器中
            map.addLayer(customVectorLayer);
    
            return customVectorLayer;
        }
    
        /**
         * @todo wkt格式数据转化成图形对象
         * @param {string} wkt   "POINT(112.7197265625,39.18164062499999)" 格式数据
         * @param {string|Projection} sourceCode 源投影坐标系
         * @param {string|Projection} targetCode 目标投影坐标系
         * @returns {Feature}
         */
        function getFeatureByWKT(wkt, sourceCode, targetCode) {
            try {
                let view = map.getView();
                if (!wkt) {
                    return null;
                }
                let format = new ol.format.WKT();
    
                let feature;
    
                feature = format.readFeature(wkt, {
                    featureProjection: targetCode || view.getProjection(),
                    dataProjection: sourceCode || view.getProjection(),
                });
    
                return feature;
            } catch (e) {
                console.log(e);
                return null;
            }
        }
    
        /**
         * 获取样式
         * @param name
         * @returns {ol.style.Style}
         */
        function getStyle(name) {
            // 圆点样式
            return new ol.style.Style({
                image: new ol.style.Icon({
                    // 允许跨域,如果不设置,打印地图不会打印
                    crossOrigin: 'anonymous',
                    // 标注图片和文字之间的距离
                    anchor: [0.5, 0],
                    // 图片的偏移
                    offset: [0.2, 0],
                    // 图片的锚点,一般来说,都是右下角
                    anchorOrigin: 'bottom-right',
                    //图标的url
                    src: "http://api.tianditu.gov.cn/v4.0/image/marker-icon.png",
                    //图标比例, 0.5 大概是25*34
                    scale: 1,
                }),
                text: new ol.style.Text({
                    text: name,
                    // 偏移
                    offsetX: 0,
                    offsetY: -60,
                    // 文字居中
                    textAlign: 'center',
                    // 字体
                    font: 'normal bold  18px  Arial,sans-serif',
                    // 比例
                    scale: 1,
                    // 边距
                    padding: [5, 5, 5, 5],
                    // 字体颜色
                    fill: new ol.style.Fill({
                        color: 'rgba(51,51,51, 1)'
                    }),
                    // 字体边框,可以配合 fill 是文字高亮
                    stroke: new ol.style.Stroke({
                        color: 'rgba(0, 255, 255, 0.8)',
                        width: 2,
                    }),
                    // 背景色
                    backgroundFill: new ol.style.Fill({
                        color: 'rgba(252,254,255, 1)'
                    }),
                    // 背景边框
                    backgroundStroke: new ol.style.Stroke({
                        color: 'rgba(0, 255, 255, 0.8)',
                        width: 1,
                    }),
                })
            });
        }
    
        /**
         * 定位
         * @param layerTemp
         */
        function moveTo(layerTemp) {
            //定位范围
            map.getView().fit(layerTemp.getSource().getExtent(), {
                duration: 500,//动画的持续时间,
                callback: function () {
                },
            });
        }
    
        // 添加多个点,地名获取列表,将点叠加在地图上
        let addMarkerList = function (poi) {
            let arr = [];
            if (poi && poi.length > 0) {
                for (let i = 0; i < poi.length; i++) {
    
                    const poiElement = poi[i];
    
                    let xy = poiElement.lonlat.split(',');
    
                    let feature = getFeatureByWKT('POINT(' + xy[0] + ' ' + xy[1] + ')');
    
                    feature.setStyle(getStyle(poiElement.name));
    
                    arr.push(feature)
                }
            }
    
            layerVector.getSource().addFeatures(arr);
    
            moveTo(layerVector);
        }
    
        // 添加点
        let addMarker = function (result) {
    
            let x = result.location.lon;
            let y = result.location.lat;
    
            let feature = getFeatureByWKT('POINT(' + x + ' ' + y + ')');
    
            // 如果有面图形要素,则加载;主要是行政区划的边界。
            let featurePolygon = result.location.polygon && getFeatureByWKT(result.location.polygon);
    
            feature.setStyle(getStyle(result.formatted_address || result.location.keyWord))
    
            layerVector.getSource().addFeatures([feature]);
    
            featurePolygon && layerVector.getSource().addFeatures([featurePolygon]);
    
            moveTo(layerVector);
        }
    
        //显示导航位置
        let addLine = function (responseData) {
    
    		// 导航数据为 xml 格式
            let temp = $(responseData).find('routelatlon').text();
    
    		// 拼接 wkt 格式
            while (temp.indexOf(',') != -1) {
                temp = temp.replace(',', ' ');
            }
            while (temp.indexOf(';') != -1) {
                temp = temp.replace(';', ',');
            }
    
            temp = temp.substring(0, temp.length - 1);
    
            temp = 'LINESTRING(' + temp + ')';
    
            let feature = getFeatureByWKT(temp);
    
            //渐变色线
            let styleLine = [];
            let steps = 10;
            // 渐变色原理,其实就是多个样式共同使用
            for (let i = 0; i < steps; i++) {
                styleLine.push(
                    new ol.style.Style({
                        stroke: new ol.style.Stroke({
                            color: [0, 255, 255, 1 / (steps - i)],
                            width: (steps - i) * 2 - 1
                        }),
                    })
                );
            }
    
            feature.setStyle(styleLine);
            layerVector.getSource().addFeatures([feature]);
    
            moveTo(layerVector);
        }
    
        // 关键字查询列表,根据关键字获取列表数据
        function searchKeyword() {
    
            // 清除上一次叠加对象
            layerVector && layerVector.getSource().clear();
    
            $.ajax({
                url: 'http://api.tianditu.gov.cn/v2/search',
                type: 'get',
                contentType: "application/json;charset=UTF-8", //指定消息请求类型
                data: {
                    // 注意参数格式
                    postStr: JSON.stringify({
                        // 关键字
                        "keyWord": $('#searchKeywordQuery').val(),
                        // 地图等级,需要设置整数
                        "level": map.getView().getZoom(),
                        // 地图范围
                        "mapBound": map.getView().calculateExtent(map.getSize()).toString(),
                        // 查询类型
                        "queryType": '1',
                        // 分页
                        "start": '0',
                        "count": '10',
                    }),
                    type: 'query',
                    // 请更换自己的 tk,此 tk 只能在当前域名下使用
                    tk: '2b7cbf61123cbe4e9ec6267a87e7442f',
                },
                beforeSend: function () {
                    layer.load(2, {
                        shade: [0.5, '#fff'] //0.1透明度的白色背景
                    })
                },
                success: function (res, status) {
    
                    layer.closeAll();
    
                    res.pois && addMarkerList(res.pois);
                },
            });
        }
    
        // 地理编码查询,根据关键字查询坐标
        function searchName() {
    
            // 清除上一次叠加对象
            layerVector && layerVector.getSource().clear();
    
            $.ajax({
                url: 'http://api.tianditu.gov.cn/geocoder',
                type: 'get',
                contentType: "application/json;charset=UTF-8", //指定消息请求类型
                data: {
                    // 注意参数格式
                    ds: JSON.stringify({
                        // 关键字
                        "keyWord": $('#searchNameQuery').val(),
                    }),
                    type: 'query',
                    // 请更换自己的 tk,此 tk 只能在当前域名下使用
                    tk: '2b7cbf61123cbe4e9ec6267a87e7442f',
                },
                beforeSend: function () {
                    layer.load(2, {
                        shade: [0.5, '#fff'] //0.1透明度的白色背景
                    })
                },
                success: function (res, status) {
    
                    layer.closeAll();
    
                    res = JSON.parse(res);
    
                    res.location && addMarker(res);
                },
            });
        }
    
        // 地理逆编码查询,根据坐标查询名称
        function searchCoordinate() {
    
            // 清除上一次叠加对象
            layerVector && layerVector.getSource().clear();
    
            let coordinates = $('#searchCoordinateQuery').val().split(',');
    
            $.ajax({
                url: 'http://api.tianditu.gov.cn/geocoder',
                type: 'get',
                contentType: "application/json;charset=UTF-8", //指定消息请求类型
                data: {
                    // 注意参数格式
                    postStr: JSON.stringify({
                        // 坐标
                        "lon": coordinates[0],
                        "lat": coordinates[1],
                        "ver": 1
                    }),
                    type: 'geocode',
                    // 请更换自己的 tk,此 tk 只能在当前域名下使用
                    tk: '2b7cbf61123cbe4e9ec6267a87e7442f',
                },
                beforeSend: function () {
                    layer.load(2, {
                        shade: [0.5, '#fff'] //0.1透明度的白色背景
                    })
                },
                success: function (res, status) {
    
                    layer.closeAll();
    
                    res = JSON.parse(res);
    
                    res.result && addMarker(res.result);
                },
            });
        }
    
        // 行政区别,根据关键字查询行政区划信息;包括名称、类型(省市)、范围等
        function searchGovernment() {
    
            // 清除上一次叠加对象
            layerVector && layerVector.getSource().clear();
    
            $.ajax({
                url: 'http://api.tianditu.gov.cn/administrative',
                type: 'get',
                async: false,
                contentType: "application/json;charset=UTF-8", //指定消息请求类型
                data: {
                    // 注意参数格式
                    postStr: JSON.stringify({
                        // 关键字
                        "searchWord": $('#searchGovernmentQuery').val(),
                        "searchType": '1',
                        // 子项
                        "needSubInfo": 'false',
                        // 所有属性
                        "needAll": 'false',
                        // 边界属性,好像是不起作用
                        "needPolygon": 'true',
                        "needPre": '10',
                    }),
                    type: 'query',
                    // 请更换自己的 tk,此 tk 只能在当前域名下使用
                    tk: '2b7cbf61123cbe4e9ec6267a87e7442f',
                },
                beforeSend: function () {
                    layer.load(2, {
                        shade: [0.5, '#fff'] //0.1透明度的白色背景
                    })
                },
                success: function (res, status) {
    
                    layer.closeAll();
    
                    if (res && res.data && res.data.length > 0) {
    
    					// 拼接通用方法参数
                        let location = {};
    
    					// 坐标
                        location.lon = res.data[0].lnt;
                        location.lat = res.data[0].lat;
                        
    					// 名称
                        location.keyWord = res.data[0].name;
                        
    					// 四至范围
                        location.bound = res.data[0].bound.split(',');
                        
    					// 类型(省市县)
                        location.adminType = res.data[0].adminType;
    
    					// 拼接矩形(面状图形要素)
                        let polygon = 'POLYGON((' + location.bound[0] + ' ' + location.bound[1] + '' +
                            ',' + location.bound[2] + ' ' + location.bound[1] + ',' +
                            '' + location.bound[2] + ' ' + location.bound[3] + ',' +
                            '' + location.bound[0] + ' ' + location.bound[3] + ',' +
                            '' + location.bound[0] + ' ' + location.bound[1] + '))';
    
                        location.polygon = polygon;
    
                        res.data[0].location = location;
    
                        addMarker(res.data[0]);
                    }
                },
            });
        }
    
        // 路径规划,根据出发地和目的地获取导航路径
        function searchRoute() {
    
            // 清除上一次叠加对象
            layerVector && layerVector.getSource().clear();
    
            $.ajax({
                url: 'http://api.tianditu.gov.cn/drive',
                type: 'get',
                contentType: "application/json;charset=UTF-8", //指定消息请求类型
                data: {
                    // 注意参数格式
                    postStr: JSON.stringify({
                        // 出发地
                        "orig": $('#searchRouteQuery1').val(),
                        // 目的地
                        "dest": $('#searchRouteQuery2').val(),
                        "style": '0',
                        "ver": 1
                    }),
                    type: 'search',
                    // 请更换自己的 tk,此 tk 只能在当前域名下使用
                    tk: '2b7cbf61123cbe4e9ec6267a87e7442f',
                },
                beforeSend: function () {
                    layer.load(2, {
                        shade: [0.5, '#fff'] //0.1透明度的白色背景
                    })
                },
                success: function (res, status) {
    
                    layer.closeAll();
                    
                    res && addLine(res);
                },
            });
        }
    
    script>
    <br/>
    <br/>
    <input type="text" id="searchKeywordQuery" value="西什库大街" placeholder="请输入地名查询..."/>
    <button id="searchKeyword" onClick="searchKeyword()">关键字查询列表button>
    <br/>
    <br/>
    <input type="text" id="searchNameQuery" value="西什库大街31号院23" placeholder="请输入地名查询..."/>
    <button id="searchName" onClick="searchName()">地理编码查询button>
    <br/>
    <br/>
    <input type="text" id="searchCoordinateQuery" value="116.37304,39.92594" placeholder="请输入 x y 查询..."/>
    <button id="searchCoordinate" onClick="searchCoordinate()">地理逆编码查询button>
    <br/>
    <br/>
    <input type="text" id="searchGovernmentQuery" value="北京市" placeholder="请输入城市名称..."/>
    <button id="searchGovernment" onClick="searchGovernment()">行政区别button>
    <br/>
    <br/>
    <input type="text" id="searchRouteQuery1" value="116.38301126947785,39.91934326306291" placeholder="请输入出发地..."/>
    <input type="text" id="searchRouteQuery2" value="116.2813877343216,39.99109771862933" placeholder="请输入目的地..."/>
    <button id="searchRoute" onClick="searchRoute()">路径规划button>
    body>
    html>
    
    
    • 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
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281
    • 282
    • 283
    • 284
    • 285
    • 286
    • 287
    • 288
    • 289
    • 290
    • 291
    • 292
    • 293
    • 294
    • 295
    • 296
    • 297
    • 298
    • 299
    • 300
    • 301
    • 302
    • 303
    • 304
    • 305
    • 306
    • 307
    • 308
    • 309
    • 310
    • 311
    • 312
    • 313
    • 314
    • 315
    • 316
    • 317
    • 318
    • 319
    • 320
    • 321
    • 322
    • 323
    • 324
    • 325
    • 326
    • 327
    • 328
    • 329
    • 330
    • 331
    • 332
    • 333
    • 334
    • 335
    • 336
    • 337
    • 338
    • 339
    • 340
    • 341
    • 342
    • 343
    • 344
    • 345
    • 346
    • 347
    • 348
    • 349
    • 350
    • 351
    • 352
    • 353
    • 354
    • 355
    • 356
    • 357
    • 358
    • 359
    • 360
    • 361
    • 362
    • 363
    • 364
    • 365
    • 366
    • 367
    • 368
    • 369
    • 370
    • 371
    • 372
    • 373
    • 374
    • 375
    • 376
    • 377
    • 378
    • 379
    • 380
    • 381
    • 382
    • 383
    • 384
    • 385
    • 386
    • 387
    • 388
    • 389
    • 390
    • 391
    • 392
    • 393
    • 394
    • 395
    • 396
    • 397
    • 398
    • 399
    • 400
    • 401
    • 402
    • 403
    • 404
    • 405
    • 406
    • 407
    • 408
    • 409
    • 410
    • 411
    • 412
    • 413
    • 414
    • 415
    • 416
    • 417
    • 418
    • 419
    • 420
    • 421
    • 422
    • 423
    • 424
    • 425
    • 426
    • 427
    • 428
    • 429
    • 430
    • 431
    • 432
    • 433
    • 434
    • 435
    • 436
    • 437
    • 438
    • 439
    • 440
    • 441
    • 442
    • 443
    • 444
    • 445
    • 446
    • 447
    • 448
    • 449
    • 450
    • 451
    • 452
    • 453
    • 454
    • 455
    • 456
    • 457
    • 458
    • 459
    • 460
    • 461
    • 462
    • 463
    • 464
    • 465
    • 466
    • 467
    • 468
    • 469
    • 470
    • 471
    • 472
    • 473
    • 474
    • 475
    • 476
    • 477
    • 478
    • 479
    • 480
    • 481
    • 482
    • 483
    • 484
    • 485
    • 486
    • 487
    • 488
    • 489
    • 490
    • 491
    • 492
    • 493
    • 494
    • 495
    • 496
    • 497
    • 498
    • 499
    • 500
    • 501
    • 502
    • 503
    • 504
    • 505
    • 506
    • 507
    • 508
    • 509
    • 510
    • 511
    • 512
    • 513
    • 514

    在线示例

    Openlayers 天地图Web服务:Openlayers-tianditu-web

  • 相关阅读:
    Grafana 高可用部署最佳实践
    SpringBoot SpringBoot 开发实用篇 5 整合第三方技术 5.11 jetcache 方法缓存
    前端无需install快速调试npm包,Console-Import使用
    【排序专题】不会吧,不会吧居然还有人不懂排序算法?有彩蛋哦
    中高价位搭载率超过60%!NOA几乎标配!APA赛道持续升温
    【笔试题】【day29】
    Numpy(二) 元素与数组的操作
    【LeetCode-75】 颜色分类
    数据驱动 vs 关键字驱动:对搭建UI自动化测试框架的探索
    寄存器、CPU缓存、内存。以及他们之间的关系
  • 原文地址:https://blog.csdn.net/linzi19900517/article/details/125465478