; (function (Cesium) {
const coordinate = {
x_PI: (Math.PI * 3000.0) / 180.0,
PI: Math.PI,
ee: 0.00669342162296594323,
a: 6378245.0,
projs: {
'01': 'wgs84', //84坐标
'02': 'gcj02', //火星坐标
'03': 'bd09', //百度坐标
'04': 'utm4', //utm坐标
'05': 'shcj', //城建坐标
'06': 'meter', //米制单位
'07': 'degree' // 度制单位
},
epsg: {
//WGS 84 - WGS84 - World Geodetic System 1984, used in GPS
'4326': '+proj=longlat +datum=WGS84 +no_defs',
//WGS 84 / Pseudo-Mercator - Spherical Mercator, Google Maps, OpenStreetMap, Bing, ArcGIS, ESRI
'3857':
'+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs',
//CGCS2000 / 3-degree Gauss-Kruger zone 40
'4528':
'+proj=tmerc +lat_0=0 +lon_0=120 +k=1 +x_0=40500000 +y_0=0 +ellps=GRS80 +units=m +no_defs'
},
bd09_to_gcj02: function (bd_lon, bd_lat) {
var x = bd_lon - 0.0065
var y = bd_lat - 0.006
var z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * this.x_PI)
var theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * this.x_PI)
var gg_lng = z * Math.cos(theta)
var gg_lat = z * Math.sin(theta)
return [gg_lng, gg_lat]
},
gcj02_to_bd09: function (lng, lat) {
var z =
Math.Sqrt(lng * lng + lat * lat) + 0.00002 * Math.Sin(lat * this.x_PI)
var theta = Math.Atan2(lat, lng) + 0.000003 * Math.Cos(lng * this.x_PI)
var bd_lng = z * Math.Cos(theta) + 0.0065
var bd_lat = z * Math.Sin(theta) + 0.006
return [bd_lng, bd_lat]
},
wgs84_to_gcj02: function (lng, lat) {
if (this.out_of_china(lng, lat)) {
[lng, lat]
} else {
var dlat = this.transformlat(lng - 105.0, lat - 35.0)
var dlng = this.transformlng(lng - 105.0, lat - 35.0)
var radlat = (lat / 180.0) * this.PI
var magic = Math.sin(radlat)
magic = 1 - this.ee * magic * magic
var sqrtmagic = Math.sqrt(magic)
dlat =
(dlat * 180.0) /
(((this.a * (1 - this.ee)) / (magic * sqrtmagic)) * this.PI)
dlng =
(dlng * 180.0) / ((this.a / sqrtmagic) * Math.cos(radlat) * this.PI)
var mglat = parseFloat(lat) + parseFloat(dlat)
var mglng = parseFloat(lng) + parseFloat(dlng)
return [mglng, mglat]
}
},
gcj02_to_wgs84: function (lng, lat) {
if (this.out_of_china(lng, lat)) {
return [lng, lat]
} else {
var dlat = this.transformlat(lng - 105.0, lat - 35.0)
var dlng = this.transformlng(lng - 105.0, lat - 35.0)
var radlat = (lat / 180.0) * this.PI
var magic = Math.sin(radlat)
magic = 1 - this.ee * magic * magic
var sqrtmagic = Math.sqrt(magic)
dlat =
(dlat * 180.0) /
(((this.a * (1 - this.ee)) / (magic * sqrtmagic)) * this.PI)
dlng =
(dlng * 180.0) / ((this.a / sqrtmagic) * Math.cos(radlat) * this.PI)
var mglat = lat + dlat
var mglng = lng + dlng
return [lng * 2 - mglng, lat * 2 - mglat]
}
},
out_of_china: function (lng, lat) {
// 纬度3.86~53.55,经度73.66~135.05
return !(lng > 73.66 && lng < 135.05 && lat > 3.86 && lat < 53.55)
},
transformlat: function (lng, lat) {
var 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 * this.PI) +
20.0 * Math.sin(2.0 * lng * this.PI)) *
2.0) /
3.0
ret +=
((20.0 * Math.sin(lat * this.PI) +
40.0 * Math.sin((lat / 3.0) * this.PI)) *
2.0) /
3.0
ret +=
((160.0 * Math.sin((lat / 12.0) * this.PI) +
320 * Math.sin((lat * this.PI) / 30.0)) *
2.0) /
3.0
return ret
},
transformlng: function (lng, lat) {
var 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 * this.PI) +
20.0 * Math.sin(2.0 * lng * this.PI)) *
2.0) /
3.0
ret +=
((20.0 * Math.sin(lng * this.PI) +
40.0 * Math.sin((lng / 3.0) * this.PI)) *
2.0) /
3.0
ret +=
((150.0 * Math.sin((lng / 12.0) * this.PI) +
300.0 * Math.sin((lng / 30.0) * this.PI)) *
2.0) /
3.0
return ret
},
///
/// web墨卡托经纬度转米
///
///
///
///
degree_to_meter: function (lng, lat) {
var x = (lng * 20037508.34) / 180
var y = Math.log(Math.tan(((90 + lat) * this.PI) / 360)) / (this.PI / 180)
y = (y * 20037508.34) / 180
return [x, y]
},
//Web墨卡托转经纬度
meter_to_degree: function (x, y) {
var lon = (x / 20037508.34) * 180
var lat = (y / 20037508.34) * 180
lat =
(180 / this.PI) *
(2 * Math.atan(Math.exp((lat * this.PI) / 180)) - this.PI / 2)
return [lon, lat]
},
/**
* @description wgs84坐标转上海城建
* @time 2020-09-02
* @author zhb
* @param {*} x
* @param {*} y
*/
wgs84_to_shcj: function (x, y) {
let xy = []
xy = this.shcj_get_UTM_from_WGS(x, y)
return this.utm_to_shcj4(xy[0], xy[1])
},
utm_to_shcj4(x, y) {
let DX, DY, T, K
DX = -500199.29965
DY = -3457078.805985
T = 0.0000001755
K = 1.0004000106
return this.covert_by_four_parm(x, y, DX, DY, T, K)
},
shcj_get_UTM_from_WGS: function (lon, lat) {
let a = 6378137
let b = 6356752.3142451
let f = (a - b) / a
let eSquare = 2 * f - f * f
let k0 = 0.9996
let lonOrigin = 121.46714714
let FN = 0
// # 确保longtitude位于-180.00----179.9之间
let lonTemp = lon + 180 - Math.floor((lon + 180) / 360) * 360 - 180
let latRad = (lat * this.PI) / 180
let lonRad = (lonTemp * this.PI) / 180
let lonOriginRad = (lonOrigin * this.PI) / 180
let e2Square = eSquare / (1 - eSquare)
let V = a / Math.sqrt(1 - eSquare * Math.pow(Math.sin(latRad), 2))
let T = Math.pow(Math.tan(latRad), 2)
let C = e2Square * Math.pow(Math.cos(latRad), 2)
let A = Math.cos(latRad) * (lonRad - lonOriginRad)
let M =
a *
((1 -
eSquare / 4 -
(3 * Math.pow(eSquare, 2)) / 64 -
(5 * Math.pow(eSquare, 3)) / 256) *
latRad -
((3 * eSquare) / 8 +
(3 * Math.pow(eSquare, 2)) / 32 +
(45 * Math.pow(eSquare, 3)) / 1024) *
Math.sin(2 * latRad) +
((15 * Math.pow(eSquare, 2)) / 256 +
(45 * Math.pow(eSquare, 3)) / 1024) *
Math.sin(4 * latRad) -
((35 * Math.pow(eSquare, 3)) / 3072) * Math.sin(6 * latRad))
// # x
let UTMEasting =
k0 *
V *
(A +
((1 - T + C) * Math.pow(A, 3)) / 6 +
((5 - 18 * T + Math.pow(T, 2) + 72 * C - 58 * e2Square) *
Math.pow(A, 5)) /
120) +
500000.0
// # y
let UTMNorthing =
k0 *
(M +
V *
Math.tan(latRad) *
(Math.pow(A, 2) / 2 +
((5 - T + 9 * C + 4 * Math.pow(C, 2)) * Math.pow(A, 4)) / 24 +
((61 - 58 * T + Math.pow(T, 2) + 600 * C - 330 * e2Square) *
Math.pow(A, 6)) /
720))
//# 南半球纬度起点为10000000.0m
UTMNorthing += FN
let xy = []
xy[0] = UTMEasting
xy[1] = UTMNorthing
return xy
},
/**
* @description 上海城建坐标转wgs84
* @time 2020-09-02
* @author zhb
* @param {*} x
* @param {*} y
*/
shcj_to_wgs84: function (x, y) {
let xy = []
xy = this.shcj_to_utm4(x, y)
return this.shcj_get_WGS_from_UTM(xy[0], xy[1])
},
shcj_to_utm4: function (x, y) {
let DX, DY, T, K
DX = 499999.90104
DY = 3455696.403019
T = -0.0000001755
K = 0.999600149344
return this.covert_by_four_parm(x, y, DX, DY, T, K)
},
//四参数公式
covert_by_four_parm: function (x, y, dx, dy, a, k) {
let px = 0
let py = 0
px = x * k * Math.cos(a) - y * k * Math.sin(a) + dx
py = x * k * Math.sin(a) + y * k * Math.cos(a) + dy
let xy = []
xy[0] = px
xy[1] = py
return xy
},
shcj_get_WGS_from_UTM: function (x, y) {
//WGS84
let a = 6378137 //椭球体长半轴
let b = 6356752.3142451 //椭球体短半轴
// double a = 6378245 ;
// double b =6356863.018773047300000000;
x = 500000 - x
let k0 = 0.9996
let e = Math.sqrt(1 - Math.pow(b, 2) / Math.pow(a, 2))
// # calculate the meridional arc
let M = y / k0
//# calculate footprint latitude
let mu =
M /
(a *
(1 -
Math.pow(e, 2) / 4 -
(3 * Math.pow(e, 4)) / 64 -
(5 * Math.pow(e, 6)) / 256))
let e1 =
(1 - Math.pow(1 - Math.pow(e, 2), 1.0 / 2)) /
(1 + Math.pow(1 - Math.pow(e, 2), 1.0 / 2))
let J1 = (3 * e1) / 2 - (27 * Math.pow(e1, 3)) / 32
let J2 = (21 * Math.pow(e1, 2)) / 16 - (55 * Math.pow(e1, 4)) / 32
let J3 = (151 * Math.pow(e1, 3)) / 96
let J4 = (1097 * Math.pow(e1, 4)) / 512
let fp =
mu +
J1 * Math.sin(2 * mu) +
J2 * Math.sin(4 * mu) +
J3 * Math.sin(6 * mu) +
J4 * Math.sin(8 * mu)
// # Calculate Latitude and Longitude
let e2 = Math.pow(e, 2) / (1 - Math.pow(e, 2))
let C1 = e2 * Math.pow(Math.cos(fp), 2)
let T1 = Math.pow(Math.tan(fp), 2)
let R1 =
(a * (1 - Math.pow(e, 2))) /
Math.pow(1 - Math.pow(e * Math.sin(fp), 2), 3.0 / 2)
//# This is the same as rho in the forward conversion formulas above, but calculated for fp instead of lat.
let N1 = a / Math.pow(1 - Math.pow(e * Math.sin(fp), 2), 1.0 / 2)
//# This is the same as nu in the forward conversion formulas above, but calculated for fp instead of lat.
let D = x / (N1 * k0)
let Q1 = (N1 * Math.tan(fp)) / R1
let Q2 = Math.pow(D, 2) / 2
let Q3 =
((5 + 3 * T1 + 10 * C1 - 4 * Math.pow(C1, 2) - 9 * e2) * Math.pow(D, 4)) /
24
let Q4 =
((61 +
90 * T1 +
298 * C1 +
45 * Math.pow(T1, 2) -
3 * Math.pow(C1, 2) -
252 * e2) *
Math.pow(D, 6)) /
720
let lat = ((fp - Q1 * (Q2 - Q3 + Q4)) * 180) / this.PI
// System.out.println("lat===="+Math.toRadians(fp - Q1*(Q2 - Q3 + Q4)));
let Q5 = D
let Q6 = ((1 + 2 * T1 + C1) * Math.pow(D, 3)) / 6
let Q7 =
((5 -
2 * C1 +
28 * T1 -
3 * Math.pow(C1, 2) +
8 * e2 +
24 * Math.pow(T1, 2)) *
Math.pow(D, 5)) /
120
let lonmid = 121.46714714
let lon = lonmid - (((Q5 - Q6 + Q7) / Math.cos(fp)) * 180) / this.PI
//System.out.println("lon===="+(mMid - Math.toRadians((Q5 - Q6 + Q7)/Math.cos(fp))));
// System.out.println(lat+","+lon);
let xy = []
xy[0] = lon
xy[1] = lat
return xy
},
wgs84_to_bd09: function (x, y) {
let ll = this.wgs84_to_gcj02(x, y)
ll = this.gcj02_to_bd09(ll[0], ll[1])
return ll
},
bd09_to_wgs84: function (x, y) {
let ll = this.bd09_to_gcj02(x, y)
ll = this.gcj02_to_wgs84(ll[0], ll[1])
return ll
},
gcj02_to_shcj: function (x, y) {
let ll = this.gcj02_to_wgs84(x, y)
ll = this.wgs84_to_shcj(ll[0], ll[1])
return ll
},
shcj_to_gcj02: function (x, y) {
let ll = this.shcj_to_wgs84(x, y)
ll = this.wgs84_to_gcj02(ll[0], ll[1])
return ll
},
/**
* @description 坐标转换转换 01:84,02:高德,03.百度,04,UTM,05,上海城建,06:米制单位
* @param {} from
* @param {*} to
* @param {*} xy
* @time 2020-09-02
* @author zhb
*/
convert_proj_from_to: function (from, to, xy) {
if (from === to) {
return xy
} else {
let fromProj = this.projs[from]
let toProj = this.projs[to]
let targetMethod = `${fromProj}_to_${toProj}`
return this[targetMethod](xy[0], xy[1])
}
}
}
class CoordTransform {
constructor() {
this.PI = 3.1415926535897932384626;
this.RADIUS = 6378245.0;
this.EE = 0.00669342162296594323;
}
static WGS84ToSH2000(lng, lat) {
if (this.out_of_sh(lng, lat)) {
return [lng, lat];
} else {
var templatlng = coordinate.wgs84_to_shcj(lng, lat);
templatlng = coordinate.meter_to_degree(templatlng[0], templatlng[1])
return [templatlng[0], templatlng[1]];
}
}
static SH2000ToWGS84(x, y) {
//墨卡托转经纬度
var templatlng = coordinate.meter_to_degree(x, y);
if (this.out_of_sh2000(templatlng[0], templatlng[1])) {
return [x, y];
} else {
templatlng = coordinate.shcj_to_wgs84(x, y);
return templatlng;
}
}
static SH2000lnglatToWGS84(lng, lat) {
//墨卡托转经纬度
if (this.out_of_sh2000(lng, lat)) {
return [lng, lat];
} else {
var templatlng = coordinate.degree_to_meter(lng, lat);
templatlng = coordinate.shcj_to_wgs84(templatlng[0], templatlng[1]);
return templatlng;
}
}
/**
* 判断是否在上海。不在上海不做偏移
* 118.48721797337146,30.26010209544536,122.69588184110438,32.52150117412529
* @param lng
* @param lat
* @returns {boolean}
*/
static out_of_sh(lng, lat) {
lat = +lat;
lng = +lng;
return !(lng > 115.487 && lng < 123.696 && lat > 28.260 && lat < 33.521);
}
/*
* 上海坐标系范围判断
*/
static out_of_sh2000(lng, lat) {
lat = +lat;
lng = +lng;
return !(lng > -12.819008830308748 && lng < 10.125641358030961 && lat > -7.553039281805486 && lat < 8.400473860032621);
}
/**
*
* @param lng
* @param lat
* @returns {number[]}
*/
static delta(lng, lat) {
let dLng = this.transformLng(lng - 105, lat - 35);
let dLat = this.transformLat(lng - 105, lat - 35);
const radLat = (lat / 180) * this.PI;
let magic = Math.sin(radLat);
magic = 1 - this.EE * magic * magic;
const sqrtMagic = Math.sqrt(magic);
dLng = (dLng * 180) / ((this.RADIUS / sqrtMagic) * Math.cos(radLat) * this.PI);
dLat = (dLat * 180) / (((this.RADIUS * (1 - this.EE)) / (magic * sqrtMagic)) * this.PI);
return [dLng, dLat];
}
/**
*
* @param lng
* @param lat
* @returns {number}
*/
static transformLng(lng, lat) {
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 * this.PI) + 20.0 * Math.sin(2.0 * lng * this.PI)) * 2.0) / 3.0;
ret += ((20.0 * Math.sin(lng * this.PI) + 40.0 * Math.sin((lng / 3.0) * this.PI)) * 2.0) / 3.0;
ret += ((150.0 * Math.sin((lng / 12.0) * this.PI) + 300.0 * Math.sin((lng / 30.0) * this.PI)) * 2.0) / 3.0;
return ret;
}
/**
*
* @param lng
* @param lat
* @returns {number}
*/
static transformLat(lng, lat) {
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 * this.PI) + 20.0 * Math.sin(2.0 * lng * this.PI)) * 2.0) / 3.0;
ret += ((20.0 * Math.sin(lat * this.PI) + 40.0 * Math.sin((lat / 3.0) * this.PI)) * 2.0) / 3.0;
ret += ((160.0 * Math.sin((lat / 12.0) * this.PI) + 320 * Math.sin((lat * this.PI) / 30.0)) * 2.0) / 3.0;
return ret;
}
// 经纬度转墨卡托
static transformMercator(lonLat) {
var mercator = {};
var x = lonLat.x * 20037508.34 / 180;
var y = Math.log(Math.tan((90 + lonLat.y) * Math.PI / 360)) / (Math.PI / 180);
y = y * 20037508.34 / 180;
mercator.x = x;
mercator.y = y;
return mercator;
}
}
Cesium.CoordTransform = CoordTransform;
/**
* A tiling scheme for geometry referenced to a {@link WebMercatorProjection}, EPSG:3857. This is
* the tiling scheme used by Google Maps, Microsoft Bing Maps, and most of ESRI ArcGIS Online.
*
* @alias SHmapMercatorTilingScheme
* @constructor
*
* @param {Object} [options] Object with the following properties:
* @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid whose surface is being tiled. Defaults to
* the WGS84 ellipsoid.
* @param {Number} [options.numberOfLevelZeroTilesX=1] The number of tiles in the X direction at level zero of
* the tile tree.
* @param {Number} [options.numberOfLevelZeroTilesY=1] The number of tiles in the Y direction at level zero of
* the tile tree.
* @param {Cartesian2} [options.rectangleSouthwestInMeters] The southwest corner of the rectangle covered by the
* tiling scheme, in meters. If this parameter or rectangleNortheastInMeters is not specified, the entire
* globe is covered in the longitude direction and an equal distance is covered in the latitude
* direction, resulting in a square projection.
* @param {Cartesian2} [options.rectangleNortheastInMeters] The northeast corner of the rectangle covered by the
* tiling scheme, in meters. If this parameter or rectangleSouthwestInMeters is not specified, the entire
* globe is covered in the longitude direction and an equal distance is covered in the latitude
* direction, resulting in a square projection.
*/
function SHmapMercatorTilingScheme(options) {
options = Cesium.defaultValue(options, Cesium.defaultValue.EMPTY_OBJECT);
this._ellipsoid = Cesium.defaultValue(options.ellipsoid, Cesium.Ellipsoid.WGS84);
this._numberOfLevelZeroTilesX = Cesium.defaultValue(
options.numberOfLevelZeroTilesX,
1
);
this._numberOfLevelZeroTilesY = Cesium.defaultValue(
options.numberOfLevelZeroTilesY,
1
);
this._projection = new Cesium.WebMercatorProjection();
var oprojection = new Cesium.WebMercatorProjection();
this._projection.project = function (cartographic, result) {
result = CoordTransform.WGS84ToSH2000(
Cesium.Math.toDegrees(cartographic.longitude),
Cesium.Math.toDegrees(cartographic.latitude)
);
result = oprojection.project(new Cesium.Cartographic(Cesium.Math.toRadians(result[0]), Cesium.Math.toRadians(result[1])));
return new Cesium.Cartesian2(result.x, result.y);
};
this._projection.unproject = function (cartesian, result) {
let cartographic = oprojection.unproject(cartesian);
result = CoordTransform.SH2000lnglatToWGS84(
Cesium.Math.toDegrees(cartographic.longitude),
Cesium.Math.toDegrees(cartographic.latitude)
);
return new Cesium.Cartographic(Cesium.Math.toRadians(result[0]), Cesium.Math.toRadians(result[1]));
};
if (
Cesium.defined(options.rectangleSouthwestInMeters) &&
Cesium.defined(options.rectangleNortheastInMeters)
) {
this._rectangleSouthwestInMeters = options.rectangleSouthwestInMeters;
this._rectangleNortheastInMeters = options.rectangleNortheastInMeters;
} else {
const semimajorAxisTimesPi = this._ellipsoid.maximumRadius * Cesium.Math.PI;
this._rectangleSouthwestInMeters = new Cesium.Cartesian2(
-semimajorAxisTimesPi,
-semimajorAxisTimesPi
);
this._rectangleNortheastInMeters = new Cesium.Cartesian2(
semimajorAxisTimesPi,
semimajorAxisTimesPi
);
}
const southwest = this._projection.unproject(
this._rectangleSouthwestInMeters
);
const northeast = this._projection.unproject(
this._rectangleNortheastInMeters
);
this._rectangle = new Cesium.Rectangle(
southwest.longitude,
southwest.latitude,
northeast.longitude,
northeast.latitude
);
}
Object.defineProperties(SHmapMercatorTilingScheme.prototype, {
/**
* Gets the ellipsoid that is tiled by this tiling scheme.
* @memberof SHmapMercatorTilingScheme.prototype
* @type {Ellipsoid}
*/
ellipsoid: {
get: function () {
return this._ellipsoid;
},
},
/**
* Gets the rectangle, in radians, covered by this tiling scheme.
* @memberof SHmapMercatorTilingScheme.prototype
* @type {Rectangle}
*/
rectangle: {
get: function () {
return this._rectangle;
},
},
/**
* Gets the map projection used by this tiling scheme.
* @memberof SHmapMercatorTilingScheme.prototype
* @type {MapProjection}
*/
projection: {
get: function () {
return this._projection;
},
},
});
/**
* Gets the total number of tiles in the X direction at a specified level-of-detail.
*
* @param {Number} level The level-of-detail.
* @returns {Number} The number of tiles in the X direction at the given level.
*/
SHmapMercatorTilingScheme.prototype.getNumberOfXTilesAtLevel = function (level) {
return this._numberOfLevelZeroTilesX << level;
};
/**
* Gets the total number of tiles in the Y direction at a specified level-of-detail.
*
* @param {Number} level The level-of-detail.
* @returns {Number} The number of tiles in the Y direction at the given level.
*/
SHmapMercatorTilingScheme.prototype.getNumberOfYTilesAtLevel = function (level) {
return this._numberOfLevelZeroTilesY << level;
};
/**
* Transforms a rectangle specified in geodetic radians to the native coordinate system
* of this tiling scheme.
*
* @param {Rectangle} rectangle The rectangle to transform.
* @param {Rectangle} [result] The instance to which to copy the result, or undefined if a new instance
* should be created.
* @returns {Rectangle} The specified 'result', or a new object containing the native rectangle if 'result'
* is undefined.
*/
SHmapMercatorTilingScheme.prototype.rectangleToNativeRectangle = function (
rectangle,
result
) {
const projection = this._projection;
const southwest = projection.project(Cesium.Rectangle.southwest(rectangle));
const northeast = projection.project(Cesium.Rectangle.northeast(rectangle));
if (!Cesium.defined(result)) {
return new Cesium.Rectangle(southwest.x, southwest.y, northeast.x, northeast.y);
}
result.west = southwest.x;
result.south = southwest.y;
result.east = northeast.x;
result.north = northeast.y;
return result;
};
/**
* Converts tile x, y coordinates and level to a rectangle expressed in the native coordinates
* of the tiling scheme.
*
* @param {Number} x The integer x coordinate of the tile.
* @param {Number} y The integer y coordinate of the tile.
* @param {Number} level The tile level-of-detail. Zero is the least detailed.
* @param {Object} [result] The instance to which to copy the result, or undefined if a new instance
* should be created.
* @returns {Rectangle} The specified 'result', or a new object containing the rectangle
* if 'result' is undefined.
*/
SHmapMercatorTilingScheme.prototype.tileXYToNativeRectangle = function (
x,
y,
level,
result
) {
const xTiles = this.getNumberOfXTilesAtLevel(level);
const yTiles = this.getNumberOfYTilesAtLevel(level);
const xTileWidth =
(this._rectangleNortheastInMeters.x - this._rectangleSouthwestInMeters.x) /
xTiles;
const west = this._rectangleSouthwestInMeters.x + x * xTileWidth;
const east = this._rectangleSouthwestInMeters.x + (x + 1) * xTileWidth;
const yTileHeight =
(this._rectangleNortheastInMeters.y - this._rectangleSouthwestInMeters.y) /
yTiles;
const north = this._rectangleNortheastInMeters.y - y * yTileHeight;
const south = this._rectangleNortheastInMeters.y - (y + 1) * yTileHeight;
if (!Cesium.defined(result)) {
return new Cesium.Rectangle(west, south, east, north);
}
result.west = west;
result.south = south;
result.east = east;
result.north = north;
return result;
};
/**
* Converts tile x, y coordinates and level to a cartographic rectangle in radians.
*
* @param {Number} x The integer x coordinate of the tile.
* @param {Number} y The integer y coordinate of the tile.
* @param {Number} level The tile level-of-detail. Zero is the least detailed.
* @param {Object} [result] The instance to which to copy the result, or undefined if a new instance
* should be created.
* @returns {Rectangle} The specified 'result', or a new object containing the rectangle
* if 'result' is undefined.
*/
SHmapMercatorTilingScheme.prototype.tileXYToRectangle = function (
x,
y,
level,
result
) {
const nativeRectangle = this.tileXYToNativeRectangle(x, y, level, result);
const projection = this._projection;
const southwest = projection.unproject(
new Cesium.Cartesian2(nativeRectangle.west, nativeRectangle.south)
);
const northeast = projection.unproject(
new Cesium.Cartesian2(nativeRectangle.east, nativeRectangle.north)
);
nativeRectangle.west = southwest.longitude;
nativeRectangle.south = southwest.latitude;
nativeRectangle.east = northeast.longitude;
nativeRectangle.north = northeast.latitude;
return nativeRectangle;
};
/**
* Calculates the tile x, y coordinates of the tile containing
* a given cartographic position.
*
* @param {Cartographic} position The position.
* @param {Number} level The tile level-of-detail. Zero is the least detailed.
* @param {Cartesian2} [result] The instance to which to copy the result, or undefined if a new instance
* should be created.
* @returns {Cartesian2} The specified 'result', or a new object containing the tile x, y coordinates
* if 'result' is undefined.
*/
SHmapMercatorTilingScheme.prototype.positionToTileXY = function (
position,
level,
result
) {
const rectangle = this._rectangle;
if (!Cesium.Rectangle.contains(rectangle, position)) {
// outside the bounds of the tiling scheme
return undefined;
}
const xTiles = this.getNumberOfXTilesAtLevel(level);
const yTiles = this.getNumberOfYTilesAtLevel(level);
const overallWidth =
this._rectangleNortheastInMeters.x - this._rectangleSouthwestInMeters.x;
const xTileWidth = overallWidth / xTiles;
const overallHeight =
this._rectangleNortheastInMeters.y - this._rectangleSouthwestInMeters.y;
const yTileHeight = overallHeight / yTiles;
const projection = this._projection;
const webMercatorPosition = projection.project(position);
const distanceFromWest =
webMercatorPosition.x - this._rectangleSouthwestInMeters.x;
const distanceFromNorth =
this._rectangleNortheastInMeters.y - webMercatorPosition.y;
let xTileCoordinate = (distanceFromWest / xTileWidth) | 0;
if (xTileCoordinate >= xTiles) {
xTileCoordinate = xTiles - 1;
}
let yTileCoordinate = (distanceFromNorth / yTileHeight) | 0;
if (yTileCoordinate >= yTiles) {
yTileCoordinate = yTiles - 1;
}
if (!Cesium.defined(result)) {
return new Cesium.Cartesian2(xTileCoordinate, yTileCoordinate);
}
result.x = xTileCoordinate;
result.y = yTileCoordinate;
return result;
}
Cesium.SHmapMercatorTilingScheme = SHmapMercatorTilingScheme;
/**
* @typedef {Object} CGCS2000ArcGisMapServerImageryProvider.ConstructorOptions
*
* Initialization options for the CGCS2000ArcGisMapServerImageryProvider constructor
*
* @property {Resource|String} url The URL of the ArcGIS MapServer service.
* @property {String} [token] The ArcGIS token used to authenticate with the ArcGIS MapServer service.
* @property {TileDiscardPolicy} [tileDiscardPolicy] The policy that determines if a tile
* is invalid and should be discarded. If this value is not specified, a default
* {@link DiscardMissingTileImagePolicy} is used for tiled map servers, and a
* {@link NeverTileDiscardPolicy} is used for non-tiled map servers. In the former case,
* we request tile 0,0 at the maximum tile level and check pixels (0,0), (200,20), (20,200),
* (80,110), and (160, 130). If all of these pixels are transparent, the discard check is
* disabled and no tiles are discarded. If any of them have a non-transparent color, any
* tile that has the same values in these pixel locations is discarded. The end result of
* these defaults should be correct tile discarding for a standard ArcGIS Server. To ensure
* that no tiles are discarded, construct and pass a {@link NeverTileDiscardPolicy} for this
* parameter.
* @property {Boolean} [usePreCachedTilesIfAvailable=true] If true, the server's pre-cached
* tiles are used if they are available. If false, any pre-cached tiles are ignored and the
* 'export' service is used.
* @property {String} [layers] A comma-separated list of the layers to show, or undefined if all layers should be shown.
* @property {Boolean} [enablePickFeatures=true] If true, {@link CGCS2000ArcGisMapServerImageryProvider#pickFeatures} will invoke
* the Identify service on the MapServer and return the features included in the response. If false,
* {@link CGCS2000ArcGisMapServerImageryProvider#pickFeatures} will immediately return undefined (indicating no pickable features)
* without communicating with the server. Set this property to false if you don't want this provider's features to
* be pickable. Can be overridden by setting the {@link CGCS2000ArcGisMapServerImageryProvider#enablePickFeatures} property on the object.
* @property {Rectangle} [rectangle=Rectangle.MAX_VALUE] The rectangle of the layer. This parameter is ignored when accessing
* a tiled layer.
* @property {TilingScheme} [tilingScheme=new GeographicTilingScheme()] The tiling scheme to use to divide the world into tiles.
* This parameter is ignored when accessing a tiled server.
* @property {Ellipsoid} [ellipsoid] The ellipsoid. If the tilingScheme is specified and used,
* this parameter is ignored and the tiling scheme's ellipsoid is used instead. If neither
* parameter is specified, the WGS84 ellipsoid is used.
* @property {Credit|String} [credit] A credit for the data source, which is displayed on the canvas. This parameter is ignored when accessing a tiled server.
* @property {Number} [tileWidth=256] The width of each tile in pixels. This parameter is ignored when accessing a tiled server.
* @property {Number} [tileHeight=256] The height of each tile in pixels. This parameter is ignored when accessing a tiled server.
* @property {Number} [maximumLevel] The maximum tile level to request, or undefined if there is no maximum. This parameter is ignored when accessing
* a tiled server.
*/
/**
* Provides tiled imagery hosted by an ArcGIS MapServer. By default, the server's pre-cached tiles are
* used, if available.
*
* @alias CGCS2000ArcGisMapServerImageryProvider
* @constructor
*
* @param {CGCS2000ArcGisMapServerImageryProvider.ConstructorOptions} options Object describing initialization options
*
* @see BingMapsImageryProvider
* @see GoogleEarthEnterpriseMapsProvider
* @see OpenStreetMapImageryProvider
* @see SingleTileImageryProvider
* @see TileMapServiceImageryProvider
* @see WebMapServiceImageryProvider
* @see WebMapTileServiceImageryProvider
* @see UrlTemplateImageryProvider
*
*
* @example
* const esri = new Cesium.CGCS2000ArcGisMapServerImageryProvider({
* url : 'https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer'
* });
*
* @see {@link https://developers.arcgis.com/rest/|ArcGIS Server REST API}
* @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing}
*/
function CGCS2000ArcGisMapServerImageryProvider(options) {
options = Cesium.defaultValue(options, Cesium.defaultValue.EMPTY_OBJECT);
//>>includeStart('debug', pragmas.debug);
if (!Cesium.defined(options.url)) {
throw new Cesium.DeveloperError("options.url is required.");
}
//>>includeEnd('debug');
/**
* The default alpha blending value of this provider, with 0.0 representing fully transparent and
* 1.0 representing fully opaque.
*
* @type {Number|undefined}
* @default undefined
*/
this.defaultAlpha = undefined;
/**
* The default alpha blending value on the night side of the globe of this provider, with 0.0 representing fully transparent and
* 1.0 representing fully opaque.
*
* @type {Number|undefined}
* @default undefined
*/
this.defaultNightAlpha = undefined;
/**
* The default alpha blending value on the day side of the globe of this provider, with 0.0 representing fully transparent and
* 1.0 representing fully opaque.
*
* @type {Number|undefined}
* @default undefined
*/
this.defaultDayAlpha = undefined;
/**
* The default brightness of this provider. 1.0 uses the unmodified imagery color. Less than 1.0
* makes the imagery darker while greater than 1.0 makes it brighter.
*
* @type {Number|undefined}
* @default undefined
*/
this.defaultBrightness = undefined;
/**
* The default contrast of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces
* the contrast while greater than 1.0 increases it.
*
* @type {Number|undefined}
* @default undefined
*/
this.defaultContrast = undefined;
/**
* The default hue of this provider in radians. 0.0 uses the unmodified imagery color.
*
* @type {Number|undefined}
* @default undefined
*/
this.defaultHue = undefined;
/**
* The default saturation of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces the
* saturation while greater than 1.0 increases it.
*
* @type {Number|undefined}
* @default undefined
*/
this.defaultSaturation = undefined;
/**
* The default gamma correction to apply to this provider. 1.0 uses the unmodified imagery color.
*
* @type {Number|undefined}
* @default undefined
*/
this.defaultGamma = undefined;
/**
* The default texture minification filter to apply to this provider.
*
* @type {TextureMinificationFilter}
* @default undefined
*/
this.defaultMinificationFilter = undefined;
/**
* The default texture magnification filter to apply to this provider.
*
* @type {TextureMagnificationFilter}
* @default undefined
*/
this.defaultMagnificationFilter = undefined;
const resource = Cesium.Resource.createIfNeeded(options.url);
resource.appendForwardSlash();
if (Cesium.defined(options.token)) {
resource.setQueryParameters({
token: options.token,
});
}
this._resource = resource;
this._tileDiscardPolicy = options.tileDiscardPolicy;
this._tileWidth = Cesium.defaultValue(options.tileWidth, 256);
this._tileHeight = Cesium.defaultValue(options.tileHeight, 256);
this._maximumLevel = options.maximumLevel;
this._tilingScheme = Cesium.defaultValue(
options.tilingScheme,
new Cesium.SHmapMercatorTilingScheme()
);
this._useTiles = Cesium.defaultValue(options.usePreCachedTilesIfAvailable, true);
this._rectangle = Cesium.defaultValue(
options.rectangle,
this._tilingScheme.rectangle
);
this._layers = options.layers;
let credit = options.credit;
if (typeof credit === "string") {
credit = new Cesium.Credit(credit);
}
this._credit = credit;
/**
* Gets or sets a value indicating whether feature picking is enabled. If true, {@link CGCS2000ArcGisMapServerImageryProvider#pickFeatures} will
* invoke the "identify" operation on the ArcGIS server and return the features included in the response. If false,
* {@link CGCS2000ArcGisMapServerImageryProvider#pickFeatures} will immediately return undefined (indicating no pickable features)
* without communicating with the server.
* @type {Boolean}
* @default true
*/
this.enablePickFeatures = Cesium.defaultValue(options.enablePickFeatures, true);
this._errorEvent = new Cesium.Event();
this._ready = false;
this._readyPromise = Cesium.defer();
// Grab the details of this MapServer.
const that = this;
let metadataError;
function metadataSuccess(data) {
const tileInfo = data.tileInfo;
if (!Cesium.defined(tileInfo)) {
that._useTiles = false;
} else if (!tileInfo.spatialReference.wkid) {
that._useTiles = false;
} else {
that._tileWidth = tileInfo.rows;
that._tileHeight = tileInfo.cols;
if (!tileInfo.spatialReference.wkid) {
tileInfo.spatialReference.wkid = 1001;
}
if (
tileInfo.spatialReference.wkid === 102100 ||
tileInfo.spatialReference.wkid === 102113
) {
that._tilingScheme = new Cesium.SHmapMercatorTilingScheme();
} else if (data.tileInfo.spatialReference.wkid === 4326) {
that._tilingScheme = new Cesium.GeographicTilingScheme({
ellipsoid: options.ellipsoid,
});
} else if (data.fullExtent.spatialReference.wkid === 4490 || data.fullExtent.spatialReference.wkid === 1001) {
that._tilingScheme = new Cesium.GeographicTilingScheme({
ellipsoid: options.ellipsoid,
tileInfo: data.tileInfo,
rectangle: that._rectangle
});
that._tilingScheme._tileInfo = data.tileInfo; //附加自定义属性
} else {
const message = `Tile spatial reference WKID ${data.tileInfo.spatialReference.wkid} is not supported.`;
metadataError = Cesium.TileProviderError.reportError(
metadataError,
that,
that._errorEvent,
message,
undefined,
undefined,
undefined,
requestMetadata
);
if (!metadataError.retry) {
that._readyPromise.reject(new Cesium.RuntimeError(message));
}
return;
}
that._maximumLevel = data.tileInfo.lods.length - 1;
if (Cesium.defined(data.fullExtent)) {
if (
Cesium.defined(data.fullExtent.spatialReference) &&
Cesium.defined(data.fullExtent.spatialReference.wkid)
) {
if (
data.fullExtent.spatialReference.wkid === 102100 ||
data.fullExtent.spatialReference.wkid === 102113
) {
const projection = new Cesium.WebMercatorProjection();
const extent = data.fullExtent;
//{x: 13521978.544776667, y: 3662655.182794742}
// extent.xmin = extent.xmin + 13521978.544776667;
// extent.ymin = extent.ymin + 3662655.182794742;
extent.xmax = extent.xmax + 13521978.544776667;
extent.ymax = extent.ymax + 3662655.182794742;
const sw = projection.unproject(
new Cesium.Cartesian3(
Math.max(
extent.xmin,
-that._tilingScheme.ellipsoid.maximumRadius * Math.PI
),
Math.max(
extent.ymin,
-that._tilingScheme.ellipsoid.maximumRadius * Math.PI
),
0.0
)
);
const ne = projection.unproject(
new Cesium.Cartesian3(
Math.min(
extent.xmax,
that._tilingScheme.ellipsoid.maximumRadius * Math.PI
),
Math.min(
extent.ymax,
that._tilingScheme.ellipsoid.maximumRadius * Math.PI
),
0.0
)
);
that._rectangle = new Cesium.Rectangle(
sw.longitude,
sw.latitude,
ne.longitude,
ne.latitude
);
} else if (data.fullExtent.spatialReference.wkid === 4326 || data.fullExtent.spatialReference.wkid === 4490) {
that._rectangle = Cesium.Rectangle.fromDegrees(
data.fullExtent.xmin,
data.fullExtent.ymin,
data.fullExtent.xmax,
data.fullExtent.ymax
);
} else if (data.fullExtent.spatialReference.wkid === 1001) {
// var minlatlng = gaussToGeo(data.fullExtent.xmin, data.fullExtent.ymin, 121.2751921);
// console.log(minlatlng)
// var maxlatlng = gaussToGeo(data.fullExtent.xmax, data.fullExtent.ymax, 121.2751921);
that._rectangle = Cesium.Rectangle.fromDegrees(
106.19840661411284,
22.72534254352711,
132.3724776782459,
39.41964096043237
);
console.log(that._rectangle);
} else {
const extentMessage = `fullExtent.spatialReference WKID ${data.fullExtent.spatialReference.wkid} is not supported.`;
metadataError = Cesium.TileProviderError.reportError(
metadataError,
that,
that._errorEvent,
extentMessage,
undefined,
undefined,
undefined,
requestMetadata
);
if (!metadataError.retry) {
that._readyPromise.reject(new Cesium.RuntimeError(extentMessage));
}
return;
}
}
} else {
that._rectangle = that._tilingScheme.rectangle;
}
// Install the default tile discard policy if none has been supplied.
if (!Cesium.defined(that._tileDiscardPolicy)) {
that._tileDiscardPolicy = new Cesium.DiscardMissingTileImagePolicy({
missingImageUrl: buildImageResource(that, 0, 0, that._maximumLevel)
.url,
pixelsToCheck: [
new Cesium.Cartesian2(0, 0),
new Cesium.Cartesian2(200, 20),
new Cesium.Cartesian2(20, 200),
new Cesium.Cartesian2(80, 110),
new Cesium.Cartesian2(160, 130),
],
disableCheckIfAllPixelsAreTransparent: true,
});
}
that._useTiles = true;
}
if (Cesium.defined(data.copyrightText) && data.copyrightText.length > 0) {
that._credit = new Cesium.Credit(data.copyrightText);
}
that._ready = true;
that._readyPromise.resolve(true);
Cesium.TileProviderError.reportSuccess(metadataError);
}
function metadataFailure(e) {
const message = `An error occurred while accessing ${that._resource.url}.`;
metadataError = Cesium.TileProviderError.reportError(
metadataError,
that,
that._errorEvent,
message,
undefined,
undefined,
undefined,
requestMetadata
);
that._readyPromise.reject(new Cesium.RuntimeError(message));
}
function requestMetadata() {
const resource = that._resource.getDerivedResource({
queryParameters: {
f: "json",
},
});
resource
.fetchJsonp()
.then(function (result) {
metadataSuccess(result);
})
.catch(function (e) {
metadataFailure(e);
});
}
if (this._useTiles) {
requestMetadata();
} else {
this._ready = true;
this._readyPromise.resolve(true);
}
}
function buildImageResource(imageryProvider, x, y, level, request) {
let resource;
if (imageryProvider._useTiles) {
resource = imageryProvider._resource.getDerivedResource({
url: `tile/${level}/${y}/${x}`,
request: request,
});
} else {
const nativeRectangle = imageryProvider._tilingScheme.tileXYToNativeRectangle(
x,
y,
level
);
const bbox = `${nativeRectangle.west},${nativeRectangle.south},${nativeRectangle.east},${nativeRectangle.north}`;
const query = {
bbox: bbox,
size: `${imageryProvider._tileWidth},${imageryProvider._tileHeight}`,
format: "png32",
transparent: true,
f: "image",
};
if (
imageryProvider._tilingScheme.projection instanceof Cesium.GeographicProjection
) {
query.bboxSR = 4326;
query.imageSR = 4326;
} else {
query.bboxSR = 3857;
query.imageSR = 3857;
}
if (imageryProvider.layers) {
query.layers = `show:${imageryProvider.layers}`;
}
resource = imageryProvider._resource.getDerivedResource({
url: "export",
request: request,
queryParameters: query,
});
}
return resource;
}
Object.defineProperties(CGCS2000ArcGisMapServerImageryProvider.prototype, {
/**
* Gets the URL of the ArcGIS MapServer.
* @memberof CGCS2000ArcGisMapServerImageryProvider.prototype
* @type {String}
* @readonly
*/
url: {
get: function () {
return this._resource._url;
},
},
/**
* Gets the ArcGIS token used to authenticate with the ArcGis MapServer service.
* @memberof CGCS2000ArcGisMapServerImageryProvider.prototype
* @type {String}
* @readonly
*/
token: {
get: function () {
return this._resource.queryParameters.token;
},
},
/**
* Gets the proxy used by this provider.
* @memberof CGCS2000ArcGisMapServerImageryProvider.prototype
* @type {Proxy}
* @readonly
*/
proxy: {
get: function () {
return this._resource.proxy;
},
},
/**
* Gets the width of each tile, in pixels. This function should
* not be called before {@link CGCS2000ArcGisMapServerImageryProvider#ready} returns true.
* @memberof CGCS2000ArcGisMapServerImageryProvider.prototype
* @type {Number}
* @readonly
*/
tileWidth: {
get: function () {
//>>includeStart('debug', pragmas.debug);
if (!this._ready) {
throw new Cesium.DeveloperError(
"tileWidth must not be called before the imagery provider is ready."
);
}
//>>includeEnd('debug');
return this._tileWidth;
},
},
/**
* Gets the height of each tile, in pixels. This function should
* not be called before {@link CGCS2000ArcGisMapServerImageryProvider#ready} returns true.
* @memberof CGCS2000ArcGisMapServerImageryProvider.prototype
* @type {Number}
* @readonly
*/
tileHeight: {
get: function () {
//>>includeStart('debug', pragmas.debug);
if (!this._ready) {
throw new Cesium.DeveloperError(
"tileHeight must not be called before the imagery provider is ready."
);
}
//>>includeEnd('debug');
return this._tileHeight;
},
},
/**
* Gets the maximum level-of-detail that can be requested. This function should
* not be called before {@link CGCS2000ArcGisMapServerImageryProvider#ready} returns true.
* @memberof CGCS2000ArcGisMapServerImageryProvider.prototype
* @type {Number|undefined}
* @readonly
*/
maximumLevel: {
get: function () {
//>>includeStart('debug', pragmas.debug);
if (!this._ready) {
throw new Cesium.DeveloperError(
"maximumLevel must not be called before the imagery provider is ready."
);
}
//>>includeEnd('debug');
return this._maximumLevel;
},
},
/**
* Gets the minimum level-of-detail that can be requested. This function should
* not be called before {@link CGCS2000ArcGisMapServerImageryProvider#ready} returns true.
* @memberof CGCS2000ArcGisMapServerImageryProvider.prototype
* @type {Number}
* @readonly
*/
minimumLevel: {
get: function () {
//>>includeStart('debug', pragmas.debug);
if (!this._ready) {
throw new Cesium.DeveloperError(
"minimumLevel must not be called before the imagery provider is ready."
);
}
//>>includeEnd('debug');
return 0;
},
},
/**
* Gets the tiling scheme used by this provider. This function should
* not be called before {@link CGCS2000ArcGisMapServerImageryProvider#ready} returns true.
* @memberof CGCS2000ArcGisMapServerImageryProvider.prototype
* @type {TilingScheme}
* @readonly
*/
tilingScheme: {
get: function () {
//>>includeStart('debug', pragmas.debug);
if (!this._ready) {
throw new Cesium.DeveloperError(
"tilingScheme must not be called before the imagery provider is ready."
);
}
//>>includeEnd('debug');
return this._tilingScheme;
},
},
/**
* Gets the rectangle, in radians, of the imagery provided by this instance. This function should
* not be called before {@link CGCS2000ArcGisMapServerImageryProvider#ready} returns true.
* @memberof CGCS2000ArcGisMapServerImageryProvider.prototype
* @type {Rectangle}
* @readonly
*/
rectangle: {
get: function () {
//>>includeStart('debug', pragmas.debug);
if (!this._ready) {
throw new Cesium.DeveloperError(
"rectangle must not be called before the imagery provider is ready."
);
}
//>>includeEnd('debug');
return this._rectangle;
},
},
/**
* Gets the tile discard policy. If not undefined, the discard policy is responsible
* for filtering out "missing" tiles via its shouldDiscardImage function. If this function
* returns undefined, no tiles are filtered. This function should
* not be called before {@link CGCS2000ArcGisMapServerImageryProvider#ready} returns true.
* @memberof CGCS2000ArcGisMapServerImageryProvider.prototype
* @type {TileDiscardPolicy}
* @readonly
*/
tileDiscardPolicy: {
get: function () {
//>>includeStart('debug', pragmas.debug);
if (!this._ready) {
throw new Cesium.DeveloperError(
"tileDiscardPolicy must not be called before the imagery provider is ready."
);
}
//>>includeEnd('debug');
return this._tileDiscardPolicy;
},
},
/**
* Gets an event that is raised when the imagery provider encounters an asynchronous error. By subscribing
* to the event, you will be notified of the error and can potentially recover from it. Event listeners
* are passed an instance of {@link TileProviderError}.
* @memberof CGCS2000ArcGisMapServerImageryProvider.prototype
* @type {Event}
* @readonly
*/
errorEvent: {
get: function () {
return this._errorEvent;
},
},
/**
* Gets a value indicating whether or not the provider is ready for use.
* @memberof CGCS2000ArcGisMapServerImageryProvider.prototype
* @type {Boolean}
* @readonly
*/
ready: {
get: function () {
return this._ready;
},
},
/**
* Gets a promise that resolves to true when the provider is ready for use.
* @memberof CGCS2000ArcGisMapServerImageryProvider.prototype
* @type {Promise.}
* @readonly
*/
readyPromise: {
get: function () {
return this._readyPromise.promise;
},
},
/**
* Gets the credit to display when this imagery provider is active. Typically this is used to credit
* the source of the imagery. This function should not be called before {@link CGCS2000ArcGisMapServerImageryProvider#ready} returns true.
* @memberof CGCS2000ArcGisMapServerImageryProvider.prototype
* @type {Credit}
* @readonly
*/
credit: {
get: function () {
return this._credit;
},
},
/**
* Gets a value indicating whether this imagery provider is using pre-cached tiles from the
* ArcGIS MapServer. If the imagery provider is not yet ready ({@link CGCS2000ArcGisMapServerImageryProvider#ready}), this function
* will return the value of `options.usePreCachedTilesIfAvailable`, even if the MapServer does
* not have pre-cached tiles.
* @memberof CGCS2000ArcGisMapServerImageryProvider.prototype
*
* @type {Boolean}
* @readonly
* @default true
*/
usingPrecachedTiles: {
get: function () {
return this._useTiles;
},
},
/**
* Gets a value indicating whether or not the images provided by this imagery provider
* include an alpha channel. If this property is false, an alpha channel, if present, will
* be ignored. If this property is true, any images without an alpha channel will be treated
* as if their alpha is 1.0 everywhere. When this property is false, memory usage
* and texture upload time are reduced.
* @memberof CGCS2000ArcGisMapServerImageryProvider.prototype
*
* @type {Boolean}
* @readonly
* @default true
*/
hasAlphaChannel: {
get: function () {
return true;
},
},
/**
* Gets the comma-separated list of layer IDs to show.
* @memberof CGCS2000ArcGisMapServerImageryProvider.prototype
*
* @type {String}
*/
layers: {
get: function () {
return this._layers;
},
},
});
/**
* Gets the credits to be displayed when a given tile is displayed.
*
* @param {Number} x The tile X coordinate.
* @param {Number} y The tile Y coordinate.
* @param {Number} level The tile level;
* @returns {Credit[]} The credits to be displayed when the tile is displayed.
*
* @exception {DeveloperError} getTileCredits must not be called before the imagery provider is ready.
*/
CGCS2000ArcGisMapServerImageryProvider.prototype.getTileCredits = function (
x,
y,
level
) {
return undefined;
};
/**
* Requests the image for a given tile. This function should
* not be called before {@link CGCS2000ArcGisMapServerImageryProvider#ready} returns true.
*
* @param {Number} x The tile X coordinate.
* @param {Number} y The tile Y coordinate.
* @param {Number} level The tile level.
* @param {Request} [request] The request object. Intended for internal use only.
* @returns {Promise.|undefined} A promise for the image that will resolve when the image is available, or
* undefined if there are too many active requests to the server, and the request
* should be retried later. The resolved image may be either an
* Image or a Canvas DOM object.
*
* @exception {DeveloperError} requestImage must not be called before the imagery provider is ready.
*/
CGCS2000ArcGisMapServerImageryProvider.prototype.requestImage = function (
x,
y,
level,
request
) {
//>>includeStart('debug', pragmas.debug);
if (!this._ready) {
throw new Cesium.DeveloperError(
"requestImage must not be called before the imagery provider is ready."
);
}
//>>includeEnd('debug');
level = level;
return Cesium.ImageryProvider.loadImage(
this,
buildImageResource(this, x, y, level, request)
);
};
/**
/**
* Asynchronously determines what features, if any, are located at a given longitude and latitude within
* a tile. This function should not be called before {@link ImageryProvider#ready} returns true.
*
* @param {Number} x The tile X coordinate.
* @param {Number} y The tile Y coordinate.
* @param {Number} level The tile level.
* @param {Number} longitude The longitude at which to pick features.
* @param {Number} latitude The latitude at which to pick features.
* @return {Promise.|undefined} A promise for the picked features that will resolve when the asynchronous
* picking completes. The resolved value is an array of {@link ImageryLayerFeatureInfo}
* instances. The array may be empty if no features are found at the given location.
*
* @exception {DeveloperError} pickFeatures must not be called before the imagery provider is ready.
*/
CGCS2000ArcGisMapServerImageryProvider.prototype.pickFeatures = function (
x,
y,
level,
longitude,
latitude
) {
//>>includeStart('debug', pragmas.debug);
if (!this._ready) {
throw new Cesium.DeveloperError(
"pickFeatures must not be called before the imagery provider is ready."
);
}
//>>includeEnd('debug');
if (!this.enablePickFeatures) {
return undefined;
}
const rectangle = this._tilingScheme.tileXYToNativeRectangle(x, y, level);
let horizontal;
let vertical;
let sr;
if (this._tilingScheme.projection instanceof Cesium.GeographicProjection) {
horizontal = Cesium.Math.toDegrees(longitude);
vertical = Cesium.Math.toDegrees(latitude);
sr = "4326";
} else {
const projected = this._tilingScheme.projection.project(
new Cesium.Cartographic(longitude, latitude, 0.0)
);
horizontal = projected.x;
vertical = projected.y;
sr = "3857";
}
let layers = "visible";
if (Cesium.defined(this._layers)) {
layers += `:${this._layers}`;
}
const query = {
f: "json",
tolerance: 2,
geometryType: "esriGeometryPoint",
geometry: `${horizontal},${vertical}`,
mapExtent: `${rectangle.west},${rectangle.south},${rectangle.east},${rectangle.north}`,
imageDisplay: `${this._tileWidth},${this._tileHeight},96`,
sr: sr,
layers: layers,
};
const resource = this._resource.getDerivedResource({
url: "identify",
queryParameters: query,
});
return resource.fetchJson().then(function (json) {
const result = [];
const features = json.results;
if (!Cesium.defined(features)) {
return result;
}
for (let i = 0; i < features.length; ++i) {
const feature = features[i];
const featureInfo = new Cesium.ImageryLayerFeatureInfo();
featureInfo.data = feature;
featureInfo.name = feature.value;
featureInfo.properties = feature.attributes;
featureInfo.configureDescriptionFromProperties(feature.attributes);
// If this is a point feature, use the coordinates of the point.
if (feature.geometryType === "esriGeometryPoint" && feature.geometry) {
const wkid =
feature.geometry.spatialReference &&
feature.geometry.spatialReference.wkid ?
feature.geometry.spatialReference.wkid :
4326;
if (wkid === 4326 || wkid === 4283) {
featureInfo.position = Cesium.Cartographic.fromDegrees(
feature.geometry.x,
feature.geometry.y,
feature.geometry.z
);
} else if (wkid === 102100 || wkid === 900913 || wkid === 3857) {
const projection = new Cesium.WebMercatorProjection();
featureInfo.position = projection.unproject(
new Cesium.Cartesian3(
feature.geometry.x,
feature.geometry.y,
feature.geometry.z
)
);
}
}
result.push(featureInfo);
}
return result;
});
};
Cesium.CGCS2000ArcGisMapServerImageryProvider = CGCS2000ArcGisMapServerImageryProvider;
}(Cesium));