|
|
@@ -3,7 +3,7 @@ import { CompassHeadingController } from '../sensor/compassHeadingController'
|
|
|
import { LocationController } from '../sensor/locationController'
|
|
|
import { WebGLMapRenderer } from '../renderer/webglMapRenderer'
|
|
|
import { type MapRendererStats } from '../renderer/mapRenderer'
|
|
|
-import { gcj02ToWgs84, lonLatToWorldTile, worldTileToLonLat, type LonLatPoint } from '../../utils/projection'
|
|
|
+import { lonLatToWorldTile, worldTileToLonLat, type LonLatPoint, type MapCalibration } from '../../utils/projection'
|
|
|
import { isTileWithinBounds, type RemoteMapConfig, type TileZoomBounds } from '../../utils/remoteMapConfig'
|
|
|
|
|
|
const RENDER_MODE = 'Single WebGL Pipeline'
|
|
|
@@ -21,6 +21,14 @@ const DEFAULT_TOP_LEFT_TILE_Y = 51199
|
|
|
const DEFAULT_CENTER_TILE_X = DEFAULT_TOP_LEFT_TILE_X + 1
|
|
|
const DEFAULT_CENTER_TILE_Y = DEFAULT_TOP_LEFT_TILE_Y + 1
|
|
|
const TILE_SOURCE = 'https://oss-mbh5.colormaprun.com/wxMap/lcx/{z}/{x}/{y}.png'
|
|
|
+const OSM_TILE_SOURCE = 'https://tiles.mymarsgo.xyz/{z}/{x}/{y}.png'
|
|
|
+const MAP_OVERLAY_OPACITY = 0.72
|
|
|
+const GPS_MAP_CALIBRATION: MapCalibration = {
|
|
|
+ offsetEastMeters: 0,
|
|
|
+ offsetNorthMeters: 0,
|
|
|
+ rotationDeg: 0,
|
|
|
+ scale: 1,
|
|
|
+}
|
|
|
const MIN_PREVIEW_SCALE = 0.55
|
|
|
const MAX_PREVIEW_SCALE = 1.85
|
|
|
const INERTIA_FRAME_MS = 16
|
|
|
@@ -114,6 +122,8 @@ export interface MapEngineViewState {
|
|
|
gpsTracking: boolean
|
|
|
gpsTrackingText: string
|
|
|
gpsCoordText: string
|
|
|
+ osmReferenceEnabled: boolean
|
|
|
+ osmReferenceText: string
|
|
|
}
|
|
|
|
|
|
export interface MapEngineCallbacks {
|
|
|
@@ -158,6 +168,8 @@ const VIEW_SYNC_KEYS: Array<keyof MapEngineViewState> = [
|
|
|
'gpsTracking',
|
|
|
'gpsTrackingText',
|
|
|
'gpsCoordText',
|
|
|
+ 'osmReferenceEnabled',
|
|
|
+ 'osmReferenceText',
|
|
|
]
|
|
|
|
|
|
function buildCenterText(zoom: number, x: number, y: number): string {
|
|
|
@@ -524,6 +536,8 @@ export class MapEngine {
|
|
|
gpsTracking: false,
|
|
|
gpsTrackingText: '持续定位待启动',
|
|
|
gpsCoordText: '--',
|
|
|
+ osmReferenceEnabled: false,
|
|
|
+ osmReferenceText: 'OSM参考:关',
|
|
|
}
|
|
|
this.previewScale = 1
|
|
|
this.previewOriginX = 0
|
|
|
@@ -575,7 +589,7 @@ export class MapEngine {
|
|
|
|
|
|
|
|
|
handleLocationUpdate(longitude: number, latitude: number, accuracyMeters: number | null): void {
|
|
|
- const nextPoint: LonLatPoint = gcj02ToWgs84({ lon: longitude, lat: latitude })
|
|
|
+ const nextPoint: LonLatPoint = { lon: longitude, lat: latitude }
|
|
|
const lastTrackPoint = this.currentGpsTrack.length ? this.currentGpsTrack[this.currentGpsTrack.length - 1] : null
|
|
|
if (!lastTrackPoint || getApproxDistanceMeters(lastTrackPoint, nextPoint) >= GPS_TRACK_MIN_STEP_METERS) {
|
|
|
this.currentGpsTrack = [...this.currentGpsTrack, nextPoint].slice(-GPS_TRACK_MAX_POINTS)
|
|
|
@@ -612,6 +626,16 @@ export class MapEngine {
|
|
|
this.syncRenderer()
|
|
|
}
|
|
|
|
|
|
+ handleToggleOsmReference(): void {
|
|
|
+ const nextEnabled = !this.state.osmReferenceEnabled
|
|
|
+ this.setState({
|
|
|
+ osmReferenceEnabled: nextEnabled,
|
|
|
+ osmReferenceText: nextEnabled ? 'OSM参考:开' : 'OSM参考:关',
|
|
|
+ statusText: nextEnabled ? `OSM参考底图已开启 (${this.buildVersion})` : `OSM参考底图已关闭 (${this.buildVersion})`,
|
|
|
+ }, true)
|
|
|
+ this.syncRenderer()
|
|
|
+ }
|
|
|
+
|
|
|
handleToggleGpsTracking(): void {
|
|
|
if (this.locationController.listening) {
|
|
|
this.locationController.stop()
|
|
|
@@ -1364,11 +1388,15 @@ export class MapEngine {
|
|
|
}
|
|
|
|
|
|
buildScene() {
|
|
|
+ const exactCenter = this.getExactCenterFromTranslate(this.state.tileTranslateX, this.state.tileTranslateY)
|
|
|
return {
|
|
|
tileSource: this.state.tileSource,
|
|
|
+ osmTileSource: OSM_TILE_SOURCE,
|
|
|
zoom: this.state.zoom,
|
|
|
centerTileX: this.state.centerTileX,
|
|
|
centerTileY: this.state.centerTileY,
|
|
|
+ exactCenterWorldX: exactCenter.x,
|
|
|
+ exactCenterWorldY: exactCenter.y,
|
|
|
tileBoundsByZoom: this.tileBoundsByZoom,
|
|
|
viewportWidth: this.state.stageWidth,
|
|
|
viewportHeight: this.state.stageHeight,
|
|
|
@@ -1382,6 +1410,10 @@ export class MapEngine {
|
|
|
previewOriginY: this.previewOriginY || this.state.stageHeight / 2,
|
|
|
track: this.currentGpsTrack.length ? this.currentGpsTrack : SAMPLE_TRACK_WGS84,
|
|
|
gpsPoint: this.currentGpsPoint,
|
|
|
+ gpsCalibration: GPS_MAP_CALIBRATION,
|
|
|
+ gpsCalibrationOrigin: worldTileToLonLat({ x: this.defaultCenterTileX, y: this.defaultCenterTileY }, this.defaultZoom),
|
|
|
+ osmReferenceEnabled: this.state.osmReferenceEnabled,
|
|
|
+ overlayOpacity: MAP_OVERLAY_OPACITY,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -1395,8 +1427,8 @@ export class MapEngine {
|
|
|
|
|
|
getCameraState(rotationDeg = this.state.rotationDeg): CameraState {
|
|
|
return {
|
|
|
- centerWorldX: this.state.centerTileX,
|
|
|
- centerWorldY: this.state.centerTileY,
|
|
|
+ centerWorldX: this.state.centerTileX + 0.5,
|
|
|
+ centerWorldY: this.state.centerTileY + 0.5,
|
|
|
viewportWidth: this.state.stageWidth,
|
|
|
viewportHeight: this.state.stageHeight,
|
|
|
visibleColumns: DESIRED_VISIBLE_COLUMNS,
|
|
|
@@ -1410,10 +1442,10 @@ export class MapEngine {
|
|
|
return normalizeRotationDeg(rotationDeg) * Math.PI / 180
|
|
|
}
|
|
|
|
|
|
- getBaseCamera(centerWorldX = this.state.centerTileX, centerWorldY = this.state.centerTileY, rotationDeg = this.state.rotationDeg): CameraState {
|
|
|
+ getBaseCamera(centerTileX = this.state.centerTileX, centerTileY = this.state.centerTileY, rotationDeg = this.state.rotationDeg): CameraState {
|
|
|
return {
|
|
|
- centerWorldX,
|
|
|
- centerWorldY,
|
|
|
+ centerWorldX: centerTileX + 0.5,
|
|
|
+ centerWorldY: centerTileY + 0.5,
|
|
|
viewportWidth: this.state.stageWidth,
|
|
|
viewportHeight: this.state.stageHeight,
|
|
|
visibleColumns: DESIRED_VISIBLE_COLUMNS,
|
|
|
@@ -1437,8 +1469,8 @@ export class MapEngine {
|
|
|
getExactCenterFromTranslate(translateX: number, translateY: number): { x: number; y: number } {
|
|
|
if (!this.state.stageWidth || !this.state.stageHeight) {
|
|
|
return {
|
|
|
- x: this.state.centerTileX,
|
|
|
- y: this.state.centerTileY,
|
|
|
+ x: this.state.centerTileX + 0.5,
|
|
|
+ y: this.state.centerTileY + 0.5,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -1456,8 +1488,8 @@ export class MapEngine {
|
|
|
tileTranslateX: number
|
|
|
tileTranslateY: number
|
|
|
} {
|
|
|
- const nextCenterTileX = Math.round(centerWorldX)
|
|
|
- const nextCenterTileY = Math.round(centerWorldY)
|
|
|
+ const nextCenterTileX = Math.floor(centerWorldX)
|
|
|
+ const nextCenterTileY = Math.floor(centerWorldY)
|
|
|
|
|
|
if (!this.state.stageWidth || !this.state.stageHeight) {
|
|
|
return {
|
|
|
@@ -1763,6 +1795,13 @@ export class MapEngine {
|
|
|
|
|
|
|
|
|
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
|
|
|
|
|
|
|