前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >WebGis技术汇总

WebGis技术汇总

作者头像
码客说
发布2023-07-11 14:09:43
7970
发布2023-07-11 14:09:43
举报
文章被收录于专栏:码客

前言

WebGIS系统通常都围绕地图进行内容表达,但并不是有地图就一定是WebGIS,所以有必要讨论下基于Web的地图API分类及应用场景。

Web上的Map API主要分类如下几类:

  • Charts:以D3.js,Echarts等为代表。
  • LBS:以高德/谷歌/百度地图等为代表。
  • WebGIS商业API:ESRI的ArcGIS API For JS,超图的IClient。
  • WebGIS开源API:Leaflet,OpenLayers,Cesium,MapboxGL等。

建模工具Blender

https://zhuanlan.zhihu.com/p/628531907

Leaflet

https://leafletjs.com/

OpenLayers

https://openlayers.org/doc/quickstart.html

https://blog.csdn.net/qq_29602347/article/details/99623968

https://viglino.github.io/ol-ext/examples/map/map.layer.3D.html

Cesium

https://github.com/CesiumGS/cesium

https://sandcastle.cesium.com/?src=3D%20Tiles%20Photogrammetry.html

使用OpenLayers

创建项目

代码语言:javascript
复制
vue create z-webgis-ol

添加依赖

代码语言:javascript
复制
cd z-webgis-ol

npm i -S ol

地图页面

添加页面

OlMap.vue

代码语言:javascript
复制
// example
<template>
  <div style="height: 100vh; width: 100vw">
    <div id="map" ref="map" style="height: 100%; width: 100%"></div>
  </div>
</template>

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

export default {
  data() {
    return {
      map: {},
    };
  },
  mounted() {
    this.initMap();
  },
  methods: {
    initMap() {
      this.map = new Map({
        target: "map",
        layers: [
          new TileLayer({
            source: new OSM({
              url: "http://webst0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x={x}&y={y}&z={z}",
              crossOrigin: "anonymous",
              maxZoom: 19,
            }),
          }),
        ],
        view: new View({
          center: [121.5025, 31.237015], // 中心点, 填的是经纬度
          projection: "EPSG:4326", // EPSG:4326格式的经纬度
          zoom: 10, // 地图默认缩放级别
          maxZoom: 15, // 地图最大缩放级别
          // minZoom: 5, // 地图最小缩放级别
        }),
      });
    },
  },
};
</script>

<style>
#map {
  height: 100%;
}

/*隐藏ol的一些自带元素*/
.ol-attribution,
.ol-zoom {
  display: none;
}
</style>

瓦片地址

瓦片地址配置

代码语言:javascript
复制
new TileLayer({
	source: new OSM(),
}),

更换为

代码语言:javascript
复制
new TileLayer({
    source: new OSM({
      url: "https://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png",
      crossOrigin: "anonymous",
      maxZoom: 19,
    }),
}),

高德

代码语言:javascript
复制
new TileLayer({
    source: new OSM({
      url: "http://webst0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x={x}&y={y}&z={z}",
      crossOrigin: "anonymous",
      maxZoom: 19,
    }),
}),

openstreetmap地址

代码语言:javascript
复制
https://a.tile.openstreetmap.org/10/809/421.png

格式为

代码语言:javascript
复制
https://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png

高德的地址

http://webst01.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x=809&y=421&z=10

格式为

代码语言:javascript
复制
http://webst0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x={x}&y={y}&z={z}

经纬度

代码语言:javascript
复制
view: new View({
  center: [121.5025, 31.237015], // 中心点, 填的是经纬度
  projection: "EPSG:4326", // EPSG:4326格式的经纬度
  zoom: 10, // 地图默认缩放级别
  maxZoom: 15, // 地图最大缩放级别
  minZoom: 5, // 地图最小缩放级别
}),

引用

代码语言:javascript
复制
<template>
  <div class="home">
    <olmap />
  </div>
</template>

