A005:Openlayers加载天地图、百度、高德、ArcGIS、Bing、OSM、Google地图 (结合Vue 详细教程)


前言

要在 Vue.js 项目中使用 OpenLayers 加载多种地图服务(包括天地图、百度、高德、ArcGIS、Bing、OSM 和 Google 地图),你需要按照以下步骤进行操作:

1.安装必要的依赖:

安装 ol(OpenLayers)库。

2.创建 Vue 组件:

创建一个新的 Vue 组件,并在其中初始化 OpenLayers 地图实例。

3.添加地图服务:

根据每种地图服务的特性,设置相应的图层和源。

下面是一个详细的示例,它展示了如何在一个 Vue.js 组件中集成 OpenLayers 并加载各种地图服务。


提示:"如果对操作流程还不熟悉的话,可以参考之前的文章 A001 至 A004,这些内容会帮助你更好地了解 OpenLayers 的功能点。我们会持续更新相关内容,如果你感兴趣或有这方面的需求,欢迎关注并收藏。"

一、常见的地图数据源类型及其使用方法

1. XYZ (ol/source/XYZ)

XYZ 数据源是一种基于经纬度划分的 Web 地图瓦片服务。这是一种广泛使用的地图数据源类型,在许多免费或商业地图服务上都可以找到。例如:Stamen Maps,ArcGIS 地图服务。

2. OSM (ol/source/OSM)

OpenStreetMap(OSM)数据源是基于开源的全球地图数据。这种类型的底图广泛应用于个人项目、企业级应用等场合,因为它可以提供充足的地理信息数据和免费无限制的访问权限。

3. WMS (ol/source/TileWMS)

Web 地图服务(WMS)是 OGC(Open Geospatial Consortium)定义的基于网络的地图服务规范。WMS 数据源通常用于访问矢量数据、栅格数据等地图图层。例如:地理空间数据存储在 Geoserver 上时,可以通过 WMS 来访问。

二、如何在地图中使用以上三种数据源

1. XYZ 数据源(Stamen Maps 服务)

import TileLayer from "ol/layer/Tile";
import XYZ from "ol/source/XYZ";
 
// 创建 Stamen Maps 图层
const stamenLayer = new TileLayer({
  source: new XYZ({
    // 设置图层的 URL 模板
    url: "https://stamen-tiles-{a-d}.a.ssl.fastly.net/toner/{z}/{x}/{y}.png"
  })
});

2. OSM (ol/source/OSM)

import TileLayer from "ol/layer/Tile";
import OSM from "ol/source/OSM";
 
// 创建 OpenStreetMap 图层
const osmLayer = new TileLayer({
  source: new OSM()
});

3. WMS (ol/source/TileWMS)

import TileLayer from "ol/layer/Tile";
import TileWMS from "ol/source/TileWMS";
 
// 创建 WMS 图层(从 Geoserver 获取数据)
const wmsLayer = new TileLayer({
  source: new TileWMS({
    // 设置 Geoserver 服务的 URL
    url: "https://your-geoserver-url/wms",
    // 设置请求参数
    params: {
      // 指定要获取的图层名称
      LAYERS: "your-layer-name",
      // 设置为平铺模式获取
      TILED: true
    }
  })
});

创建好对应图层后,您可以将它们添加到 OpenLayers 地图实例中:

const map = new ol.Map({
  target: "map-container",
  layers: [stamenLayer, osmLayer, wmsLayer],
  view: view
});

三、加载天地图、百度、高德、ArcGIS、Bing、OSM、Google

1. 天地图(使用 WMTS 服务)

天地图有自己的服务,并且支持 WMTS。因此,为了使用这个优越的加载功能,我们通过创建一个包含 WMTS 结构的层来定义它。我们使用 ol/source/WMTS 启用 WMTS 加载,并定义各种地图参数以适应该服务的特点。例如,我们定义了瓦片网格,包括投影、瓦片的分辨率和矩阵 ID 等。

import TileLayer from "ol/layer/Tile";
import WMTS from "ol/source/WMTS";
import WMTSTileGrid from "ol/tilegrid/WMTS";
import { get as getProjection } from "ol/proj";
import { getWidth, getTopLeft } from "ol/extent";
 
