When using amAP images, if osM or city white film is loaded, geographic coordinates will be offset. Here because the domestic map developers use different coordinate system, so when using to do a coordinate conversion.

Geographic coordinate system

WGS84

An internationally used geocentric coordinate system. The Z axis of the geocentric space cartesian coordinate system points to the direction of the protocol Earth pole (CTP) defined by BIH (International Time Service) 1984.o, and the X axis points to the intersection of the zero meridional plane of BIH 1984.0 and the CTP equator. Y axis and Z axis, X axis perpendicular to form the right hand coordinate system, known as the 1984 world geodetic coordinate system.

CGCS2000

China Geodetic Coordinate System 2000 (CGCS2000), also known as the 2000 National Geodetic Coordinate System, is a new generation of Geodetic Coordinate System in China, which has been formally implemented in China in the early 21st century. It is not much different from WGS84, and the domestic map of heaven and earth uses this coordinate system.

GCJ02

Gcj-02 is a coordinate system of geographic information System developed by the State Bureau of Surveying and Mapping of China (G stands for Guojia Country, C stands for Cehui Survey and J stands for Ju Bureau). In fact, it is the real coordinate system for artificial add bias processing, according to the special algorithm, the real coordinate encryption into false coordinates, and this is not linear add bias, so the offset will be different around. The encrypted coordinates are often referred to as the “Mars coordinate system”.

BD09

BD09 latitude and longitude projection belongs to The Baidu coordinate system, which is based on the standard latitude and longitude after gCJ-02 bias, plus Baidu’s own bias algorithm, that is, on the basis of the standard latitude and longitude for two times.

Scott rectifying

Through the cesium UrlTemplateImageryProvider tilingScheme to rectify.

The world geodetic coordinate system to Mars coordinate system and the Mars coordinate system to the world geodetic coordinate system are converted through the _megal. project and _megal.unproject methods of the overloaded WebMercatorTilingScheme

    this.viewerCesium.imageryLayers.addImageryProvider(
      new UrlTemplateImageryProvider({
        url: 'https://webrd04.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x={x}&y={y}&z={z}'.minimumLevel: 3.maximumLevel: 18.tilingScheme: new AmapMercatorTilingScheme(),
      })
    );
Copy the code
import { WebMercatorProjection, WebMercatorTilingScheme, Math, Cartographic, Cartesian2 } from '.. /cesium/Cesium';
import CoordTransform from './CoordTransform';

class AmapMercatorTilingScheme extends WebMercatorTilingScheme {
  _projection: any;