<script>
// @ is an alias to /src
import olmap from "@/components/OlMap.vue";

export default {
  name: "HomeView",
  components: {
    olmap,
  },
};
</script>

百度坐标拾取器

https://lbs.qq.com/getPoint/

经纬度转换

概念

投影方式

  • Google的墨卡托坐标,也就是我们经常看到的 EPSG:3857 坐标系。 EPSG:3857 的数据一般是这种的。[12914838.35,4814529.9],看上去相对数值较大。不利于存储,比较占内存。
  • EPSG:4326/WGS-84:是国际标准,GPS坐标(Google Earth使用、或者GPS模块)。 EPSG:4326 的数据一般是这种的。[22.37,114.05]。利于存储,可读性高。 所以我们常常看到和用到的坐标系数据往往不是墨卡托坐标,而是EPSG:4326坐标系下的坐标数据。

讲完投影方式,我们再聊一下坐标系,WGS84、GCJ-02、BD-09

WGS84/EPSG:4326:也叫大地坐标系,它是原始坐标系统。

GCJ02/火星坐标:是由中国国家测绘局(G表⽰Guojia国家,C表⽰Cehui测绘,J表⽰Ju局)制订的地理信息系统的坐标系统,是在WGS84经纬度的基础上执⾏加密算法⽽成。因为GPS得到的经纬度直接在 GCJ-02 坐标系下会定位到错误的地点,有种到了⽕星的感觉,因此在坊间也将 GCJ-02 戏称为火星坐标系。

BD09:只有百度地图没有使用这种加密算法,而是使用的是BD09,从名字上可以看出,GCJ02是2002年提出来的算法,BD09则是2009年提出来的,虽然百度地图没有使用GCJ02加密算法,但是他却是在GCJ02基础上做了一个二次加密,所以说,从WGS84坐标系不能直接转BD09,中间需要跨越一个GCJ02,反过来,需要将GCJ02或者BD09转为WGS84就是纠偏算法,相当于逆向解密,同样的DB09直接到不了WGS84,中间还需要转为GCJ02,所以现在的很多算法,如果你看到有百度坐标转大地坐标,基本上需要借助火星坐标来计算。

使用对象

高德地图、腾讯地图以及谷歌中国区地图使用的是GCJ-02坐标系

百度地图使用的是BD-09坐标系

底层接口(HTML5 Geolocation或iOS、安卓API)通过GPS设备获取的坐标使用的是EPSG:4326/WGS-84坐标系

在Openlayers 中默认的坐标就是Google的摩卡托坐标,也就是我们经常看到的 EPSG:3857 坐标系。

不过我们可以设置为EPSG:4326/WGS-84

代码语言:javascript
复制
view: new View({
  center: [121.5025, 31.237015], // 中心点, 填的是经纬度
  projection: "EPSG:4326", // EPSG:4326格式的经纬度
  zoom: 10, // 地图默认缩放级别
  maxZoom: 15, // 地图最大缩放级别
  minZoom: 5, // 地图最小缩放级别
}),

坐标示例:

  • EPSG:3857 的数据一般是这种的:[12914838.35,4814529.9],看上去相对数值较大。不利于存储,比较占内存。
  • EPSG:4326/WGS-84 数据一般是这种的:[121.5025, 31.237015]
  • BD-09的数据一般是这种的[113.65523,34.79977]

EPSG:4326/WGS-84:是国际标准,GPS坐标(Google Earth使用、或者GPS模块)EPSG:4326 的数据一般是这种的:[22.37,114.05]。利于存储,可读性高。

EPSG:4326和EPSG:3857区别(重点)

EPSG:3857(投影):数据的可读性差和数值大存储比较占用内存。 EPSG:4326(地理):使用此坐标系会导致页面变形。

经纬度存储计算用EPSG:4326也就是WGS84,数据展示用EPSG:3857。

百度地图采用 BD09 百度坐标系,叠加到 Leaflet 和 Cesium 默认的 WGS84 通用坐标系需要进行纠偏。

