投影
坐标系转换
点我查看代码
vue
<script lang="ts" setup>
import { EPSG_3857ToEPSG_4326, EPSG_4326ExtentToEPSG_3857, EPSG_4326ToEPSG_3857, EPSG_3857ExtentToEPSG_4326, createTileGrid, registerEPSG_3395 } from '@summeruse/ol'
import { NButton, NFormItem, NInputNumber } from 'naive-ui'
import { computed, ref } from 'vue'
// 坐标转换
const coord = ref([116.404, 39.915])
const mercator = computed(() => EPSG_4326ToEPSG_3857(coord.value))
const mercator2 = ref([12959638.8957, 4855982.5492])
const coord2 = computed(() => EPSG_3857ToEPSG_4326(mercator2.value))
// 范围转换
const bbox = computed(() => {
const [lon, lat] = coord.value
const d = 0.5
return [lon - d, lat - d, lon + d, lat + d] as [number, number, number, number]
})
const mercatorBbox = computed(() => EPSG_4326ExtentToEPSG_3857(bbox.value))
const backBbox = computed(() => EPSG_3857ExtentToEPSG_4326(mercatorBbox.value))
// 注册 EPSG:3395
const registered = ref(false)
function doRegister() {
registerEPSG_3395()
registered.value = true
}
// 创建 TileGrid
const tileGridInfo = computed(() => {
const grid = createTileGrid('EPSG:3395')
if (!grid) return '未注册 EPSG:3395,请先点击注册'
return `TileSize: ${grid.getTileSize(0)}, Extent: [${grid.getExtent().join(', ')}]`
})
</script>
<template>
<NFormItem label="WGS84坐标转墨卡托">
<NInputNumber v-model:value="coord[0]" :step="0.1" /> 经度
<NInputNumber v-model:value="coord[1]" :step="0.1" /> 纬度
</NFormItem>
<NFormItem label="=">
<span> {{ mercator[0] }} , {{ mercator[1] }} </span>
</NFormItem>
<NFormItem label="墨卡托转WGS84">
<NInputNumber v-model:value="mercator2[0]" :step="0.1" /> x
<NInputNumber v-model:value="mercator2[1]" :step="0.1" /> y
</NFormItem>
<NFormItem label="=">
<span> {{ coord2[0] }} , {{ coord2[1] }} </span>
</NFormItem>
<NFormItem label="范围转换">
<span>4326 bbox: [{{ bbox.join(', ') }}]</span>
</NFormItem>
<NFormItem label="→ 3857">
<span>[{{ mercatorBbox.map(v => v.toFixed(0)).join(', ') }}]</span>
</NFormItem>
<NFormItem label="→ 4326 回转换">
<span>[{{ backBbox.map(v => v.toFixed(4)).join(', ') }}]</span>
</NFormItem>
<NFormItem label="EPSG:3395">
<NButton :disabled="registered" @click="doRegister">
{{ registered ? '已注册' : '注册 EPSG:3395' }}
</NButton>
</NFormItem>
<NFormItem label="TileGrid">
<span>{{ tileGridInfo }}</span>
</NFormItem>
</template>API
坐标转换
| 名称 | 类型 | 说明 |
|---|---|---|
| EPSG_4326ToEPSG_3857 | (coordinate: Coordinate) => Coordinate | EPSG:4326 坐标转 EPSG:3857 |
| EPSG_3857ToEPSG_4326 | (coordinate: Coordinate) => Coordinate | EPSG:3857 坐标转 EPSG:4326 |
范围转换
| 名称 | 类型 | 说明 |
|---|---|---|
| EPSG_4326ExtentToEPSG_3857 | (extent: Extent) => Extent | EPSG:4326 范围转 EPSG:3857 |
| EPSG_3857ExtentToEPSG_4326 | (extent: Extent) => Extent | EPSG:3857 范围转 EPSG:4326 |
其他
| 名称 | 类型 | 说明 |
|---|---|---|
| registerEPSG_3395 | () => void | 注册 EPSG:3395 椭球墨卡托投影(通过 proj4),重复调用不生效 |
| createTileGrid | (ProjectionLike?: Projection | string) => XYZTileGrid | undefined | 根据投影创建 TileGrid,当前支持 EPSG:3395 |
| proj4 | typeof proj4 | 直接导出 proj4 实例,用于自定义投影注册 |
源代码
点我查看代码
ts
import type { Coordinate } from 'ol/coordinate'
import type { Extent } from 'ol/extent'
import type { Projection } from 'ol/proj'
import { get as getProjection, transform, transformExtent } from 'ol/proj'
import { register } from 'ol/proj/proj4'
import { createXYZ } from 'ol/tilegrid'
import proj4 from 'proj4'
import { EPSG_3395, EPSG_3857, EPSG_4326 } from '../../constants'
/** EPSG_4326转EPSG_3857 */
export function EPSG_4326ToEPSG_3857(coordinate: Coordinate) {
return transform(coordinate, EPSG_4326, EPSG_3857)
}
/** EPSG_3857转EPSG_4326 */
export function EPSG_3857ToEPSG_4326(coordinate: Coordinate) {
return transform(coordinate, EPSG_3857, EPSG_4326)
}
/** EPSG_4326范围转EPSG_3857 */
export function EPSG_4326ExtentToEPSG_3857(extent: Extent) {
return transformExtent(extent, EPSG_4326, EPSG_3857)
}
/** EPSG_3857范围转EPSG_4326 */
export function EPSG_3857ExtentToEPSG_4326(extent: Extent) {
return transformExtent(extent, EPSG_3857, EPSG_4326)
}
export function registerEPSG_3395() {
if (getProjection(EPSG_3395)) {
return
}
proj4.defs(
'EPSG:3395',
// cSpell:disable-next-line
'+proj=merc +lon_0=0 +k=1 +x_0=0 +y_0=0 ' + '+datum=WGS84 +units=m +no_defs +type=crs',
)
register(proj4)
}
export function createTileGrid(ProjectionLike?: Projection | string) {
if (ProjectionLike === EPSG_3395) {
registerEPSG_3395()
return createXYZ({
extent: [-20037508.3427892, -20037508.3427892, 20037508.3427892, 20037508.3427892],
})
}
}
export { proj4 }