  constructor() {
    super(a);let projection = new WebMercatorProjection();

    this._projection.project = function (cartographic: any, result: any) {
      result = CoordTransform.WGS84ToGCJ02(
        Math.toDegrees(cartographic.longitude),
        Math.toDegrees(cartographic.latitude)
      );
      result = projection.project(new Cartographic(Math.toRadians(result[0]), Math.toRadians(result[1)));return new Cartesian2(result.x, result.y);
    };

    this._projection.unproject = function (cartesian: any, result: any) {
      let cartographic = projection.unproject(cartesian);
      result = CoordTransform.GCJ02ToWGS84(
        Math.toDegrees(cartographic.longitude),
        Math.toDegrees(cartographic.latitude)
      );
      return new Cartographic(Math.toRadians(result[0]), Math.toRadians(result[1])); }; }}export default AmapMercatorTilingScheme;
Copy the code
// Define some constants
const BD_FACTOR = (3.14159265358979324 * 3000.0) / 180.0;
const PI = 3.1415926535897932384626;
const RADIUS = 6378245.0;
const EE = 0.00669342162296594323;

class CoordTransform {
  /** * bD-09 (Baidu coordinates) To GCJ-02(Mars coordinates) *@param lng
   * @param lat
   * @returns {number[]}* /
  static BD09ToGCJ02(lng: number, lat: number) {
    let x = +lng - 0.0065;
    let y = +lat - 0.006;
    let z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * BD_FACTOR);
    let theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * BD_FACTOR);
    let gg_lng = z * Math.cos(theta);
    let gg_lat = z * Math.sin(theta);
    return [gg_lng, gg_lat];
  }

  /** * gcJ-02 To BD-09 *@param lng
   * @param lat
   * @returns {number[]}
   * @constructor* /
  static GCJ02ToBD09(lng: number, lat: number) {
    lat = +lat;
    lng = +lng;
    let z = Math.sqrt(lng * lng + lat * lat) + 0.00002 * Math.sin(lat * BD_FACTOR);
    let theta = Math.atan2(lat, lng) + 0.000003 * Math.cos(lng * BD_FACTOR);
    let bd_lng = z * Math.cos(theta) + 0.0065;
    let bd_lat = z * Math.sin(theta) + 0.006;
    return [bd_lng, bd_lat];
  }

  /** * WGS-84 To GCJ-02 To gCJ-02@param lng
   * @param lat
   * @returns {number[]}* /
  static WGS84ToGCJ02(lng: number, lat: number) {
    lat = +lat;
    lng = +lng;
    if (this.out_of_china(lng, lat)) {
      return [lng, lat];
    } else {
      let d = this.delta(lng, lat);
      return [lng + d[0], lat + d[1]]. }}/** * GCJ-02(Mars coordinates) To WGS-84(World geodetic coordinates) *@param lng
   * @param lat
   * @returns {number[]}
   * @constructor* /
  static GCJ02ToWGS84(lng: number, lat: number) {
    lat = +lat;
    lng = +lng;
    if (this.out_of_china(lng, lat)) {
      return [lng, lat];
    } else {
      let d = this.delta(lng, lat);
      let mgLng = lng + d[0];
      let mgLat = lat + d[1];
      return [lng * 2 - mgLng, lat * 2- mgLat]; }}/ * * * *@param lng
   * @param lat
   * @returns {number[]}* /
  static delta(lng: number, lat: number) {
    let dLng = this.transformLng(lng - 105, lat - 35);
    let dLat = this.transformLat(lng - 105, lat - 35);
    const radLat = (lat / 180) * PI;
    let magic = Math.sin(radLat);
    magic = 1 - EE * magic * magic;
    const sqrtMagic = Math.sqrt(magic);
    dLng = (dLng * 180) / ((RADIUS / sqrtMagic) * Math.cos(radLat) * PI);
    dLat = (dLat * 180) / (((RADIUS * (1 - EE)) / (magic * sqrtMagic)) * PI);
    return [dLng, dLat];
  }

  / * * * *@param lng
   * @param lat
   * @returns {number}* /
  static transformLng(lng: number, lat: number) {
    lat = +lat;
    lng = +lng;
    let ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng));
    ret += ((20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0) / 3.0;
    ret += ((20.0 * Math.sin(lng * PI) + 40.0 * Math.sin((lng / 3.0) * PI)) * 2.0) / 3.0;
    ret += ((150.0 * Math.sin((lng / 12.0) * PI) + 300.0 * Math.sin((lng / 30.0) * PI)) * 2.0) / 3.0;
    return ret;
  }

  / * * * *@param lng
   * @param lat
   * @returns {number}* /
  static transformLat(lng: number, lat: number) {
    lat = +lat;
    lng = +lng;
    let ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng));
    ret += ((20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0) / 3.0;
    ret += ((20.0 * Math.sin(lat * PI) + 40.0 * Math.sin((lat / 3.0) * PI)) * 2.0) / 3.0;
    ret += ((160.0 * Math.sin((lat / 12.0) * PI) + 320 * Math.sin((lat * PI) / 30.0)) * 2.0) / 3.0;
    return ret;
  }

  /** * Check whether it is in the country. Do not do domestic offset *@param lng
   * @param lat
   * @returns {boolean}* /
  static out_of_china(lng: number, lat: number) {
    lat = +lat;
    lng = +lng;
    return! (lng >73.66 && lng < 135.05 && lat > 3.86 && lat < 53.55); }}export default CoordTransform;
Copy the code