2个格式的数据怎么互转呢?

JS转换

代码语言:javascript
复制
var GPS = {
    PI: 3.14159265358979324,
    x_pi: 3.14159265358979324 * 3000.0 / 180.0,
    delta: function (lat, lon) {
        // Krasovsky 1940
        //
        // a = 6378245.0, 1/f = 298.3
        // b = a * (1 - f)
        // ee = (a^2 - b^2) / a^2;
        var a = 6378245.0; //  a: 卫星椭球坐标投影到平面地图坐标系的投影因子。
        var ee = 0.00669342162296594323; //  ee: 椭球的偏心率。
        var dLat = this.transformLat(lon - 105.0, lat - 35.0);
        var dLon = this.transformLon(lon - 105.0, lat - 35.0);
        var radLat = lat / 180.0 * this.PI;
        var magic = Math.sin(radLat);
        magic = 1 - ee * magic * magic;
        var sqrtMagic = Math.sqrt(magic);
        dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * this.PI);
        dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * this.PI);
        return { 'lat': dLat, 'lon': dLon };
    },

    //WGS-84 to GCJ-02
    gcj_encrypt: function (wgsLat, wgsLon) {
        if (this.outOfChina(wgsLat, wgsLon))
            return { 'lat': wgsLat, 'lon': wgsLon };

        var d = this.delta(wgsLat, wgsLon);
        return { 'lat': wgsLat + d.lat, 'lon': wgsLon + d.lon };
    },
    //GCJ-02 to WGS-84 (粗略)
    gcj_decrypt: function (gcjLat, gcjLon) {
        if (this.outOfChina(gcjLat, gcjLon))
            return { 'lat': gcjLat, 'lon': gcjLon };

        var d = this.delta(gcjLat, gcjLon);
        return { 'lat': gcjLat - d.lat, 'lon': gcjLon - d.lon };
    },
    //GCJ-02 to WGS-84 exactly (精确(二分极限法))
    gcj_decrypt_exact: function (gcjLat, gcjLon) {
        var initDelta = 0.01;
        var threshold = 0.000000001;
        var dLat = initDelta, dLon = initDelta;
        var mLat = gcjLat - dLat, mLon = gcjLon - dLon;
        var pLat = gcjLat + dLat, pLon = gcjLon + dLon;
        var wgsLat, wgsLon, i = 0;
        while (1) {
            wgsLat = (mLat + pLat) / 2;
            wgsLon = (mLon + pLon) / 2;
            var tmp = this.gcj_encrypt(wgsLat, wgsLon)
            dLat = tmp.lat - gcjLat;
            dLon = tmp.lon - gcjLon;
            if ((Math.abs(dLat) < threshold) && (Math.abs(dLon) < threshold))
                break;

            if (dLat > 0) pLat = wgsLat; else mLat = wgsLat;
            if (dLon > 0) pLon = wgsLon; else mLon = wgsLon;

            if (++i > 10000) break;
        }
        //console.log(i);
        return { 'lat': wgsLat, 'lon': wgsLon };
    },
    //GCJ-02 to BD-09
    bd_encrypt: function (gcjLat, gcjLon) {
        var x = gcjLon, y = gcjLat;
        var z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * this.x_pi);
        var theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * this.x_pi);
        bdLon = z * Math.cos(theta) + 0.0065;
        bdLat = z * Math.sin(theta) + 0.006;
        return { 'lat': bdLat, 'lon': bdLon };
    },
    //BD-09 to GCJ-02
    bd_decrypt: function (bdLat, bdLon) {
        var x = bdLon - 0.0065, y = bdLat - 0.006;
        var z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * this.x_pi);
        var theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * this.x_pi);
        var gcjLon = z * Math.cos(theta);
        var gcjLat = z * Math.sin(theta);
        return { 'lat': gcjLat, 'lon': gcjLon };
    },
    //WGS-84 to Web mercator
    //mercatorLat -> y mercatorLon -> x
    mercator_encrypt: function (wgsLat, wgsLon) {
        var x = wgsLon * 20037508.34 / 180.;
        var y = Math.log(Math.tan((90. + wgsLat) * this.PI / 360.)) / (this.PI / 180.);
        y = y * 20037508.34 / 180.;
        return { 'lat': y, 'lon': x };
        /*
         if ((Math.abs(wgsLon) > 180 || Math.abs(wgsLat) > 90))
         return null;
         var x = 6378137.0 * wgsLon * 0.017453292519943295;
         var a = wgsLat * 0.017453292519943295;
         var y = 3189068.5 * Math.log((1.0 + Math.sin(a)) / (1.0 - Math.sin(a)));
         return {'lat' : y, 'lon' : x};
         //*/
    },
    // Web mercator to WGS-84
    // mercatorLat -> y mercatorLon -> x
    mercator_decrypt: function (mercatorLat, mercatorLon) {
        var x = mercatorLon / 20037508.34 * 180.;
        var y = mercatorLat / 20037508.34 * 180.;
        y = 180 / this.PI * (2 * Math.atan(Math.exp(y * this.PI / 180.)) - this.PI / 2);
        return { 'lat': y, 'lon': x };
    },
    //两点的距离
    distance: function (latA, lonA, latB, lonB) {
        var earthR = 6371000.;
        var x = Math.cos(latA * this.PI / 180.) * Math.cos(latB * this.PI / 180.) * Math.cos((lonA - lonB) * this.PI / 180);
        var y = Math.sin(latA * this.PI / 180.) * Math.sin(latB * this.PI / 180.);
        var s = x + y;
        if (s > 1) s = 1;
        if (s < -1) s = -1;
        var alpha = Math.acos(s);
        var distance = alpha * earthR;
        return distance;
    },
    outOfChina: function (lat, lon) {
        if (lon < 72.004 || lon > 137.8347)
            return true;
        if (lat < 0.8293 || lat > 55.8271)
            return true;
        return false;
    },
    transformLat: function (x, y) {
        var ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.sqrt(Math.abs(x));
        ret += (20.0 * Math.sin(6.0 * x * this.PI) + 20.0 * Math.sin(2.0 * x * this.PI)) * 2.0 / 3.0;
        ret += (20.0 * Math.sin(y * this.PI) + 40.0 * Math.sin(y / 3.0 * this.PI)) * 2.0 / 3.0;
        ret += (160.0 * Math.sin(y / 12.0 * this.PI) + 320 * Math.sin(y * this.PI / 30.0)) * 2.0 / 3.0;
        return ret;
    },
    transformLon: function (x, y) {
        var ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.sqrt(Math.abs(x));
        ret += (20.0 * Math.sin(6.0 * x * this.PI) + 20.0 * Math.sin(2.0 * x * this.PI)) * 2.0 / 3.0;
        ret += (20.0 * Math.sin(x * this.PI) + 40.0 * Math.sin(x / 3.0 * this.PI)) * 2.0 / 3.0;
        ret += (150.0 * Math.sin(x / 12.0 * this.PI) + 300.0 * Math.sin(x / 30.0 * this.PI)) * 2.0 / 3.0;
        return ret;
    }
};

