Created
September 11, 2021 02:06
-
-
Save HeGanjie/a106a2c90f95d5c1875277b29b87dcd0 to your computer and use it in GitHub Desktop.
自适应坐标转换工具类
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import * as d3Scale from "d3-scale" | |
import _ from "lodash"; | |
export interface MappingInfo { | |
onWindowSize: number[] | |
screenA: number[] | |
geoA: number[] | |
screenB: number[] | |
geoB: number[] | |
} | |
export class Geo2ScreenMapper { | |
mappingInfo: MappingInfo | |
mapperX: Function | |
mapperY: Function | |
constructor(mappingInfo: MappingInfo) { | |
const {screenA, geoA, screenB, geoB, onWindowSize} = mappingInfo | |
// 例如 地图 1920 * 1080 | |
// 662, 323 -> 0.344791667,0.299074074 -> 87.428839,49.077867 | |
// 1044, 833 -> 0.54375,0.771296296 -> 113.23,23.16 | |
const [width, height] = onWindowSize | |
const percentA = [screenA[0] / width, screenA[1] / height] | |
const percentB = [screenB[0] / width, screenB[1] / height] | |
this.mappingInfo = mappingInfo | |
this.mapperX = d3Scale.scaleLinear() | |
.domain([geoA[0], geoB[0]]) | |
.range([percentA[0], percentB[0]]) | |
this.mapperY = d3Scale.scaleLinear() | |
.domain([geoA[1], geoB[1]]) | |
.range([percentA[1], percentB[1]]) | |
} | |
getScreenPos(lngLat: number[]) { | |
const [lng, lat] = lngLat | |
return [this.mapperX(lng), this.mapperY(lat)] | |
} | |
getLngLat(coord: number[]) { | |
const [x, y] = coord | |
return [this.mapperX.invert(x), this.mapperY.invert(y)] | |
} | |
getScreenPosKeepRatio(lngLat: number[]) { | |
const [lng, lat] = lngLat | |
const [originWidth, originHeight] = this.mappingInfo.onWindowSize | |
// oW / oH = cW / (cH * s) | |
// s = cW * oH / oW / cH | |
const s = window.innerWidth * originHeight / originWidth / window.innerHeight; | |
return [ | |
this.mapperX(lng), | |
this.mapperY(lat) * s | |
] | |
} | |
getScreenPosStyleKeepRatio(lngLat: number[]) { | |
if (!lngLat) { | |
return undefined | |
} | |
const [lng, lat] = lngLat | |
const [originWidth, originHeight] = this.mappingInfo.onWindowSize | |
// oW / oH = cW / (cH * s) | |
// s = cW * oH / oW / cH | |
// const s = window.innerWidth * originHeight / originWidth / window.innerHeight; | |
return { | |
left: `${_.round(this.mapperX(lng) * 100, 3)}vw`, | |
// top: `${_.round(this.mapperY(lat) * s * 100, 3)}vh`, | |
top: `${_.round(this.mapperY(lat) * 100 * originHeight / originWidth, 3)}vw` | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment