Projection
projection 的意思是投影,要说投影,需要先从坐标系说起。GIS 中坐标系整体上分为地理坐标系和投影坐标系。
地理坐标系
定义
- 地理坐标系 是基于球体(或椭球体)来描述地球表面位置的坐标系统。
- 它使用 经度(Longitude)和 纬度(Latitude)来表示地球上的位置。
特点
- 单位:经度和纬度的单位是 度(degrees)。
- 参考基准面:通常基于某个参考椭球体,如 WGS84、NAD83 等。
- 坐标范围:
- 纬度:从 90°(南极) 到 +90°(北极)。
- 经度:从 180°(西经) 到 +180°(东经)。
- 三维坐标:有时还包括 高度(Elevation) 或 海拔(Altitude) 信息。
适用场景
- 用于 全球定位系统(GPS) 和 全球地理数据存储。
- 适合表示地球表面上任意位置的精确坐标。
- 常用于 卫星影像、航拍数据 和 地理数据库(如 GeoJSON)。
示例
- 北京市天安门广场的地理坐标为:jsx
(经度, 纬度) = (116.397, 39.908)
常见地理坐标系
- EPSG:4326(WGS84):最常用的全球地理坐标系,广泛应用于 GPS 和 Web 地图(如 OpenStreetMap、Google Earth)。
- EPSG:4269(NAD83):北美常用的地理坐标系。
投影坐标系
定义
- 投影坐标系 是将地球的三维表面投影到二维平面上的坐标系统。
- 它将球面上的经纬度坐标转换为平面上的 X(横坐标) 和 Y(纵坐标)。
特点
- 单位:通常是 米(meters) 或 英尺(feet)。
- 投影算法:基于不同的投影方法(如 墨卡托投影、UTM 投影、兰伯特投影 等)。
- 坐标范围:取决于投影中心和投影区域,适用于特定的地理范围。
- 形变:由于地球是曲面的,而投影是平面,因此会产生不同的 形变(例如面积、形状、距离或方向的失真)。不同的投影算法会尽量减少某一类形变。
适用场景
- 适合 本地地图展示、导航系统 和 工程测量。
- 常用于 城市规划、土地管理 和 精确的平面地图绘制。
- 在 Web 地图应用中,用于提供更直观的平面地图展示(如 Google Maps)。
示例
- 在 EPSG:3857(Web 墨卡托投影)下,北京市天安门广场的坐标大约为:jsx
(X, Y) = (12958071.51, 4844104.53) 米
常见投影坐标系
- EPSG:3857(Web 墨卡托):常用在 Web 地图(如 Google Maps、OpenStreetMap)。
- EPSG:32633(UTM Zone 33N):常用于工程测量,适合狭长的区域。
- EPSG:3395(世界墨卡托):适合展示全球地图,但会有极地区域的变形。
Openlayers 中的坐标系
openlayers 中内置了EPSG:3857
和EPSG:4326
两种坐标系,默认为EPSG:3857
,可以通过以下方式指定地图的视图坐标系:
new View({
projection: "EPSG:4326",
});
EPSG:4326
当指定projection: 'EPSG:4326'
时,表示当前视图中的坐标不经过投影换算,直接以地理坐标系中的坐标值为横坐标和纵坐标在地图上显示,单位为度。这时所有需要坐标的地方只需传入经纬度即可, 例如:
const map = new Map({
target: "map",
layers: [
new TileLayer({
source: new OSM(),
}),
],
view: new View({
center: [109.06450587297525, 34.18640389101999],
zoom: 8,
projection: "EPSG:4326",
}),
});
同时,方法返回值和事件中派发出来的坐标,也是经纬度坐标:
const center = map.getView().getCenter();
// [109.06450587297525, 34.18640389101999]
map.on("click", e => {
console.log(e.coordinate); // 打印鼠标点击位置的经纬度坐标
});
EPSG:3857
当指定projection: 'EPSG:3857'
时,表示当前的视图中的坐标以 WGS84 为基准面,并且经过 Web 墨卡托投影换算,将最终结果在地图上显示,单位为米。这时所有需要坐标的地方,需要将经纬度坐标转换为平面的投影坐标后再使用,例如:
import { fromLonLat } from "ol/proj";
const center = fromLonLat([109.06450587297525, 34.18640389101999]);
// [12141005.257399598, 4053859.061567851]
const map = new Map({
target: "map",
layers: [
new TileLayer({
source: new OSM(),
}),
],
view: new View({
center: center,
zoom: 8,
projection: "EPSG:3857",
}),
});
同时,方法返回值和事件中派发出来的坐标,也是平面投影坐标:
const center = map.getView().getCenter();
// [12141005.257399598, 4053859.061567851]
map.on("click", e => {
console.log(e.coordinate); // 打印鼠标点击位置的平面投影坐标
});
EPSG:4326 与 EPSG:3857 对比
特性 | EPSG:4326 | EPSG:3857 |
---|---|---|
类型 | 地理坐标系(经纬度) | 投影坐标系(Web 墨卡托) |
基准面 | WGS84 | WGS84 |
单位 | 度(degrees) | 米(meters) |
适用范围 | 全球 | 全球(但极地区域有变形) |
应用 | GPS 定位,存储原始地理数据 | Web 地图(如 Google Maps, OpenStreetMap) |
EPSG:4490
EPSG:4490 是我国使用的一种 地理坐标系,它基于 CGCS2000(China Geodetic Coordinate System 2000,中国大地坐标系 2000)椭球模型。它与全球广泛使用的 EPSG:4326 (WGS84) 类似,但针对中国地区进行了优化。
CGCS2000(China Geodetic Coordinate System 2000) 是我国于 2000 年发布的国家级地理坐标系,旨在替代之前使用的 北京 54 坐标系 和 西安 80 坐标系。CGCS2000 基于 ITRF(国际地球参考框架) 系统,并使用了与 WGS84 十分接近的椭球体模型,但在一些参数上进行了微调,以更准确地适应中国大陆的地理特征。
EPSG:4490 的定义
- 名称:China Geodetic Coordinate System 2000(CGCS2000)
- EPSG 编码:4490
- 基准椭球:CGCS2000 椭球(非常接近 WGS84 椭球)
- 坐标系类型:地理坐标系(Geographic Coordinate System, GCS)
- 坐标单位:度(degrees)
- 坐标格式:
- 经度(Longitude):范围为 180° 到 +180°
- 纬度(Latitude):范围为 90° 到 +90°
EPSG:4490 与 EPSG:4326 的区别
特性 | EPSG:4326 (WGS84) | EPSG:4490 (CGCS2000) |
---|---|---|
椭球基准 | WGS84 | CGCS2000 |
适用范围 | 全球 | 中国及周边区域 |
坐标单位 | 度(degrees) | 度(degrees) |
使用场景 | GPS、全球地理数据 | 中国国家标准测绘、导航、GIS 系统 |
引入时间 | 1984 年(国际通用) | 2000 年(中国制定) |
在 openlayers 中使用 EPSG:4490
openlayers 本身没有 EPSG:4490 坐标系,但是我们可以通过 proj4 扩展。坐标系的具体参数可以通过 https://epsg.io/4490 获取。
安装 proj4 库
npm install proj4
proj.js
import proj4 from "proj4";
import { register } from "ol/proj/proj4";
import { Projection, addProjection, addCoordinateTransforms } from "ol/proj";
proj4.defs("EPSG:4490", "+proj=longlat +ellps=GRS80 +no_defs");
register(proj4);
const projection = new Projection({
code: "EPSG:4490",
units: "degrees",
extent: [-180, -90, 180, 90],
});
addProjection(projection);
// 扩展transform方法中EPSG:4326和EPSG:4490的互转
addCoordinateTransforms(
"EPSG:4326",
"EPSG:4490",
function (coordinate) {
return proj4("EPSG:4326", "EPSG:4490", coordinate);
},
function (coordinate) {
return proj4("EPSG:4490", "EPSG:4326", coordinate);
}
);
main.js
import "ol/ol.css";
import Map from "ol/Map.js";
import OSM from "ol/source/OSM.js";
import TileLayer from "ol/layer/Tile.js";
import View from "ol/View.js";
import "./proj";
const map = new Map({
target: "map",
layers: [
new TileLayer({
source: new OSM(),
}),
],
view: new View({
center: [116.397, 39.908],
zoom: 3,
projection: "EPSG:4490",
}),
});