https://www.freesion.com/article/1751396517/
有个项目需要使用openlayer加载各种服务上发布的数据,坐标系也不同,我们都知道openalyer默认可以加载EPAG:3857,要加载4490的坐标系的数据需要重新定义一下,之后再加载。一想起要重新定义坐标系感觉很难,就想放弃,其实静下心了做一下也没那么难。在此做个简单的记录,要加载的数据如下:
1.3结果 加载好天地图、4490arcgisserver 服务、本地影像切片
使用proj4js 给所有坐标和范围提供视图投影系(默认是EPAG:3857),给每个要加载的图层设置此坐标系即可正常加载。
(1).API OpenLayers v7.4.0 API
(2)epsg EPSG.io: Coordinate Systems Worldwide
了解有关各种投影的参数定义
(3)proj4js proj4js (v2.9.0) https://www.bootcdn.cn/proj4js/
(1)proj4引用 前端添加Proj4js有三种方式:
(2)基础使用
proj4.js中预定义了三个坐标系,其他的坐标系则需要自己定义了,下面以从WGS84(4326)到Web墨卡托(3857)的转换为例
function Wgs84ToMector2(lat,lng) {
const proj4 = require('proj4');
return proj4(proj4('EPSG:4326'), proj4('EPSG:3857'), [lng, lat])
}
定义坐标系:
function init4490(){
proj4.defs("EPSG:4490","+proj=longlat +ellps=GRS80 +no_defs +type=crs");
//4490的坐标系注册进openlayer的projection中
register(proj4);
//重写projection4490,地图投影
var projection = new Projection({
code: 'EPSG:4490',
units: 'degrees',
axisOrientation: 'neu'
});
addProjection(projection);
projection.setExtent([-180, -90, 180, 90]);
projection.setWorldExtent([-180, -90, 180, 90]);
projection.getMetersPerUnit = function(){
return 2 * Math.PI * 6378137 / 360;
};
addCoordinateTransforms( "EPSG:4326","EPSG:4490", function( coordinate){
return proj4("EPSG:4490", "EPSG:4326",coordinate);},
function(coordinate){
return proj4("ERSG:4490" , "EPSG:4326" , coordinate);
}
);
}
其中 proj4.defs("EPSG:4490","+proj=longlat +ellps=GRS80 +no_defs +type=crs");是从epsg的网站上获取的参数,如下图:【输入4490坐标系】---【选择proj4js】---【复制】即可。
定义好4490坐标系后,需要注册和重写projection
function getWMTSLayer(options) {
const projections = options.projection?options.projection:projection4326;
const res = getResolutionsAndMids(projections);
return new TileLayer({
source: new WMTS({
name: "中国",
url: options.url,
layer: options.layer, // 图层名
version: '1.0.0',// WMTS版本
style: options.style?options.style:"default",
matrixSet: options.matrixSet?options.matrixSet:"c", // 投影坐标系矩阵集,一定要和WMTS capabilities文档中一致,否则会加载失败
format: options.format?options.format:"tiles", // 图片格式
wrapX: true,
tileGrid: new WMTSTileGrid({// 投影坐标系
origin: getTopLeft(projections.getExtent()),
resolutions: res.resolutions,
matrixIds: res.matrixIds,
}),
projection: projections // 投影坐标系
}),
})
}
function getXYZLayer(options) {
const projections = options.projection?options.projection:projection4326;
return new TileLayer({
title: '泾阳',
source: new XYZ({
url: options.url,
projection: projections
})
})
}
在 openlayer 中,图层是使用 layer 对象表示的,主要有 WebGLPoints Layer、 热度图(HeatMap Layer)、图片图层(lmage Layer)、切片图层(Tile Layer)和 矢量图层(Vector Layer)五种类型,它们都是继承 Layer 类的。
常用参数
找到新建Map对象的时候,调整layers的顺序,layer越往右,图层越往上显示。
var layer = new Vector({
source: new Vector({
projection: 'EPSG:4326',
format: new GeoJSON()
}),
style: styleFunction,
zIndex:9999
});
openalyer.vue
#map
map.js
import {register} from 'ol/proj/proj4'
import {Projection,addProjection,addCoordinateTransforms,get} from 'ol/proj';
import TileLayer from 'ol/layer/Tile.js';
import {WMTS,XYZ} from 'ol/source.js';
import WMTSTileGrid from 'ol/tilegrid/WMTS.js';
import {getWidth,getTopLeft} from 'ol/extent';
import proj4 from 'proj4';
function init4490(){
proj4.defs("EPSG:4490","+proj=longlat +ellps=GRS80 +no_defs +type=crs");
//4490的坐标系注册进openlayer的projection中
register(proj4);
//重写projection4490,地图投影
var projection = new Projection({
code: 'EPSG:4490',
units: 'degrees',
axisOrientation: 'neu'
});
addProjection(projection);
projection.setExtent([-180, -90, 180, 90]);
projection.setWorldExtent([-180, -90, 180, 90]);
projection.getMetersPerUnit = function(){
return 2 * Math.PI * 6378137 / 360;
};
addCoordinateTransforms( "EPSG:4326","EPSG:4490", function( coordinate){
return proj4("EPSG:4490", "EPSG:4326",coordinate);},
function(coordinate){
return proj4("ERSG:4490" , "EPSG:4326" , coordinate);
}
);
}
init4490()
//transform([118,32] , 'EPSG:4326' , 'EPSG:4490 ');
const projection4490 = new get('EPSG:4490' );
const projection4326 = new get('EPSG:4326' );
const projection3857 = new get('EPSG:3857' );
function getResolutionsAndMids(projection) {
const projections = projection?projection:projection4326;
let projectionExtent = projections.getExtent();
let size = getWidth(projectionExtent) / 256; //size就是一个像素代表的经纬度
let matrixIds = [];
let resolutions = [];
for (let z = 0; z < 20; ++z) {
resolutions[z] = size / Math.pow(2, z);
matrixIds[z] = z;
}
return {"resolutions":resolutions,"matrixIds":matrixIds};
}
export function getProjection() {
return projection4490
}
// WMTS 形式
function getWMTSLayer(options) {
const projections = options.projection?options.projection:projection4326;
const res = getResolutionsAndMids(projections);
return new TileLayer({
source: new WMTS({
name: "中国",
url: options.url,
layer: options.layer, // 图层名
version: '1.0.0',// WMTS版本
style: options.style?options.style:"default",
matrixSet: options.matrixSet?options.matrixSet:"c",
// 投影坐标系矩阵集,一定要和WMTS capabilities文档中一致,否则会加载失败
format: options.format?options.format:"tiles", // 图片格式
wrapX: true,
tileGrid: new WMTSTileGrid({// 投影坐标系
origin: getTopLeft(projections.getExtent()),
resolutions: res.resolutions,
matrixIds: res.matrixIds,
}),
projection: projections // 投影坐标系
}),
})
}
function getXYZLayer(options) {
const projections = options.projection?options.projection:projection4326;
return new TileLayer({
title: '泾阳',
source: new XYZ({
url: options.url,
projection: projections
})
})
}
const key ='b9031f80391e6b65bd1dd80dcde1b097';
/**
\* 矢量底图 + 矢量注记
*/
export function vec_c() {
return [
getWMTSLayer({"url":'http://t{0-7}.tianditu.gov.cn/vec_c/wmts?tk=' + key, "layer":'vec',"projection":projection4490}),
getWMTSLayer({"url":'http://t{0-7}.tianditu.gov.cn/cva_c/wmts?tk=' + key, "layer":'cva',"projection":projection4490}),
]
}
/**
\* 影像底图 + 影像注记
*/
export function img_c() {
return [
// getWMTSLayer({"url":'http://t{0-7}.tianditu.gov.cn/img_c/wmts?tk=' + key, "layer":'img',"projection":projection4490}), getXYZLayer({"url":'https://xxxx/jingyang/imgyx/jyx/{z}/{x}/{y}.png',"projection":projection3857}),
getWMTSLayer({"url":'http://xxxx:6080/arcgis/rest/services/jingyang/jingyang1/MapServer/WMTS?',"layer":'jingyang_jingyang1',"projection":projection4490}),
getWMTSLayer({"url":'http://t{0-7}.tianditu.gov.cn/cia_c/wmts?tk=' + key, "layer":'cia'}),
// getXYZLayer({"url":'http://xxxx:6080/arcgis/rest/services/jingyang/jingyang1/MapServer/tiles/{z}/{x}/{y}.png',"projection":projection4490}),
]
}
/**
\* 地形底图 + 地形注记
*/
export function ter_c() {
return [
getWMTSLayer({"url":'http://t{0-7}.tianditu.gov.cn/ter_c/wmts?tk=' + key, "layer":'ter',"projection":projection4490}),
getWMTSLayer({"url":'http://t{0-7}.tianditu.gov.cn/cta_c/wmts?tk=' + key, "layer":'cta',"projection":projection4490}),
]
}
source 是 Layer 的重要组成部分,表示图层的来源,也就是服务地址。除了在构造函数中制定外,可以使用 layer.setSource(source) 稍后指定。
基类(不能被实例化,只负责被继承):
可以实例化的类:
(1)ol.proj.addCoordinateTransforms(source, destination, forward, inverse)
注册坐标转换函数来转换源投影和目标投影之间的坐标。正、反函数转换坐标对;此函数将这些转换为内部使用的处理区段和坐标数组的函数
source:源投影
destination:目标投影
forward:接受ol的正向变换函数(即从源投影到目标投影)。作为参数,并返回转换后的ol.Coordinate
inverse:接受ol的逆变换函数(即从目标投影到源投影)。作为参数,并返回转换后的ol.Coordinate
(2)ol.proj.addEquivalentProjections(projections)
注册不改变坐标的转换函数。它们允许在具有相同含义的投影之间进行转换。
(3)ol.proj.addProjection(projection)
将投影对象添加到受支持的投影列表中,这些投影可以通过它们的SRS码进行查找。
(4)ol.proj.equivalent(projection1, projection2)
检查两个投影是否相同,即一个投影中的每个坐标确实表示另一个投影中的相同地理点。
(5)ol.proj.fromLonLat(coordinate, opt_projection)
将经纬度坐标转换为不同的投影
coordinate:经纬度数组,经度在前,纬度在后
projection:目标投影。默认是Web Mercator,即“EPSG: 3857”
(6)ol.proj.get(projectionLike)
获取指定代码的投影对象。
(7)ol.proj.getTransform(source, destination)
给定类似于投影的对象,搜索转换函数将坐标数组从源投影转换为目标投影。
(8)ol.proj.setProj4(proj4)
proj4注册。如果没有显式注册,则假定proj4js将加载在全局名称空间中
ol.proj.setProj4(proj4);
(9)ol.proj.toLonLat(coordinate, opt_projection)
将坐标转换为经度/纬度
coordinate:投影坐标
projection:坐标的投影,默认是Web Mercator,即“EPSG: 3857”
(10)ol.proj.transform(coordinate, source, destination)
将坐标从源投影转换为目标投影,这将返回一个新的坐标(并且不修改原始坐标)。
coordinate:坐标
source:源投影
destination:目标投影
(11)ol.proj.transformExtent
将范围从源投影转换为目标投影,这将返回一个新范围(并且不修改原始范围)。
(12)ol.proj.Units{string}
投影单位:'degrees', 'ft', 'm', 'pixels', 'tile-pixels' or 'us-ft'
开源GIS(二)——openlayers加载Arcgis和geoserver在线离线切片 - 灰信网(软件开发博客聚合)