上面这段代码,没有对百度坐标bd09转大地坐标wgs84、大地坐标wgs84转百度坐标bd09进行书写,

如果你了解坐标之间的关系,你大概就能猜到:

只需要借助wgs84->gcj02->bd09就能实现wgs84->bd09的实现。

相反,借助bd09->gcj02->wgs84就能实现bd09->wgs84的转换了。

另一个封装

代码语言:javascript
复制
/**
 * Created by Wandergis on 2015/7/8.
 * 提供了百度坐标(BD-09)、国测局坐标(火星坐标,GCJ-02)、和 WGS-84 坐标系之间的转换
 */
// UMD 魔法代码
// if the module has no dependencies, the above pattern can be simplified to
(function (root, factory) {
  if (typeof define === 'function' && define.amd) {
    // AMD. Register as an anonymous module.
    define([], factory);
  } else if (typeof module === 'object' && module.exports) {
    // Node. Does not work with strict CommonJS, but
    // only CommonJS-like environments that support module.exports,
    // like Node.
    module.exports = factory();
  } else {
    // Browser globals (root is window)
    root.coordtransform = factory();
  }
}(this, function () {
  // 定义一些常量
  var x_PI = 3.14159265358979324 * 3000.0 / 180.0;
  var PI = 3.1415926535897932384626;
  var a = 6378245.0;
  var ee = 0.00669342162296594323;
  /**
   * 百度坐标系 (BD-09) 与 火星坐标系 (GCJ-02) 的转换
   * 即 百度 转 谷歌、高德
   * @param bd_lng
   * @param bd_lat
   * @returns {*[]}
   */
  var bd09togcj02 = function bd09togcj02(bd_lng, bd_lat) {
    var bd_lng = +bd_lng;
    var bd_lat = +bd_lat;
    var x = bd_lng - 0.0065;
    var y = bd_lat - 0.006;
    var z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_PI);
    var theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_PI);
    var gg_lng = z * Math.cos(theta);
    var gg_lat = z * Math.sin(theta);
    return [gg_lng, gg_lat]
  };
 
  /**
   * 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换
   * 即 谷歌、高德 转 百度
   * @param lng
   * @param lat
   * @returns {*[]}
   */
  var gcj02tobd09 = function gcj02tobd09(lng, lat) {
    var lat = +lat;
    var lng = +lng;
    var z = Math.sqrt(lng * lng + lat * lat) + 0.00002 * Math.sin(lat * x_PI);
    var theta = Math.atan2(lat, lng) + 0.000003 * Math.cos(lng * x_PI);
    var bd_lng = z * Math.cos(theta) + 0.0065;
    var bd_lat = z * Math.sin(theta) + 0.006;
    return [bd_lng, bd_lat]
  };
 
  /**
   * WGS-84 转 GCJ-02
   * @param lng
   * @param lat
   * @returns {*[]}
   */
  var wgs84togcj02 = function wgs84togcj02(lng, lat) {
    var lat = +lat;
    var lng = +lng;
    if (out_of_china(lng, lat)) {
      return [lng, lat]
    } else {
      var dlat = transformlat(lng - 105.0, lat - 35.0);
      var dlng = transformlng(lng - 105.0, lat - 35.0);
      var radlat = lat / 180.0 * PI;
      var magic = Math.sin(radlat);
      magic = 1 - ee * magic * magic;
      var sqrtmagic = Math.sqrt(magic);
      dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI);
      dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * PI);
      var mglat = lat + dlat;
      var mglng = lng + dlng;
      return [mglng, mglat]
    }
  };
 
  /**
   * GCJ-02 转换为 WGS-84
   * @param lng
   * @param lat
   * @returns {*[]}
   */
  var gcj02towgs84 = function gcj02towgs84(lng, lat) {
    var lat = +lat;
    var lng = +lng;
    if (out_of_china(lng, lat)) {
      return [lng, lat]
    } else {
      var dlat = transformlat(lng - 105.0, lat - 35.0);
      var dlng = transformlng(lng - 105.0, lat - 35.0);
      var radlat = lat / 180.0 * PI;
      var magic = Math.sin(radlat);
      magic = 1 - ee * magic * magic;
      var sqrtmagic = Math.sqrt(magic);
      dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI);
      dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * PI);
      var mglat = lat + dlat;
      var mglng = lng + dlng;
      return [lng * 2 - mglng, lat * 2 - mglat]
    }
  };
 
  var transformlat = function transformlat(lng, lat) {
    var lat = +lat;
    var lng = +lng;
    var ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng));
    ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0;
    ret += (20.0 * Math.sin(lat * PI) + 40.0 * Math.sin(lat / 3.0 * PI)) * 2.0 / 3.0;
    ret += (160.0 * Math.sin(lat / 12.0 * PI) + 320 * Math.sin(lat * PI / 30.0)) * 2.0 / 3.0;
    return ret
  };
 
  var transformlng = function transformlng(lng, lat) {
    var lat = +lat;
    var lng = +lng;
    var ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng));
    ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0;
    ret += (20.0 * Math.sin(lng * PI) + 40.0 * Math.sin(lng / 3.0 * PI)) * 2.0 / 3.0;
    ret += (150.0 * Math.sin(lng / 12.0 * PI) + 300.0 * Math.sin(lng / 30.0 * PI)) * 2.0 / 3.0;
    return ret
  };
 
  /**
   * 判断是否在国内,不在国内则不做偏移
   * @param lng
   * @param lat
   * @returns {boolean}
   */
  var out_of_china = function out_of_china(lng, lat) {
    var lat = +lat;
    var lng = +lng;
    // 纬度 3.86~53.55, 经度 73.66~135.05 
    return !(lng > 73.66 && lng < 135.05 && lat > 3.86 && lat < 53.55);
  };
 
  return {
    bd09togcj02: bd09togcj02,
    gcj02tobd09: gcj02tobd09,
    wgs84togcj02: wgs84togcj02,
    gcj02towgs84: gcj02towgs84
  }
}));