const projection = getProjection("EPSG:900913");
const projectionExtent = projection.getExtent();
const size = getWidth(projectionExtent) / 256;
const resolutions = new Array(19);
const matrixIds = new Array(19);
for (let z = 0; z < 19; ++z) {
  resolutions[z] = size / Math.pow(2, z);
  matrixIds[z] = z;
}
const tileGrid = new WMTSTileGrid({
  origin: getTopLeft(projectionExtent),
  resolutions: resolutions,
  matrixIds: matrixIds,
});
 
const tiandituLayer = new TileLayer({
  source: new WMTS({
    url: "http://t{s}.tianditu.com/vec_c/wmts",
    layer: "vec",
    style: "default",
    matrixSet: "c",
    format: "tiles",
    wrapX: true,
    tileGrid: tileGrid,
    requestEncoding: "KVP",
    attributions: [
      '&copy; <a target="_blank" href="http://www.tianditu.gov.cn/">天地图</a>',
    ],
    urls: [
      "http://t0.tianditu.com/vec_c/wmts",
      "http://t1.tianditu.com/vec_c/wmts",
      "http://t2.tianditu.com/vec_c/wmts",
      "http://t3.tianditu.com/vec_c/wmts",
      "http://t4.tianditu.com/vec_c/wmts",
      "http://t5.tianditu.com/vec_c/wmts",
      "http://t6.tianditu.com/vec_c/wmts",
      "http://t7.tianditu.com/vec_c/wmts",
    ],
    tilePixelRatio: 1,
  }),
});
  • style: “default”: 设置图层样式,对于天地图同一种底图服务会有多种样式。
  • matrixSet: “c”: 设置矩阵集,这是一个用于瓦片地图切分的参数。
  • format: “tiles”: 设置图层图片格式,此处设置为 “tiles” 表示瓦片格式。
  • wrapX: true: 设置是否在水平方向上重复显示瓦片,true 表示重复,false 表示不重复。
  • tileGrid: tileGrid: 设置自定义瓦片网格,这里使用了前面创建的 tileGrid 变量,它包含了投影、分辨率和矩阵 ID 等信息。
  • requestEncoding: “KVP”: 设置请求编码,此处设置为 “KVP” 表示使用键值对格式的请求参数。在 OpenLayers 中,requestEncoding 参数用于设置 WMTS 服务的请求编码方式。requestEncoding 可以取以下两个值之一:
    “KVP”:表示使用键值对格式的请求参数,即 Key-Value Pair。这种格式是 WMTS 服务的一个标准请求方式,它将请求参数按照 “key=value” 的形式附加到 URL 中。例如:http://example.com/wmts?layer=mylayer&style=default&matrixSet=EPSG:900913 等。
  • “REST”:表示使用 RESTful 形式的请求参数。在这种格式下,请求参数会通过路径参数的形式嵌入到 URL 中。例如:http://example.com/wmts/matrix/EPSG:900913/1/2/2 等。
    如果不设置 requestEncoding 参数,默认值为 “KVP”。在大多数情况下,使用默认值 “KVP” 是足够的。但是,有些 WMTS 服务可能需要使用 RESTful 请求方式。在这种情况下,需要将 requestEncoding 设置为 “REST”。请根据实际情况选择合适的参数值,通过天地图官方接口样式我们可知选择 “KVP”,当然我们也可以选择不写,因为默认就是 “KVP”)
  • attributions: […]: 设置图层的版权信息。这是一个数组,每个元素表示一个版权声明。
  • urls: […]: 设置天地图服务的瓦片服务器 URL 列表,以实现负载均衡。当请求天地图瓦片时,OpenLayers 会从列表中随机选择一个服务器地址进行请求。这可以防止在高并发请求时,某一台服务器过载,提高服务可用性。

通过设置这些参数,我们可以保证正确加载和显示天地图底图。当然,这些参数是为天地图服务提供的,不同的地图服务需求可能有所不同。在加载其他地图服务时,应参考其 API 文档进行相应的参数配置。

2. 百度地图(使用 XYZ 服务)

在百度地图示例中,我们选择加载 XYZ 服务,因为这是一种通用方式,易于实施。我们为 TileLayer 的 source 提供百度地图瓦片服务器托管图像的 URL。需要指出的是,在这个例子中,我们没有使用百度地图的原生 JavaScript 库,而是优先采用了更通用和可扩展的 XYZ 加载方法。

import TileLayer from "ol/layer/Tile";
import XYZ from "ol/source/XYZ";
 
const baiduLayer = new TileLayer({
  source: new XYZ({
    url: "http://online{s}.map.bdimg.com/onlinelabel/?qt=tile&x={x}&y={y}&z={z}&styles=pl&udt=20141103&scaler=1",
    crossOrigin: "anonymous",
  }),
});

3. 高德地图(使用 XYZ 服务)

在高德地图示例中,我们采用了与百度地图相同的 XYZ 加载方法,原因是这种方法广泛应用于各种地图服务,并且易于实现。

import TileLayer from "ol/layer/Tile";
import XYZ from "ol/source/XYZ";
 
const gaodeLayer = new TileLayer({
  source: new XYZ({
    url: "https://webrd0{s}.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=040&size=1&scale=1&ltype=7",
    crossOrigin: "anonymous",
  }),
});

4. ArcGIS(使用 XYZ 服务)

ArcGIS 示例也采用了通用的 XYZ 加载方法,因为 ArcGIS 的图层 URL 结构与标准 XYZ 图层类似,容易被 OpenLayers 识别和使用。 ol/source/XYZ 提供了一个简单、通用的解决方案,用于从 ArcGIS 瓦片服务器获取图像。

import TileLayer from "ol/layer/Tile";
import XYZ from "ol/source/XYZ";
 
const arcGISLayer = new TileLayer({
  source: new XYZ({
    url: "https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}",
    crossOrigin: "anonymous",
  }),
});

5. Bing Maps(使用专用的 BingMaps 服务)

为了获得更好的兼容性和性能,这个示例选择使用专用的 ol/source/BingMaps 服务加载 Bing Maps。此服务允许用户直接设置 API 密钥和影像集(如路网、航空照片等),从而使代码更加简洁。

import TileLayer from "ol/layer/Tile";
import BingMaps from "ol/source/BingMaps";
  
const bingLayer = new TileLayer({
  source: new BingMaps({
    key: "{your-bing-maps-api-key}",
    imagerySet: "Road",
  }),
});

6. OpenStreetMap(OSM)

在 OSM 示例中,我们采用了专用服务 ol/source/OSM,因为它能够方便地访问默认的 OSM Fastly 瓦片服务器。这是一种简单的方式,可以直接加载 OSM 图层而无需进一步配置。

import TileLayer from "ol/layer/Tile";
import OSM from "ol/source/OSM";
  
const osmLayer = new TileLayer({
  source: new OSM()
});

7. Google Maps(使用 XYZ 服务)

Google Maps 示例采用了通用的 XYZ 加载方法,使用完整的瓦片 URL 地址来设置图层来源。需要注意的是,由于谷歌对地图服务的商业限制,这个示例的代码可能仅用于学习和实验目的。如果您要开发一个真正的 Google Maps 应用程序,最好使用 Google Maps 提供的官方 JavaScript API。

import TileLayer from "ol/layer/Tile";
import XYZ from "ol/source/XYZ";
  
const googleLayer = new TileLayer({
  source: new XYZ({
    url: "https://mt{s}.google.cn/vt/lyrs=m&x={x}&y={y}&z={z}",
    crossOrigin: "anonymous",
  }),
});

以上示例代码分别展示了如何使用不同地图数据源加载底图。请注意将相关代码中的 {your-tianditu-api-key} 和 {your-bing-maps-api-key} 替换为对应的实际的 API 密钥,以确保天地图和必应地图可以正常加载。即使在使用示例代码时,请务必将所有示例视为单独示例。

在每个示例中,我们都将图层名称定义为必要的属性(通过 layer 或 imagerySet 参数设置)以便访问特定的图层,如路网或卫星图像。另外,由于 TileLayer 的 source 属于一个提供服务器托管图像的 URL 的外部来源,我们为 source 属性设置 crossOrigin: “anonymous”。这可以防止因为 CORS 问题而出现加载错误,而无需对服务器进行额外配置。

