openlayers6【四】ol.proj类实现EPSG:3857和EPSG:4326坐标转换

880 阅读4分钟

1. 前言:

EPSG:3857即投影坐标,EPSG:4326即地理坐标。 如果不了解什么是EPSG:3857和EPSG:4326请先看下这篇文章。openlayers6【三】EPSG:3857和EPSG:4326区别详解

ol.proj 类主要实现以下功能,说通俗点就是实现坐标转换的类。

  • 转换为指定的坐标系坐标
  • 坐标系间坐标互相转换
  • 转换Extent为指定坐标系

2. ol.proj类常用方法

下面可以看下这个类里面都有哪些方法(红色方法为常用的方法,方法参数没有写,具体可以查看)。

addCoordinateTransforms 注册坐标转换功能以在源投影和目标投影之间转换坐标。正向和反向函数转换坐标对;该函数将这些转换为内部使用的函数,这些函数还可以处理范围和坐标数组。

addEquivalentProjections 注册不改变坐标的变换函数。这些允许在具有相同含义的投影之间进行转换。

addProjection 将Projection对象添加到可以通过其代码查找的受支持投影列表。

equivalent 检查两个投影是否相同,即一个投影中的每个坐标确实代表与另一个投影中的相同坐标相同的地理点。

get 为指定的代码获取一个Projection对象。

getPointResolution 收集投影的正确分辨率

getTransform 给定类似投影的对象,搜索转换函数以将坐标数组从源投影转换为目标投影。

toLonLat 将坐标转换为经度/纬度。

transformExtent 将范围从源投影转换为目标投影。这将返回一个新范围(并且不会修改原始范围)。

fromLonLat 将坐标从经度/纬度转换为其他投影。

transform 将坐标从源投影转换为目标投影。这将返回一个新坐标(并且不会修改原始坐标)。

3. ol.proj类实际使用

/****************** addCoordinateTransforms使用 *************************/
ol.proj.addCoordinateTransforms("EPSG:4326", "EPSG:3031",
    function(coordinate) {
        return proj4("EPSG:4326","EPSG:3031",coordinate);
    },
    function(coordinate) {
        return proj4("EPSG:3031","EPSG:4326",coordinate);;
    }
);
// 测试
ol.proj.transform([118,32],'EPSG:4326','EPSG:3031');


/****************** addEquivalentProjections使用 *************************/ 
var proj = new ol.proj.Projection({
  code: 'http://www.opengis.net/gml/srs/epsg.xml#4326',
  axis: 'enu',
  getPointResolution(r) {//这个函数非常关键,如果不提供将会导致地图显示比例尺非常大 return r; }
});
ol.proj.addEquivalentProjections([ol.proj.get('EPSG:4326'), proj]);//也可以使用

/****************** addProjection 使用(自定义坐标系) *************************/  
var projection_3031 = new ol.proj.Projection({
    code: 'EPSG:3031',
    extent:[-948.75 -543592.47,5817.41 -3333128.95],
    units: 'm',
    getPointResolution(r) {//这个函数非常关键,如果不提供将会导致地图显示比例尺非常大 return r; }
    axisOrientation: 'neu'
});
ol.proj.addProjection(projection_3031)将新的坐标系统添加进来即可,会自动覆盖原坐标系统

var proj = new ol.proj.Projection({
  code: 'http://www.opengis.net/gml/srs/epsg.xml#4326',
  axis: 'enu',
  getPointResolution(r) {//这个函数非常关键,如果不提供将会导致地图显示比例尺非常大 return r; }
});
ol.proj.addProjection(proj)将新的坐标系统添加进来即可,会自动覆盖原坐标系统

/****************** equivalent 使用  *************************/  
ol.proj.equivalent(map.getView().getProjection(),ol.proj.get('EPSG:3857')

/****************** get 使用  *************************/   
var projection = ol.proj.get('EPSG:3031'); 
var projectionExtent = projection.getExtent();

/****************** getPointResolution 使用  *************************/   

import { METERS_PER_UNIT } from 'ol/proj/Units'

let proj = map.getView().getProjection()
let resolution = map.getView().getResolution
let center = map.getView().getCenter()

const pointResolution = ol.proj.getPointResolution(proj, resolution / 25.4, center, METERS_PER_UNIT.m)
const pointResolution = proj.getPointResolution(resolution, center)

/****************** getTransform 使用  *************************/   
ol.proj.getTransform()

/****************** toLonLat 使用  *************************/   
let proj = map.getView().getProjection()
let lonlat = toLonLat([13507515.248758765, 4192860.8478550767], proj) //  [121.34007398437497, 35.212970997391025] 第二参数默认3857可以不传

/****************** fromLonLat 使用  *************************/   
let coord = fromLonLat([121.34007398437497, 35.212970997391025] ,'EPSG:3857') // 13507515.248758765, 4192860.8478550767  第二参数默认3857可以不传

/****************** transform 使用  *************************/   
ol.proj.transform(coordinate, source, destination)
ol.proj.transform(pos, 'EPSG:4326', 'EPSG:3857')
ol.proj.transform(pos, 'EPSG:3857', 'EPSG:4326')


var center = circle.getCenter() // [13500177.294043388, 4053439.7082629153]
var sourceProj = map.getView().getProjection()  // 'EPSG:3857'
let lonlat1 = transform(center, sourceProj, 'EPSG:4326', 'EPSG:3857')
let lonlat2 = toLonLat(center, sourceProj)
lonlat1 == lonlat2 // true

4. EPSG:4326和EPSG:3857坐标互相转换

使用 transform 转换。ol.proj.transform(coordinate, source, destination)
将坐标从源投影转换为目标投影。这将返回一个新的坐标(并且不会修改原始坐标)。

// 引入
import { transform, get } from "ol/proj";

1:将地理坐标转为投影坐标

//坐标,源投影,目标投影
transform(coordinate, 'EPSG:4326', 'EPSG:3857')

2:将投影坐标转为地理坐标

//坐标,源投影,目标投影
transform(coordinate, 'EPSG:3857', 'EPSG:4326')

如果是 geoJSON数据格式转换,则MultiPolygonPolygon方法可以直接点出transform方法直接转换。

geometry: new MultiPolygon(
    lineData.geometry.coordinates
).transform("EPSG:4326", "EPSG:3857")
//或者
geometry: new Polygon(
	lineData.geometry.coordinates
).transform("EPSG:4326", "EPSG:3857")