Skip to content

Instantly share code, notes, and snippets.

@HeGanjie
Created September 11, 2021 02:06
Show Gist options
  • Save HeGanjie/a106a2c90f95d5c1875277b29b87dcd0 to your computer and use it in GitHub Desktop.
Save HeGanjie/a106a2c90f95d5c1875277b29b87dcd0 to your computer and use it in GitHub Desktop.
自适应坐标转换工具类
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