使用方法:

代码语言:javascript
复制
//国测局坐标(火星坐标,比如高德地图在用),百度坐标,wgs84坐标(谷歌国外以及绝大部分国外在线地图使用的坐标)
var coordtransform = require('../index');
//百度经纬度坐标转国测局坐标
var bd09togcj02 = coordtransform.bd09togcj02(116.404, 39.915);
//国测局坐标转百度经纬度坐标
var gcj02tobd09 = coordtransform.gcj02tobd09(116.404, 39.915);
//wgs84转国测局坐标
var wgs84togcj02 = coordtransform.wgs84togcj02(116.404, 39.915);
//国测局坐标转wgs84坐标
var gcj02towgs84 = coordtransform.gcj02towgs84(116.404, 39.915);
console.log(bd09togcj02);
console.log(gcj02tobd09);
console.log(wgs84togcj02);
console.log(gcj02towgs84);
//result
//bd09togcj02:   [ 116.39762729119315, 39.90865673957631 ]
//gcj02tobd09:   [ 116.41036949371029, 39.92133699351021 ]
//wgs84togcj02:  [ 116.41024449916938, 39.91640428150164 ]
//gcj02towgs84:  [ 116.39775550083061, 39.91359571849836 ]

自带transform

可以通过ol/proj/transform这个方法 例:

代码语言:javascript
复制
transform([121.501842, 31.239204], ‘EPSG:4326’, ‘EPSG:3857’)

经纬度存储计算用EPSG:4326也就是WGS84,数据展示用EPSG:3857。

用 fromLonLat() 方法把4326的坐标转换为3857的坐标。

代码语言:javascript
复制
import { fromLonLat } from 'ol/proj'
this.centerMap = new Map({
    target: 'centerMap',
    layers: this.baseLayers,
    view: new View({
        projection: 'EPSG:3857',
        center: fromLonLat([117.691603, 39.014074]),
        zoom: 11.5,
        maxZoom: 18,
        minZoom: 5
    })
})

在实际开发中,因为map源数据大部分都是EPSG:4326的数据源格式的数据,但是使用EPSG:4326的坐标系地图会出现被压缩的感觉。

所以我们都是采用 EPSG:3857的坐标系类型,把数据源转换位 EPSG:3857的数据源即可。

但是这个EPSG:3857数据源不易读取和值占内存原因,所有结合两者的缺点,我们采用坐标转换,即 EPSG:4326转 EPSG:3857。

所有请理解这句话:

通常:数据存储在EPSG:4326中,显示在EPSG:3857中 如下所示:

代码语言:javascript
复制
function anmiteCenter(map, attr, zoom) {
    let pos = [parseFloat(attr.lon), parseFloat(attr.lat)];
    pos = ol.proj.transform(pos, 'EPSG:4326', 'EPSG:3857');
    map.getView().animate({
        center: pos,
        zoom: zoom
    });
}

