1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980 |
- import proj4 from "proj4";
- // 屏幕点和真实点通用对象
- type Pos = [number, number, number];
- type Conversion = {
- scale: number;
- rotation: number;
- translate: number[];
- startAltitude: number[];
- altitude: number;
- };
- // 获取角度
- const getAngle = (p1: Pos, p2: Pos) => Math.atan2(p2[0] - p1[0], p2[1] - p1[1]);
- // 获取长度
- const getLength = (p1: Pos, p2: Pos) =>
- Math.sqrt(Math.pow(p2[0] - p1[0], 2) + Math.pow(p2[1] - p1[1], 2));
- // 获取本地与魔卡托的映射关系
- const getConversion2D = ([p1, p2]: Pos[], [b1, b2]: Pos[]) => {
- const rotation = getAngle(p1, p2) - getAngle(b1, b2);
- const scale = getLength(b1, b2) / getLength(p1, p2);
- const translate = [
- b1[0] - scale * (p1[0] * Math.cos(rotation) - p1[1] * Math.sin(rotation)),
- b1[1] - scale * (p1[0] * Math.sin(rotation) + p1[1] * Math.cos(rotation)),
- ];
- const altitude = (b2[2] - b1[2]) / (p2[2] - p1[2]);
- const startAltitude = [p1[2], b1[2]];
- return {
- rotation,
- scale,
- translate,
- startAltitude,
- altitude,
- };
- };
- const transform = (point: Pos, cover: Conversion): Pos => {
- const ctrla = cover.scale * Math.cos(cover.rotation);
- const ctrlb = cover.scale * Math.sin(cover.rotation);
- return [
- ctrla * point[0] - ctrlb * point[1] + cover.translate[0],
- ctrlb * point[0] + ctrla * point[1] + cover.translate[1],
- cover.altitude * (point[2] - cover.startAltitude[0]) +
- cover.startAltitude[1],
- ];
- };
- const wCoordType = "EPSG:4326";
- const tCoordType = "EPSG:3857";
- proj4.defs(wCoordType, "+proj=longlat +ellps=GRS80 +no_defs");
- proj4.defs(
- tCoordType,
- "+proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs +type=crs"
- );
- // 传入本地坐标与控制点的关系
- export const conversionFactory = (locals: [Pos, Pos], gpss: [Pos, Pos]) => {
- const maps = gpss.map((pos) => proj4(wCoordType, tCoordType, pos));
- const coverLocalToWeb = getConversion2D(locals, maps);
- const coverWebToLocal = getConversion2D(maps, locals);
- return {
- toLocal(pos: Pos): Pos {
- const tPos = transform(
- proj4(wCoordType, tCoordType, [...pos]),
- coverWebToLocal
- );
- return tPos;
- },
- toWGS84(pos: Pos): Pos {
- const tPos = transform(pos, coverLocalToWeb);
- const wPos = proj4(tCoordType, wCoordType, [...tPos]);
- return [wPos[0], wPos[1], tPos[2]];
- },
- };
- };
|