原文链接
非原创,记录下来备用
EPSG的英文全称是European Petroleum Survey Group,中文名称为欧洲石油调查组织。这个组织成立于1986年,2005年并入IOGP(International Association of Oil & Gas Producers),中文名称为国际油气生产者协会。EPSG对世界的每一个地方都制定了地图,但是由于座标系不同,所以地图也各不相同。
比如对于中国来讲,以地球的几何球心为中心的地图就是EPSG:4479,以地球的椭球焦点为中心就是EPSG:4480,此外还有EPSG:4490,因为选择不同的座标系对于油气勘探的成本至关重要,所以有不同的座标系。
EPSG:4326
在世界地图方面,EPSG:4326是比较著名的一个,因为由美国主导的GPS系统就是在用它,它还有一个名气更大的别名叫作WGS84,WGS(World Geodetic System)是世界大地测量系统的意思,由于是1984年定义的,所以叫WGS84,之前的版本还有WGS72、WGS66、WGS60。
EPSG:3857
另一个比较知名的编码是EPSG:3857,这也是一张世界地图,目前主要是各大互联网地图公司以它为基准,例如Google地图,Microsoft地图都在用它。
所有这些EPSG
编码的具体含义都可以在https://epsg.io上查到。
本功能实现中国区域,
主功能代码:
简单分析一下代码。
想要通过proj4.js对投影坐标进行转换处理,需要:输入坐标系的EPSG、输出坐标系的EPSG、X值和Y值。而用户输入:x值、y值、输入数据的坐标系、输入数据的投影带宽度、输出数据的坐标系、输出数据的投影带宽度。
用户需要自己定义相应的EPSGid。
proj4.defs("EPSG:2401", "+proj=tmerc +lat_0=0 +lon_0=75 +k=1 +x_0=25500000 +y_0=0 +ellps=krass +units=m +no_defs "); //北京1954-3度分带-高斯克吕格投影-zone-25----73.5°E to 76.5°E
代码入口处分成了2类。
整个过程:得到带号(非必须) ---> 得到输入数据和输出数据的EPSGid ---> 通过proj4方法进行转换
得到带号:bandNumberCalculation()方法
对输入的坐标进行分析,若x值小于180,则为输入数据为地理坐标系的经纬度值,对输入的投影带宽度(6、3)进行判定,得到该位置的带号。若x值大于180,则输入数据为投影坐标系,通过extractBandNumber()方法,得到输入X值得前2位,前2位即该投影坐标的带号。
得到EPSGid。confirmEPSGid()方法
在JSONData.js文件中,存储了需要调用的EPSGid,所以需要拼凑出有规律的唯一id,通过key得到存储在json中的id。JSONData.js文件中的key是通过 坐标系+带宽+带号 来区分的(例如:BJ54_zone_3_32)。所以通过case输入的坐标系,按照规则获得存储的EPSGid。注意:WGS84的UTM投影坐标系,带号起点计算是从180度经线自西向东计算,而高斯克吕格投影的带号计算是从0度经线开始计算,所以2种投影方式计算得到的带号是不同的。
通过proj4方法进行转换。conversionMethod()方法
var firstProjection = new proj4.Proj("EPSG:" + firstEPSGid);
var secondProjection = new proj4.Proj("EPSG:" + secondEPSGid);
var result = proj4.transform(firstProjection, secondProjection, [longitude, latitude]);
return result;
通过以上代码,输入参数,返回值为object,里面包含x,y属性
全部代码
/**
* 投影转换方法
* @param longitude 经度 x值
* @param latitude 纬度 y值
* @param firstCoordinateSystem 输入数据的坐标系 取值:BJ54_zone; BJ54_CM; BJ54; Xian80_zone; Xian80_CM; Xian80;
* @param firstProjectedBandWidth 输入数据的投影带宽度 取值: 3 , 6 , 0
* @param secondCoordinateSystem 输出数据的坐标系 取值:BJ54_zone; BJ54_CM; BJ54; Xian80_zone; Xian80_CM; Xian80;
* @param secondProjectedBandWidth 输出数据的投影带宽度 取值: 3 , 6 , 0
* @returns result 输出结果,类型为object类,里面包含 x,y 属性
*/
function projectionConversionMethod(longitude, latitude, firstCoordinateSystem, firstProjectedBandWidth, secondCoordinateSystem, secondProjectedBandWidth) {
// 输出数据
var result; //输出结果,类型为object类,里面包含 x,y 属性
//如果带宽1与带宽2都不为零,且带宽1不等于带宽2
if ((firstProjectedBandWidth + secondProjectedBandWidth) === 9) {
var middleCoordinateSystem = getGeographic(firstCoordinateSystem);
var obj = projectionConversionMethod(longitude, latitude, firstCoordinateSystem, firstProjectedBandWidth, middleCoordinateSystem, 0);
result = projectionConversionMethod(obj.x, obj.y, middleCoordinateSystem, 0, secondCoordinateSystem, secondProjectedBandWidth);
return result;
} else {
result = mainMethod(longitude, latitude, firstCoordinateSystem, firstProjectedBandWidth, secondCoordinateSystem, secondProjectedBandWidth);
return result;
}
}
/**
* 带号-->EPSGid-->result
* @param longitude
* @param latitude
* @param firstCoordinateSystem
* @param firstProjectedBandWidth
* @param secondCoordinateSystem
* @param secondProjectedBandWidth
* @returns {result}
*/
function mainMethod(longitude, latitude, firstCoordinateSystem, firstProjectedBandWidth, secondCoordinateSystem, secondProjectedBandWidth) {
// 通过输入数据计算获得
// var firstBandNumber 输入数据的带号
// var secondBandNumber 输出数据的带号
// var firstEPSGid 输入的坐标系的EPSG Id
// var secondEPSGid 输出的坐标系的EPSG Id
//得到带号
var firstBandNumber = bandNumberCalculation(longitude, firstProjectedBandWidth);
var secondBandNumber = bandNumberCalculation(longitude, secondProjectedBandWidth);
//得到输入EPSGid和输出EPSGid
var firstEPSGid = confirmEPSGid(firstCoordinateSystem, firstProjectedBandWidth, firstBandNumber);
var secondEPSGid = confirmEPSGid(secondCoordinateSystem, secondProjectedBandWidth, secondBandNumber);
return conversionMethod(longitude, latitude, firstEPSGid, secondEPSGid);
}
/**
* 确定数据的EPSGid
* @param coordinateValue 传入 用户定义的 数据的坐标系 的值
* @param bandWidth 传入 用户定义的 投影带宽度 的值
* @param bandNumber 传入 带号
*/
function confirmEPSGid(coordinateValue, bandWidth, bandNumber) {
var EPSGid;
var key = coordinateValue + "_" + bandWidth + "_" + bandNumber;
switch (coordinateValue) {
case "BJ54":
EPSGid = BJ54_JSON[coordinateValue];
break;
case "Xian80":
EPSGid = Xian80_JSON[coordinateValue];
break;
case "CGCS2000":
EPSGid = CGCS2000_JSON[coordinateValue];
break;
case "WGS84": //WGS 84-WGS84-1984年世界大地测量系统,用于GPS
EPSGid = "4326";
break;
case "webMercator": //WGS 84 /伪墨卡托-球形墨卡托,谷歌地图,OpenStreetMap,必应,ArcGIS,ESRI
EPSGid = "3857";
break;
case "WGS84UTM": //仅限中国区域
key = "WGS84UTM_zone_" + (bandNumber+30) + "N";
EPSGid = WGS84UTM_JSON[key];
break;
case "BJ54_zone":
case "BJ54_CM":
EPSGid = BJ54_JSON[key];
break;
case "Xian80_zone":
case "Xian80_CM":
EPSGid = Xian80_JSON[key];
break;
case "CGCS2000_zone":
case "CGCS2000_CM":
EPSGid = CGCS2000_JSON[key];
break;
default:
alert("输入坐标系有误!");
}
return EPSGid;
}
/**
* 投影带的带号计算:通过用户输入的经纬度及定义的投影带宽度,得到该经纬度下投影带的带号
* @param long 输入 用户输入的经度
* @param projectedBandWidth 输入 用户定义的投影带宽度
* @returns {number} 返回 经纬度下投影带的带号
*/
function bandNumberCalculation(long, projectedBandWidth) {
var num;
if (long <= 180) {
if (projectedBandWidth === 6) {
num = Math.floor(long / projectedBandWidth) + 1;
} else if (projectedBandWidth === 3) {
num = Math.floor((long - 1.5) / projectedBandWidth) + 1;
} else {
num = 0;
}
} else {
num = extractBandNumber(long);
}
return num;
}
/**
* 输入经纬度及EPSGid,得到转换后的结果
* @param longitude 经度
* @param latitude 纬度
* @param firstEPSGid 输入坐标系的EPSGid
* @param secondEPSGid 输出坐标系的EPSGid
* @returns result 输出结果,类型为object类,里面包含 x,y 属性
*/
function conversionMethod(longitude, latitude, firstEPSGid, secondEPSGid) {
var firstProjection = new proj4.Proj("EPSG:" + firstEPSGid);
var secondProjection = new proj4.Proj("EPSG:" + secondEPSGid);
var result = proj4.transform(firstProjection, secondProjection, [longitude, latitude]);
return result;
}
/**
* 从投影坐标的 x 值中提取前2位,作为带号
* @param value 传入投影坐标的 x 值
* @returns {number} 将带号返回
*/
function extractBandNumber(value) {
var str = String(value);
var num = str.substring(0, 2);
return Number(num);
}
/**
* 通过名称处理,得到投影坐标系对应的地理坐标系
* @param projection 传入投影坐标系的名称
* @returns {string} 返回对应的地理坐标系的名称
*/
function getGeographic(projection) {
var num_ = projection.indexOf("_");
return projection.substring(0, num_);
}
var BJ54_JSON = {
"BJ54_zone_3_25": "2401",
"BJ54_zone_3_26": "2402",
"BJ54_zone_3_27": "2403",
"BJ54_zone_3_28": "2404",
"BJ54_zone_3_29": "2405",
"BJ54_zone_3_30": "2406",
"BJ54_zone_3_31": "2407",
"BJ54_zone_3_32": "2408",
"BJ54_zone_3_33": "2409",
"BJ54_zone_3_34": "2410",
"BJ54_zone_3_35": "2411",
"BJ54_zone_3_36": "2412",
"BJ54_zone_3_37": "2413",
"BJ54_zone_3_38": "2414",
"BJ54_zone_3_39": "2415",
"BJ54_zone_3_40": "2416",
"BJ54_zone_3_41": "2417",
"BJ54_zone_3_42": "2418",
"BJ54_zone_3_43": "2419",
"BJ54_zone_3_44": "2420",
"BJ54_zone_3_45": "2421",
"BJ54_CM_3_25": "2422",
"BJ54_CM_3_26": "2423",
"BJ54_CM_3_27": "2424",
"BJ54_CM_3_28": "2425",
"BJ54_CM_3_29": "2426",
"BJ54_CM_3_30": "2427",
"BJ54_CM_3_31": "2428",
"BJ54_CM_3_32": "2429",
"BJ54_CM_3_33": "2430",
"BJ54_CM_3_34": "2431",
"BJ54_CM_3_35": "2432",
"BJ54_CM_3_36": "2433",
"BJ54_CM_3_37": "2434",
"BJ54_CM_3_38": "2435",
"BJ54_CM_3_39": "2436",
"BJ54_CM_3_40": "2437",
"BJ54_CM_3_41": "2438",
"BJ54_CM_3_42": "2439",
"BJ54_CM_3_43": "2440",
"BJ54_CM_3_44": "2441",
"BJ54_CM_3_45": "2442",
"BJ54_zone_6_13": "21413",
"BJ54_zone_6_14": "21414",
"BJ54_zone_6_15": "21415",
"BJ54_zone_6_16": "21416",
"BJ54_zone_6_17": "21417",
"BJ54_zone_6_18": "21418",
"BJ54_zone_6_19": "21419",
"BJ54_zone_6_20": "21420",
"BJ54_zone_6_21": "21421",
"BJ54_zone_6_22": "21422",
"BJ54_zone_6_23": "21423",
"BJ54_CM_6_13": "21453",
"BJ54_CM_6_14": "21454",
"BJ54_CM_6_15": "21455",
"BJ54_CM_6_16": "21456",
"BJ54_CM_6_17": "21457",
"BJ54_CM_6_18": "21458",
"BJ54_CM_6_19": "21459",
"BJ54_CM_6_20": "21460",
"BJ54_CM_6_21": "21461",
"BJ54_CM_6_22": "21462",
"BJ54_CM_6_23": "21463",
"BJ54": "4214",
};
//北京54--3度带--zone
proj4.defs("EPSG:2401", "+proj=tmerc +lat_0=0 +lon_0=75 +k=1 +x_0=25500000 +y_0=0 +ellps=krass +units=m +no_defs "); //北京1954-3度分带-高斯克吕格投影-zone-25----73.5°E to 76.5°E
proj4.defs("EPSG:2402", "+proj=tmerc +lat_0=0 +lon_0=78 +k=1 +x_0=26500000 +y_0=0 +ellps=krass +units=m +no_defs "); //北京1954-3度分带-高斯克吕格投影-zone-26----76.5°E to 79.5°E
proj4.defs("EPSG:2403", "+proj=tmerc +lat_0=0 +lon_0=81 +k=1 +x_0=27500000 +y_0=0 +ellps=krass +units=m +no_defs "); //北京1954-3度分带-高斯克吕格投影-zone-27----79.5°E to 82.5°E
proj4.defs("EPSG:2404", "+proj=tmerc +lat_0=0 +lon_0=84 +k=1 +x_0=28500000 +y_0=0 +ellps=krass +units=m +no_defs "); //北京1954-3度分带-高斯克吕格投影-zone-28----82.5°E to 85.5°E
proj4.defs("EPSG:2405", "+proj=tmerc +lat_0=0 +lon_0=87 +k=1 +x_0=29500000 +y_0=0 +ellps=krass +units=m +no_defs "); //北京1954-3度分带-高斯克吕格投影-zone-29----85.5°E to 88.5°E
proj4.defs("EPSG:2406", "+proj=tmerc +lat_0=0 +lon_0=90 +k=1 +x_0=30500000 +y_0=0 +ellps=krass +units=m +no_defs "); //北京1954-3度分带-高斯克吕格投影-zone-30----88.5°E to 91.5°E
proj4.defs("EPSG:2407", "+proj=tmerc +lat_0=0 +lon_0=93 +k=1 +x_0=31500000 +y_0=0 +ellps=krass +units=m +no_defs "); //北京1954-3度分带-高斯克吕格投影-zone-31----91.5°E to 94.5°E
proj4.defs("EPSG:2408", "+proj=tmerc +lat_0=0 +lon_0=96 +k=1 +x_0=32500000 +y_0=0 +ellps=krass +units=m +no_defs "); //北京1954-3度分带-高斯克吕格投影-zone-32----94.5°E to 97.5°E
proj4.defs("EPSG:2409", "+proj=tmerc +lat_0=0 +lon_0=99 +k=1 +x_0=33500000 +y_0=0 +ellps=krass +units=m +no_defs "); //北京1954-3度分带-高斯克吕格投影-zone-33----97.5°E to 100.5°E
proj4.defs("EPSG:2410", "+proj=tmerc +lat_0=0 +lon_0=102 +k=1 +x_0=34500000 +y_0=0 +ellps=krass +units=m +no_defs "); //北京1954-3度分带-高斯克吕格投影-zone-34----100.5°E to 103.5°E
proj4.defs("EPSG:2411", "+proj=tmerc +lat_0=0 +lon_0=105 +k=1 +x_0=35500000 +y_0=0 +ellps=krass +units=m +no_defs "); //北京1954-3度分带-高斯克吕格投影-zone-35----103.5°E to 106.5°E
proj4.defs("EPSG:2412", "+proj=tmerc +lat_0=0 +lon_0=108 +k=1 +x_0=36500000 +y_0=0 +ellps=krass +units=m +no_defs "); //北京1954-3度分带-高斯克吕格投影-zone-36----106.5°E to 109.5°E
proj4.defs("EPSG:2413", "+proj=tmerc +lat_0=0 +lon_0=111 +k=1 +x_0=37500000 +y_0=0 +ellps=krass +units=m +no_defs "); //北京1954-3度分带-高斯克吕格投影-zone-37----109.5°E to 112.5°E
proj4.defs("EPSG:2414", "+proj=tmerc +lat_0=0 +lon_0=114 +k=1 +x_0=38500000 +y_0=0 +ellps=krass +units=m +no_defs "); //北京1954-3度分带-高斯克吕格投影-zone-38----112.5°E to 115.5°E
proj4.defs("EPSG:2415", "+proj=tmerc +lat_0=0 +lon_0=117 +k=1 +x_0=39500000 +y_0=0 +ellps=krass +units=m +no_defs "); //北京1954-3度分带-高斯克吕格投影-zone-39----115.5°E to 118.5°E
proj4.defs("EPSG:2416", "+proj=tmerc +lat_0=0 +lon_0=120 +k=1 +x_0=40500000 +y_0=0 +ellps=krass +units=m +no_defs "); //北京1954-3度分带-高斯克吕格投影-zone-40----118.5°E to 121.5°E
proj4.defs("EPSG:2417", "+proj=tmerc +lat_0=0 +lon_0=123 +k=1 +x_0=41500000 +y_0=0 +ellps=krass +units=m +no_defs "); //北京1954-3度分带-高斯克吕格投影-zone-41----121.5°E to 124.5°E
proj4.defs("EPSG:2418", "+proj=tmerc +lat_0=0 +lon_0=126 +k=1 +x_0=42500000 +y_0=0 +ellps=krass +units=m +no_defs "); //北京1954-3度分带-高斯克吕格投影-zone-42----124.5°E to 127.5°E
proj4.defs("EPSG:2419", "+proj=tmerc +lat_0=0 +lon_0=129 +k=1 +x_0=43500000 +y_0=0 +ellps=krass +units=m +no_defs "); //北京1954-3度分带-高斯克吕格投影-zone-43----127.5°E to 130.5°E
proj4.defs("EPSG:2420", "+proj=tmerc +lat_0=0 +lon_0=132 +k=1 +x_0=44500000 +y_0=0 +ellps=krass +units=m +no_defs "); //北京1954-3度分带-高斯克吕格投影-zone-44----130.5°E to 133.5°E
proj4.defs("EPSG:2421", "+proj=tmerc +lat_0=0 +lon_0=135 +k=1 +x_0=45500000 +y_0=0 +ellps=krass +units=m +no_defs "); //北京1954-3度分带-高斯克吕格投影-zone-45----133.5°E to 136.5°E
//北京54--3度带--CM
proj4.defs("EPSG:2422", "+proj=tmerc +lat_0=0 +lon_0=75 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m +no_defs "); //北京1954-3度分带-高斯克吕格投影-CM-75E----73.5°E to 76.5°E
proj4.defs("EPSG:2423", "+proj=tmerc +lat_0=0 +lon_0=78 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m +no_defs "); //北京1954-3度分带-高斯克吕格投影-CM-78E----76.5°E to 79.5°E
proj4.defs("EPSG:2424", "+proj=tmerc +lat_0=0 +lon_0=81 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m +no_defs "); //北京1954-3度分带-高斯克吕格投影-CM-81E----79.5°E to 82.5°E
proj4.defs("EPSG:2425", "+proj=tmerc +lat_0=0 +lon_0=84 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m +no_defs "); //北京1954-3度分带-高斯克吕格投影-CM-84E----82.5°E to 85.5°E
proj4.defs("EPSG:2426", "+proj=tmerc +lat_0=0 +lon_0=87 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m +no_defs "); //北京1954-3度分带-高斯克吕格投影-CM-87E----85.5°E to 88.5°E
proj4.defs("EPSG:2427", "+proj=tmerc +lat_0=0 +lon_0=90 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m +no_defs "); //北京1954-3度分带-高斯克吕格投影-CM-90E----88.5°E to 91.5°E
proj4.defs("EPSG:2428", "+proj=tmerc +lat_0=0 +lon_0=93 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m +no_defs "); //北京1954-3度分带-高斯克吕格投影-CM-93E----91.5°E to 94.5°E
proj4.defs("EPSG:2429", "+proj=tmerc +lat_0=0 +lon_0=96 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m +no_defs "); //北京1954-3度分带-高斯克吕格投影-CM-96E----94.5°E to 97.5°E
proj4.defs("EPSG:2430", "+proj=tmerc +lat_0=0 +lon_0=99 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m +no_defs "); //北京1954-3度分带-高斯克吕格投影-CM-99E----97.5°E to 100.5°E
proj4.defs("EPSG:2431", "+proj=tmerc +lat_0=0 +lon_0=102 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m +no_defs "); //北京1954-3度分带-高斯克吕格投影-CM-102E----100.5°E to 103.5°E
proj4.defs("EPSG:2432", "+proj=tmerc +lat_0=0 +lon_0=105 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m +no_defs "); //北京1954-3度分带-高斯克吕格投影-CM-105E----103.5°E to 106.5°E
proj4.defs("EPSG:2433", "+proj=tmerc +lat_0=0 +lon_0=108 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m +no_defs "); //北京1954-3度分带-高斯克吕格投影-CM-108E----106.5°E to 109.5°E
proj4.defs("EPSG:2434", "+proj=tmerc +lat_0=0 +lon_0=111 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m +no_defs "); //北京1954-3度分带-高斯克吕格投影-CM-111E----109.5°E to 112.5°E
proj4.defs("EPSG:2435", "+proj=tmerc +lat_0=0 +lon_0=114 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m +no_defs "); //北京1954-3度分带-高斯克吕格投影-CM-114E----112.5°E to 115.5°E
proj4.defs("EPSG:2436", "+proj=tmerc +lat_0=0 +lon_0=117 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m +no_defs "); //北京1954-3度分带-高斯克吕格投影-CM-117E----115.5°E to 118.5°E
proj4.defs("EPSG:2437", "+proj=tmerc +lat_0=0 +lon_0=120 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m +no_defs "); //北京1954-3度分带-高斯克吕格投影-CM-120E----118.5°E to 121.5°E
proj4.defs("EPSG:2438", "+proj=tmerc +lat_0=0 +lon_0=123 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m +no_defs "); //北京1954-3度分带-高斯克吕格投影-CM-123E----121.5°E to 124.5°E
proj4.defs("EPSG:2439", "+proj=tmerc +lat_0=0 +lon_0=126 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m +no_defs "); //北京1954-3度分带-高斯克吕格投影-CM-126E----124.5°E to 127.5°E
proj4.defs("EPSG:2440", "+proj=tmerc +lat_0=0 +lon_0=129 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m +no_defs "); //北京1954-3度分带-高斯克吕格投影-CM-129E----127.5°E to 130.5°E
proj4.defs("EPSG:2441", "+proj=tmerc +lat_0=0 +lon_0=132 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m +no_defs "); //北京1954-3度分带-高斯克吕格投影-CM-132E----130.5°E to 133.5°E
proj4.defs("EPSG:2442", "+proj=tmerc +lat_0=0 +lon_0=135 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m +no_defs "); //北京1954-3度分带-高斯克吕格投影-CM-135E----133.5°E to 136.5°E