三方库gcoord

使用gcoord这个库

代码语言:javascript
复制
npm install gcoord --save

使用

代码语言:javascript
复制
import gcoord from 'gcoord'
const xy = gcoord.transform(
   [经度, 纬度],
   gcoord.EPSG4326,
   gcoord.EPSG3857
 )

瓦片地址

高德(可用)

高德瓦片地图下载地址

矢量图

矢量图(含路网、含注记)

代码语言:javascript
复制
http://wprd0{1,4}.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scl=1&style=7

示例

http://wprd01.is.autonavi.com/appmaptile?x=809&y=421&z=10&lang=zh_cn&size=1&scl=1&style=7

http://wprd04.is.autonavi.com/appmaptile?x=809&y=421&z=10&lang=zh_cn&size=1&scl=1&style=7

矢量图(含路网,不含注记)

代码语言:javascript
复制
http://wprd0{1,4}.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scl=2&style=7

示例

http://wprd01.is.autonavi.com/appmaptile?x=809&y=421&z=10&lang=zh_cn&size=1&scl=2&style=7

http://wprd04.is.autonavi.com/appmaptile?x=809&y=421&z=10&lang=zh_cn&size=1&scl=2&style=7

影像

高德影像:

代码语言:javascript
复制
https://webst01.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}

https://webst01.is.autonavi.com/appmaptile?style=6&x=809&y=421&z=10

参数说明:

  1. {1,4}选一个数字,
  2. {x}、{y}、{z}需要替换为相应的层级。
  3. lang=zh_cn 标注语言为中文。

ArcGIS(可用)

ArcGIS上对外开放的瓦片地址网站

中文

代码语言:javascript
复制
https://map.geoq.cn/arcgis/rest/services/ChinaOnlineCommunity_Mobile/MapServer/tile/{z}/{y}/{x}

示例

https://map.geoq.cn/arcgis/rest/services/ChinaOnlineCommunity_Mobile/MapServer/tile/10/421/809

英文

代码语言:javascript
复制
https://map.geoq.cn/arcgis/rest/services/ChinaOnlineCommunityENG/MapServer/tile/{z}/{y}/{x}

示例

https://map.geoq.cn/arcgis/rest/services/ChinaOnlineCommunityENG/MapServer/tile/10/421/809

中文灰色

代码语言:javascript
复制
https://map.geoq.cn/arcgis/rest/services/ChinaOnlineStreetGray/MapServer/tile/{z}/{y}/{x}

示例

https://map.geoq.cn/arcgis/rest/services/ChinaOnlineStreetGray/MapServer/tile/10/421/809

中文蓝色

代码语言:javascript
复制
https://map.geoq.cn/arcgis/rest/services/ChinaOnlineStreetPurplishBlue/MapServer/tile/{z}/{y}/{x}

示例

https://map.geoq.cn/arcgis/rest/services/ChinaOnlineStreetPurplishBlue/MapServer/tile/10/421/809

中文暖色

代码语言:javascript
复制
https://map.geoq.cn/arcgis/rest/services/ChinaOnlineStreetWarm/MapServer/tile/{z}/{z}/{y}/{x}

示例

https://map.geoq.cn/arcgis/rest/services/ChinaOnlineStreetWarm/MapServer/tile/10/421/809

百度(不推荐)

不推荐使用百度的,原因:

百度使用的坐标体系不是标准的WGS84,所以瓦片的XY坐标也不一致。

百度地图瓦片地址: 黄色底图

