Vue+Openlayers+proj4实现坐标系转换

发布时间 2023-04-26 16:27:01作者: 霸道流氓

场景

Vue中使用Openlayers加载Geoserver发布的TileWMS:

https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/115916949

在上面的基础上实现不同坐标系坐标数据的转换。

Openlayers中默认的坐标系是EPSG:900913

 

EPSG:900913等效于EPSG:3857

可在EPSG官网进行验证

 

如果从其他坐标系的系统中获取坐标数据,则需要在Openlayers中进行坐标系转换。

注:

博客:
https://blog.csdn.net/badao_liumang_qizhi

实现

1、 openlayers中实现EPSG:4326和EPSG:3857的转换

openlayer默认支持3857和4326坐标相互转换

引入模块

import {transform} from 'ol/proj'

实现转换

    //EPSG:90013转换成EPSG:4326
    var coorTo4326 = transform([987777.93778,213834.81024], 'EPSG:3857', 'EPSG:4326')
    console.log("EPSG:90013转换成EPSG:4326为");
    console.log(coorTo4326);
    var coorTo3857 = transform(coorTo4326, 'EPSG:4326', 'EPSG:3857')
    console.log("EPSG:4326转换成EPSG:3857为");
    console.log(coorTo3857);

取一个EPSG:900913/EPSG:3857的坐标。实现与EPSG:4326的互转。

转换结果可在epsg.io中对比验证

https://epsg.io/transform#s_srs=3857&t_srs=2334&x=987777.9377800&y=213834.8102400

 

2、但是如果需要其它坐标系的转换,比如要转换成2334,直接使用则会报错

    //EPSG:90013转换成EPSG:4326
    var coorTo4326 = transform([987777.93778,213834.81024], 'EPSG:3857', 'EPSG:4326')
    console.log("EPSG:90013转换成EPSG:4326为");
    console.log(coorTo4326);
    var coorTo3857 = transform(coorTo4326, 'EPSG:4326', 'EPSG:3857')
    console.log("EPSG:4326转换成EPSG:3857为");
    console.log(coorTo3857);
    //无法用ol直接转换
    // var coorTo2334 = transform(coorTo4326, 'EPSG:4326', 'EPSG:2334')
    // console.log("EPSG:4326转换成EPSG:2334为");
    // console.log(coorTo2334);

此时需要借助于proj4.js

3、Vue中使用proj4实现坐标转换

proj4

PROJ是一种通用的坐标转换软件,可以将地理空间坐标从一种坐标参考系(CRS)转换为另一种坐标参考系。

这包括制图投影和大地测量转换。PROJ是在X/MIT开源许可下发布的

PROJ包括命令行应用程序,可以方便地从文本文件或直接从用户输入转换坐标。除了命令行实用程序之外,

PROJ还公开了一个应用程序编程接口,简称API。该API允许开发人员在自己的软件中使用PROJ的功能,

而不必自己实现类似的功能。

PROJ最初纯粹是一个制图应用程序,允许用户使用许多不同的制图投影将大地坐标转换为投影坐标。

多年来,随着需求变得越来越明显,对基准转换的支持也慢慢地在PROJ中发挥作用。

如今,PROJ支持一百多种不同的地图投影,可以使用除了最模糊的大地测量技术之外的所有基准之间的坐标转换。

proj

https://proj.org/index.html

https://github.com/OSGeo/PROJ

proj4js

https://www.npmjs.com/package/proj4

https://trac.osgeo.org/proj4js/wiki/Download

Proj4js是一个JavaScript库,用于将点坐标从一种坐标系转换为另一种坐标系,

包括基准转换。最初是PROJ(当时称为PROJ.4)和GCTCP C (Archive)的一个端口,它是MetaCRS项目组的一部分。

npm安装proj4

npm install proj4 --save

引入模块

import proj4 from 'proj4'
import {register} from 'ol/proj/proj4';

注册和使用

    proj4.defs("EPSG:2334","+proj=tmerc +lat_0=0 +lon_0=117 +k=1 +x_0=20500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m +no_defs ");
    register(proj4);
    var coorTo2334 = transform([987777.93778,213834.81024], 'EPSG:3857', 'EPSG:2334')

 

注意这里的投影字符串如何获取。

proj4的epsg的投影字符串获取:

一种是访问如下

https://spatialreference.org/

点击search,比如这里搜索2334

 

 

点击搜索结果进去之后选择Proj4

 

就能获取到结果

https://spatialreference.org/ref/epsg/2334/proj4/

 

另一种是从epsg网站查询

https://epsg.io/

搜索2334并点进去,拉到下面

 

4、以上示例完整代码

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

<script>
//导入基本模块
import "ol/ol.css";
import Map from "ol/Map";
import View from "ol/View";
//导入相关模块
import { Tile as TileLayer } from 'ol/layer'
import { TileWMS } from 'ol/source'
//引入ol坐标转换模块
import {transform} from 'ol/proj'
//引入proj4
import proj4 from 'proj4'
import {register} from 'ol/proj/proj4';

export default {
  name: "olMapTileWMSTrans",
  data() {
    return {
    };
  },
  mounted() {
    this.initMap();
    //EPSG:90013转换成EPSG:4326
    var coorTo4326 = transform([987777.93778,213834.81024], 'EPSG:3857', 'EPSG:4326')
    console.log("EPSG:90013转换成EPSG:4326为");
    console.log(coorTo4326);
    var coorTo3857 = transform(coorTo4326, 'EPSG:4326', 'EPSG:3857')
    console.log("EPSG:4326转换成EPSG:3857为");
    console.log(coorTo3857);
    //无法用ol直接转换
    // var coorTo2334 = transform(coorTo4326, 'EPSG:4326', 'EPSG:2334')
    // console.log("EPSG:4326转换成EPSG:2334为");
    // console.log(coorTo2334);
    //需借助于proj4
    proj4.defs("EPSG:2334","+proj=tmerc +lat_0=0 +lon_0=117 +k=1 +x_0=20500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m +no_defs ");
    register(proj4);
    var coorTo2334 = transform([987777.93778,213834.81024], 'EPSG:3857', 'EPSG:2334')
    console.log("EPSG:3857 转换成EPSG:2334为");
    console.log(coorTo2334);
  },
  methods: {
    initMap() {
      var image = new TileLayer({
        source: new TileWMS({
          //不能设置为0,否则地图不展示。
          ratio: 1,
          url: "http://localhost:8000/geoserver/nyc/wms",
          params: {
            LAYERS: "nyc:nyc_roads",
            STYLES: "",
            VERSION: "1.1.1",
            FORMAT: "image/png",
          },
          serverType: "geoserver",
        }),
      });

      this.map = new Map({
        //地图容器ID
        target: "map",
        //引入地图
        layers: [image],
        view: new View({
          //地图中心点
          center: [987777.93778, 213834.81024],
          zoom: 12,
          // minZoom:1, // 地图缩放最小级别
        }),
      });
    },
  },
};
</script>

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