三、整体代码

<template>
  <div id="map" class="map"></div>
</template>

<script>
import "ol/ol.css";
import { Map, View } from "ol";
import TileLayer from "ol/layer/Tile";
import OSM from "ol/source/OSM";
import XYZ from "ol/source/XYZ";
import BingMaps from "ol/source/BingMaps";
import { fromLonLat } from "ol/proj";

export default {
  name: "MapComponent",
  data() {
    return {
      map: null,
      apiKey: "--", // 用于 Mapbox
      arcgisKey: "YOUR_ARCGIS_API_KEY", // 用于 ArcGIS
      bingKey: "YOUR_BING_API_KEY", // 用于 Bing Maps
      googleKey: "YOUR_GOOGLE_API_KEY", // 用于 Google Maps
    };
  },
  mounted() {
    this.initMap();
  },
  methods: {
    initMap() {
      const map = new Map({
        target: "map",
        layers: [],
        view: new View({
          center: fromLonLat([116.407428, 39.904198]),
          zoom: 10,
        }),
      });

      this.addTDTLayer(map);
      this.addBaiduLayer(map);
      this.addGaodeLayer(map);
      this.addArcGisLayer(map);
      this.addBingLayer(map);
      this.addOSMLayer(map);
      this.addGoogleLayer(map);

      this.map = map;
    },

    addTDTLayer(map) {
      const tdtLayer = new TileLayer({
        source: new XYZ({
          url:
            "http://t{1-4}.tianditu.gov.cn/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=" +
            this.apiKey,
          crossOrigin: "anonymous",
          attributions: ["天地图", new Date().getFullYear()],
        }),
      });
      map.addLayer(tdtLayer);
    },

    addBaiduLayer(map) {
      const baiduLayer = new TileLayer({
        source: new XYZ({
          url: "http://online{s}.map.bdimg.com/onlinelabel/?qt=tile&x={x}&y={y}&z={z}&styles=pl&scaler=1&p=1",
          crossOrigin: "anonymous",
          attributions: ["百度地图", new Date().getFullYear()],
        }),
      });
      map.addLayer(baiduLayer);
    },

    addGaodeLayer(map) {
      const gaodeLayer = new TileLayer({
        source: new XYZ({
          url: "https://webst0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x={x}&y={y}&z={z}",
          crossOrigin: "anonymous",
          attributions: ["高德地图", new Date().getFullYear()],
        }),
      });
      map.addLayer(gaodeLayer);
    },

    addArcGisLayer(map) {
      const arcgisLayer = new TileLayer({
        source: new XYZ({
          url: `https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}?token=${this.arcgisKey}`,
          crossOrigin: "anonymous",
          attributions: ["ArcGIS", new Date().getFullYear()],
        }),
      });
      map.addLayer(arcgisLayer);
    },

    addBingLayer(map) {
      const bingLayer = new TileLayer({
        source: new BingMaps({
          key: this.bingKey,
          imagerySet: "AerialWithLabels",
        }),
      });
      map.addLayer(bingLayer);
    },

    addOSMLayer(map) {
      const osmLayer = new TileLayer({
        source: new OSM(),
      });
      map.addLayer(osmLayer);
    },

    addGoogleLayer(map) {
      const googleLayer = new TileLayer({
        source: new XYZ({
          url: `https://mt1.google.com/vt/lyrs=m&hl=en&x={x}&y={y}&z={z}&key=${this.googleKey}`,
          crossOrigin: "anonymous",
          attributions: ["Google Maps", new Date().getFullYear()],
        }),
      });
      map.addLayer(googleLayer);
    },
  },
};
</script>

<style scoped>
.map {
  width: 100%;
  height: 2500px;
}
</style>

部分地图服务可能需要您在设置 source 属性时使用一个有效的 API 密钥,这通常与官方服务(例如天地图和 Bing Maps)相关联。
这些代码示例遵循 OpenLayers 标准实现,并注重代码的可读性、扩展性和简洁性。根据这些示例,您可以轻松地将各种地图数据源添加到你的 OpenLayers 项目中,并根据自己的需求进行修改和调整。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值