; (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));