|
// proj4.defs("EPSG:4544", "+proj=tmerc +lat_0=0 +lon_0=105 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs +type=crs");
|
var proj4 = null;
|
var webMercator = null;
|
// const epst4326 = proj4.defs("EPSG:4326");
|
|
/**
|
* The map projection used by Google Maps, Bing Maps, and most of ArcGIS Online, EPSG:3857. This
|
* projection use longitude and latitude expressed with the WGS84 and transforms them to Mercator using
|
* the spherical (rather than ellipsoidal) equations.
|
*
|
* @alias CustomMercatorProjection
|
* @constructor
|
*
|
* @param {Object} customEPSG 自定义的proj.defs对象,如proj4.defs("EPSG:4544")
|
* @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid.
|
*
|
* @see GeographicProjection
|
*/
|
var Cesium = null;
|
function CustomMercatorProjection(customEPSG, ellipsoid,CesiumN,proj) {
|
Cesium = CesiumN;
|
proj4 = proj;
|
webMercator = proj4.defs('EPSG:3857');
|
this._ellipsoid = Cesium.defaultValue(ellipsoid, Cesium.Ellipsoid.WGS84);
|
this._semimajorAxis = this._ellipsoid.maximumRadius;
|
this._oneOverSemimajorAxis = 1.0 / this._semimajorAxis;
|
this._customEPSG = customEPSG;
|
}
|
|
Object.defineProperties(CustomMercatorProjection.prototype, {
|
/**
|
* Gets the {@link Ellipsoid}.
|
*
|
* @memberof CustomMercatorProjection.prototype
|
*
|
* @type {Ellipsoid}
|
* @readonly
|
*/
|
ellipsoid: {
|
get: function () {
|
return this._ellipsoid;
|
},
|
},
|
});
|
|
/**
|
* Converts a Mercator angle, in the range -PI to PI, to a geodetic latitude
|
* in the range -PI/2 to PI/2.
|
*
|
* @param {Number} mercatorAngle The angle to convert.
|
* @returns {Number} The geodetic latitude in radians.
|
*/
|
CustomMercatorProjection.mercatorAngleToGeodeticLatitude = function (
|
mercatorAngle
|
) {
|
return (Math.PI / 2.0) - 2.0 * Math.atan(Math.exp(-mercatorAngle));
|
};
|
|
/**
|
* Converts a geodetic latitude in radians, in the range -PI/2 to PI/2, to a Mercator
|
* angle in the range -PI to PI.
|
*
|
* @param {Number} latitude The geodetic latitude in radians.
|
* @returns {Number} The Mercator angle.
|
*/
|
CustomMercatorProjection.geodeticLatitudeToMercatorAngle = function (latitude) {
|
// Clamp the latitude coordinate to the valid Mercator bounds.
|
if (latitude > CustomMercatorProjection.MaximumLatitude) {
|
latitude = CustomMercatorProjection.MaximumLatitude;
|
} else if (latitude < -CustomMercatorProjection.MaximumLatitude) {
|
latitude = -CustomMercatorProjection.MaximumLatitude;
|
}
|
const sinLatitude = Math.sin(latitude);
|
return 0.5 * Math.log((1.0 + sinLatitude) / (1.0 - sinLatitude));
|
};
|
|
/**
|
* The maximum latitude (both North and South) supported by a Web Mercator
|
* (EPSG:3857) projection. Technically, the Mercator projection is defined
|
* for any latitude up to (but not including) 90 degrees, but it makes sense
|
* to cut it off sooner because it grows exponentially with increasing latitude.
|
* The logic behind this particular cutoff value, which is the one used by
|
* Google Maps, Bing Maps, and Esri, is that it makes the projection
|
* square. That is, the rectangle is equal in the X and Y directions.
|
*
|
* The constant value is computed by calling:
|
* CustomMercatorProjection.mercatorAngleToGeodeticLatitude(Math.PI)
|
*
|
* @type {Number}
|
*/
|
CustomMercatorProjection.MaximumLatitude = CustomMercatorProjection.mercatorAngleToGeodeticLatitude(
|
Math.PI
|
);
|
|
/**
|
* Converts geodetic ellipsoid coordinates, in radians, to the equivalent Web Mercator
|
* X, Y, Z coordinates expressed in meters and returned in a {@link Cartesian3}. The height
|
* is copied unmodified to the Z coordinate.
|
*
|
* @param {Cartographic} cartographic The cartographic coordinates in radians.
|
* @param {Cartesian3} [result] The instance to which to copy the result, or undefined if a
|
* new instance should be created.
|
* @returns {Cartesian3} The equivalent web mercator X, Y, Z coordinates, in meters.
|
*/
|
CustomMercatorProjection.prototype.project = function (cartographic, result) {
|
const semimajorAxis = this._semimajorAxis;
|
const x1 = cartographic.longitude * semimajorAxis;
|
const y1 =
|
CustomMercatorProjection.geodeticLatitudeToMercatorAngle(
|
cartographic.latitude
|
) * semimajorAxis;
|
const z = cartographic.height;
|
const projectPos = proj4(webMercator,this._customEPSG, [x1,y1]);
|
|
if (!Cesium.defined(result)) {
|
return new Cesium.Cartesian3(projectPos[0], projectPos[1], z);
|
}
|
|
result.x = projectPos[0];
|
result.y = projectPos[1];
|
result.z = z;
|
return result;
|
};
|
|
/**
|
* Converts Web Mercator X, Y coordinates, expressed in meters, to a {@link Cartographic}
|
* containing geodetic ellipsoid coordinates. The Z coordinate is copied unmodified to the
|
* height.
|
*
|
* @param {Cartesian3} cartesian The web mercator Cartesian position to unrproject with height (z) in meters.
|
* @param {Cartographic} [result] The instance to which to copy the result, or undefined if a
|
* new instance should be created.
|
* @returns {Cartographic} The equivalent cartographic coordinates.
|
*/
|
CustomMercatorProjection.prototype.unproject = function (cartesian, result) {
|
//>>includeStart('debug', pragmas.debug);
|
if (!Cesium.defined(cartesian)) {
|
throw new Cesium.DeveloperError("cartesian is required");
|
}
|
//>>includeEnd('debug');
|
const unprojectPos = proj4(this._customEPSG, webMercator, [cartesian.x, cartesian.y]);
|
|
const oneOverEarthSemimajorAxis = this._oneOverSemimajorAxis;
|
const longitude = unprojectPos[0] * oneOverEarthSemimajorAxis;
|
const latitude = CustomMercatorProjection.mercatorAngleToGeodeticLatitude(
|
unprojectPos[1] * oneOverEarthSemimajorAxis
|
);
|
const height = cartesian.z;
|
|
if (!Cesium.defined(result)) {
|
return new Cesium.Cartographic(longitude, latitude, height);
|
}
|
|
result.longitude = longitude;
|
result.latitude = latitude;
|
result.height = height;
|
return result;
|
};
|
export default CustomMercatorProjection;
|