--- title: Openlayers投影与坐标转换 date: 2020-12-25 author: ac sidebar: false tags: - Openlayers categories: - GIS --- ## 投影 在初始化`map`实例时,如果不在`view`中用`projection`参数指定投影坐标系,则将会使用默认的空间参考`EPSG:3857`(Web 墨卡托投影)。后续叠加的图层,都会将数据进行投影转换,确保`map`在同一个空间参考内。 > `EPSG`(European Petroleum Survey Group,欧洲石油调查组织)负责维护并发布坐标参照系统的数据集参数,以及坐标转换描述。它将已有的椭球体,投影坐标系等及其不同组合都对应着不同的ID号,这个号在`EPSG`中被称为`EPSG code`,它代表特定的椭球体、单位、地理坐标系或投影坐标系等信息。 `Openlayers`中的指定空间参考可以直接使用`EPSG code`指定,如`EPSG:4326`,因为`ol.proj.Projection`已经帮我们定义好`EPSG:4326`和`EPSG:3857`这两个空间参考的参数,同时也为这两个空间参考定义了一些别名,如`EPSG:3857`的`EPSG:102100`、`EPSG:102113`、`EPSG:900913`这些曾用名,也有用于识别`GML`要素的` http://www.opengis.net/gml/srs/epsg.xml#3857`和`urn:ogc:def:crs:EPSG:6.18:3:3857`。 空间参考的别名可以使用`proj4js`的`defs()`方法添加: ```javascript proj4.defs('urn:x-ogc:def:crs:EPSG:4326', proj4.defs('EPSG:4326')); ``` `ol`对于其他空间参考,可以使用`proj4js`进行自定义。`defs()`方法定义,`register()`方法进行注册。 > `proj4js`是一个JavaScript库,是一个强大的通用坐标转换引擎,可以同时进行大规模地图投影和高精密度的坐标转换。 ```javascript proj4.defs( 'EPSG:21781', '+proj=somerc +lat_0=46.95240555555556 +lon_0=7.439583333333333 +k_0=1 ' + '+x_0=600000 +y_0=200000 +ellps=bessel ' + '+towgs84=660.077,13.551,369.344,2.484,1.783,2.939,5.66 +units=m +no_defs' ); register(proj4); ``` 自定义的投影必须是在[https://epsg.io/](https://epsg.io/)可以找到的才有效。 ![image-20201221151526367](./images/image-20201221151526367.png) ![image-20201221151927037](./images/image-20201221151927037.png) **常用参数列表**: | 参数 | 描述 | | :-------- | ------------------------------------------------------------ | | +proj | 投影名称,安装`proj`后可以使用`proj - l `命令查看支持的投影名称 | | +lat_0 | 维度起点 | | +lon_0 | 中央经线 | | +x_0 | 东(伪)偏移量 | | +y_0 | 北(伪)偏移量 | | +ellps | 椭球体名称,使用`proj -le` 命令查看支持哪些椭球体 | | +units | 水平单位,meters(米)。使用`proj -lu `命令查看`PROJ`支持的单位 | | +lat_ts | 有效纬度范围 | | +a | 椭球体长半轴长度 | | +b | 椭球体短半轴长度 | | +k | 比例系数(比例因子),旧版本,不赞成使用 | | +k_0 | 比例系数(比例因子) | | +vunits | 垂直单位 | | +datum | 基准面名称,使用`proj -ld`命令查看支持的基准面 | | +towgs84 | 3参数或7参数基面转换 | | +to_meter | 将水平单位转换为米计算输出转换参数,如:1英尺= | | +no_defs | 不要使用`proj`库中的缺省定义文件。 | 下面使用`OSM`地图作为示例图层,定义`CGCS2000`的空间参考。 ```html OpenLayers example

Projection CGCS2000(EPSG:4490)

``` 可以将瓦片图层`SOM`当做底图,再往上叠加图层。 ## 坐标转换 对于矢量数据可以使用`ol.proj`命名空间下的方法,在客户端进行坐标转换,如: ```javascript //将坐标coordinate从“EPSG:3857”转换到“EPSG:4490” ol.proj.transform([12686109.88955285,2572810.705991532],"EPSG:3857","EPSG:4490"); //添加坐标转换函数 ol.proj.addCoordinateTransforms("EPSG:3857","EPSG:4490",function (coordinate) { return proj4("EPSG:3857","EPSG:4490",coordinate); },function (coordinate) { return proj4("EPSG:4490","EPSG:3857",coordinate); }) //将经纬度的coordinate转换到目标空间参考下的坐标,默认是EPSG:3857 ol.proj.fromLonLat([113.958334, 22.535640],cgcs2000) //将coordinate转换成经纬度 ol.proj.toLonLat([12686109.88955285,2572810.705991532]) ``` 上述是对单个coordinate的转换,对于几何要素Geometry及其子类(点、线、面等)可以使用`ol.geom.Geometry`中的`transform()`方法转换几何对象中的每组坐标。像`GeoJSON`、`KML`、`gpx`类型的文件可以选择在解析器解析完成得到要素集合后,对每个要素进行转化。 示例: ```html OpenLayers example

Projection CGCS2000(EPSG:4490)

``` ![projection4490](./images/projection4490.png) `test.json`数据文件 ```json { "type": "FeatureCollection", "crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:EPSG:3857" } }, "features": [ { "type": "Feature", "properties": {}, "geometry": { "type": "Point", "coordinates": [ 12686109.88955285, 2572810.705991532 ] } }, { "type": "Feature", "properties": {}, "geometry": { "type": "Point", "coordinates": [ 12683644.795390654, 2568835.9805207034 ] } }, { "type": "Feature", "properties": {}, "geometry": { "type": "LineString", "coordinates": [ [ 12673134.704001442, 2577473.364716928 ], [ 12671453.089379169, 2571625.932053112 ], [ 12689186.479941329, 2580358.8625346934 ], [ 12677606.270156125, 2580435.2995629786 ] ] } } ] } ``` 对于服务类型的数据,像`WFS`、`WMS`服务可以在请求中使用`srsname`或`CRS`参数指定返回要素的空间参考,将坐标转换的工作在服务端完成。 示例: ```html OpenLayers example

Projection:加载GeoServer的WFS服务

``` ![exmaple01](./images/exmaple01.png) ```javascript var map = new ol.Map({ layers: [ new ol.layer.Tile({ source: new ol.source.OSM() }), new ol.layer.Tile({ source: new ol.source.TileWMS({ url: 'http://localhost:8080/geoserver/tiger/ows', params: { //WIDTH, HEIGHT, BBOX and CRS (SRS for WMS version < 1.3.0) 将被动态设置. 'LAYERS': 'tiger:tiger_roads', 'TILED': false, 'VERSION':'1.1.0', 'TRANSPARENT':true,// 'CRS':"EPSG:4490" }, //远程WMS服务器的类型 serverType: 'geoserver', // 用于渲染的不透明度过渡的持续时间。要禁用不透明过渡,设置transition为: 0 transition: 0 }) }) ], target: document.getElementById('map'), view: new ol.View({ center: nyc, maxZoom: 19, zoom: 12, projection: cgcs2000 }) }); ``` ![example03](./images/example03.png)