代码语言:javascript
复制
http://api0.map.bdimg.com/customimage/tile?&x={x}&y={y}&z={z}&udt=20191205&scale=1&ak=5ieMMexWmzB9jivTq6oCRX9j1

示例地址:

http://api0.map.bdimg.com/customimage/tile?&x=100&y=100&z=10&udt=20230704&scale=1&ak=gBd1Zf7VGjYj5G9YvWDKtHOniPvs1WGd

夜深色地图,蓝色地图

代码语言:javascript
复制
http://api0.map.bdimg.com/customimage/tile?&x={x}&y={y}&z={z}&udt=20191205&scale=1&ak=5ieMMexWmzB9jivTq6oCRX9j&customid=midnight

http://api0.map.bdimg.com/customimage/tile?&x=100&y=100&z=10&udt=20191205&scale=1&ak=5ieMMexWmzB9jivTq6oCRX9j&customid=midnight

百度个性化地图模板 只需要修改customid参数分别为:midnight、light、normal、grassgreen等。

腾讯(已失效)

代码语言:javascript
复制
vector = "http://rt{s}.map.gtimg.com/realtimerender?z={z}&x={x}&y={reverseY}&type=vector&style=0&scene=0",
terrain = "http://p{s}.map.gtimg.com/demTiles/{z}/{sx}/{sy}/{x}{reverseY}.jpg&scene=0",
img = "https://p{s}.map.gtimg.com/sateTiles/{z}/{sx}/{sy}/{x}{reverseY}.jpg&scene=0”,
label = "https://rt{s}.map.gtimg.com/tile?z={z}&x={x}&y={reverseY}&type=vector&styleid=3”,
vectorSimple = "https://rt{s}.map.gtimg.com/tile?z={z}&x={x}&y={reverseY}&type=vector&styleid=1”,
vectorGrey = "https://rt{s}.map.gtimg.com/tile?z={z}&x={x}&y={reverseY}&type=vector&styleid=2”,
vectorGreyExt = "https://rt{s}.map.gtimg.com/tile?z={z}&x={x}&y={reverseY}&type=vector&styleid=3”,
vectorBlue = "https://rt{s}.map.gtimg.com/tile?z={z}&x={x}&y={reverseY}&type=vector&styleid=4”,
vectorNormal = "https://rt{s}.map.gtimg.com/tile?z={z}&x={x}&y={reverseY}&type=vector&styleid=8”,

示例

http://rts.map.gtimg.com/realtimerender?z=10&x=809&y=421&type=vector&style=0&scene=0

新版本返回格式

https://rt2.map.gtimg.com/vector/?z=11&x=1674&y=1232&type=jsonp&version=1346&compress=1&enc=simon&key=4VQBZ-ZGO3G-VGSQE-ILN4G-LWFUK-5WB7H&output=jsonp&pf=jsapi&ref=jsapi&cb=qq.maps._svcb3.td1674_815_11

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-07-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 使用OpenLayers
    • 创建项目
      • 地图页面
        • 添加页面
        • 瓦片地址
        • 经纬度
      • 引用
      • 百度坐标拾取器
      • 经纬度转换
        • 概念
          • JS转换
            • 自带transform
              • 三方库gcoord
              • 瓦片地址
                • 高德(可用)
                  • 矢量图
                  • 影像
                • ArcGIS(可用)
                  • 中文
                  • 英文
                  • 中文灰色
                  • 中文蓝色
                  • 中文暖色
                • 百度(不推荐)
                  • 腾讯(已失效)
                  相关产品与服务
                  数据保险箱
                  数据保险箱(Cloud Data Coffer Service,CDCS)为您提供更高安全系数的企业核心数据存储服务。您可以通过自定义过期天数的方法删除数据,避免误删带来的损害,还可以将数据跨地域存储,防止一些不可抗因素导致的数据丢失。数据保险箱支持通过控制台、API 等多样化方式快速简单接入,实现海量数据的存储管理。您可以使用数据保险箱对文件数据进行上传、下载,最终实现数据的安全存储和提取。
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档