Openlayers 自定义投影坐标系数据转换以及在线转换工具
- OpenLayers 教程
- 查看 EPSG 码和定义
- Openlayers 自定义投影坐标系数据转换以及在线转换工具
- 在线示例
OpenLayers 教程
工作中经常会遇到转换坐标的情况,一般都会写代码搞定,但是有时候只需要查看一下数据,犯不上专门搞段代码,这里整个在线工具,提供使用。
内置了几个投影坐标系:EPSG: 4326、EPSG: 3857、EPSG: 2433、EPSG: 4610、EPSG: 4526。
除此之外,还支持自由参数输入,输入 EPSG 码和 definition 即可。
查看 EPSG 码和定义
1. 可以通过此网站 EPSG 查看 EPSG 码和定义。
2. 输入坐标系编码查询
3. 选择坐标系,点击进入,往下滑,找到 proj4js,右侧即投影坐标系定义。
Openlayers 自定义投影坐标系数据转换以及在线转换工具
<html lang="en">
<head>
<meta charSet="utf-8">
<!--注意:openlayers 原版的比较慢,这里引起自己服务器版-->
<link rel="stylesheet" href="http://openlayers.vip/examples/css/ol.css" type="text/css">
<style>
/* 注意:这里必须给高度,否则地图初始化之后不显示;一般是计算得到高度,然后才初始化地图 */
.map {
height: 500px;
width: 100%;
float: left;
}
.ol-zoom {
display: none;
}
#labelPopup {
background-color: white;
}
</style>
<!--注意:openlayers 原版的比较慢,这里引起自己服务器版-->
<script src="http://openlayers.vip/examples/resources/ol.js"></script>
<!--proj4 插件-->
<script src="http://openlayers.vip/examples/resources/proj4.js"></script>
<script src="./tiandituLayers.js"></script>
<title>OpenLayers example</title>
<script>
var _hmt = _hmt || [];
(function () {
var hm = document.createElement("script");
hm.src = "https://hm.baidu.com/hm.js?f80a36f14f8a73bb0f82e0fdbcee3058";
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(hm, s);
})();
</script>
</head>
<body>
<h2 style="height: 120px;">OpenLayers projection transfer --- 默认为多边形的转换,什么都不填可以转换默认数据。</h2>
<!--地图容器,需要指定 id -->
<div id="map" class="map"></div>
<H3>优先使用下拉框坐标系,如果填写了自定义坐标系,则使用自定义坐标系。</H3>
<p>先下拉框选择投影坐标系或者自定义输入坐标系和定义,再输入数据进行转换。</p>
<div style="position: absolute;top: 54px;left:10px;">
<div>
<div>
<span>原投影坐标:</span>
<select name="" id="origin" style="height: 30px;width: 100px;margin-left: 16px">
<!--各种数据类型-->
<option value="EPSG:4326">默认为WGS84,请选择投影坐标--</option>
<option value="EPSG:3857">Web墨卡托</option>
<option value="EPSG:4214">北京54</option>
<option value="EPSG:4610">西安80</option>
<option value="EPSG:4555">新北京</option>
<option value="EPSG:2433">Beijing_1954_3_Degree_GK_CM_108E</option>
<option value="EPSG:4527">CGCS2000_3_Degree_GK_Zone_39</option>
</select>
<span>
自定义坐标系:
</span>
<span>
<input style="width: 208px" type="text" id="origin_epsg_code" placeholder="坐标系编码,比如:EPSG:4326">
</span>
<span>
<input style="width: 436px" type="text" id="origin_epsg_definition"
placeholder="坐标系定义,比如:+proj=longlat +datum=WGS84 +no_defs +type=crs">
</span>
</div>
<br/>
<div>
<span>转换投影坐标:</span>
<select name="" id="toData" style="height: 30px;width: 100px;">
<!--各种数据类型-->
<option value="EPSG:4326">默认为WGS84,请选择投影坐标--</option>
<option value="EPSG:3857">Web墨卡托</option>
<option value="EPSG:4214">北京54</option>
<option value="EPSG:4610">西安80</option>
<option value="EPSG:4555">新北京</option>
<option value="EPSG:2433">Beijing_1954_3_Degree_GK_CM_108E</option>
<option value="EPSG:4527">CGCS2000_3_Degree_GK_Zone_39</option>
</select>
<span>
自定义坐标系:
</span>
<span>
<input style="width: 208px" type="text" id="to_epsg_code" placeholder="坐标系编码,比如:EPSG:4326">
</span>
<span>
<input style="width: 436px" type="text" id="to_epsg_definition"
placeholder="坐标系定义,比如:+proj=longlat +datum=WGS84 +no_defs +type=crs">
</span>
</div>
</div>
</div>
<!--原始数据以及转换后数据-->
<textarea style="position:absolute;top:160px" id="result" cols="50" rows="30"></textarea>
<script type="text/javascript">
var map = new ol.Map({
// 地图容器
target: 'map',
// 地图图层,比如底图、矢量图等
layers: [
getIMG_CLayer(),
getIBO_CLayer(),
getCIA_CLayer(),
],
// 地图视野
view: new ol.View({
projection: "EPSG:4326",
// 定位
center: [115.67724700667199, 37.73879478106912],
// 缩放
zoom: 6,
maxZoom: 18,
minZoom: 1,
})
});
var defaultStyle = new ol.style.Style({
//边框样式
stroke: new ol.style.Stroke({
color: 'red',
width: 3,
}),
//填充样式
fill: new ol.style.Fill({
color: 'rgba(0, 0, 255, 0.3)',
}),
})
// 初始化图层
var layer = initVectorLayer();
// 默认多边形
const polygonStr = "POLYGON((116.25730023609182 39.99408085954892,116.255712368355 39.99236424577939,116.25476823078176 39.9906905473541,116.255712368355 39.98815854204404,116.25704274402639 39.98742898119199,116.25802979694387 39.98687108171689,116.2591885112383 39.9846394838165,116.26227841602346 39.983051616079685,116.26382336841604 39.981292086965915,116.26562581287405 39.981034594900486,116.26695618854544 39.980777102835056,116.26875863300344 39.981034594900486,116.27021775470755 39.981549579031345,116.27163396106741 39.98043378008115,116.2724064372637 39.97991879595029,116.27408013568899 39.98017628801572,116.27146229969046 39.98395283830869,116.2727497600176 39.988759356863376,116.27064690814993 39.98966057909238,116.26978860126516 39.98966057909238,116.26935944782278 39.990046817190525,116.25730023609182 39.99408085954892))";
/**
* @todo 矢量图层
* @returns {VectorLayer}
* @constructor
*/
function initVectorLayer() {
//实例化一个矢量图层Vector作为绘制层
let source = new ol.source.Vector();
//创建一个图层
let customVectorLayer = new ol.layer.Vector({
source: source,
zIndex: 2,
//设置样式
style: defaultStyle,
});
//将绘制层添加到地图容器中
map.addLayer(customVectorLayer);
return customVectorLayer;
}
/**
* @todo wkt格式数据转化成图形对象
* @param {string} wkt "POINT(112.7197265625,39.18164062499999)" 格式数据
* @param {string|Projection} sourceCode 源投影坐标系
* @param {string|Projection} targetCode 目标投影坐标系
* @returns {Feature}
*/
function getFeatureByWKT(wkt, sourceCode, targetCode) {
try {
let view = map.getView();
if (!wkt) {
return null;
}
let format = new ol.format.WKT();
let feature;
feature = format.readFeature(wkt, {
featureProjection: targetCode || view.getProjection(),
dataProjection: sourceCode || view.getProjection(),
});
return feature;
} catch (e) {
console.log(e);
return null;
}
}
/**
* @Todo 将feature 转化成wkt格式
* 大地坐标转地理坐标,可以先new feature 然后转为wkt(设置转换 'EPSG:4326' 'EPSG:3857'),在转回feature即可
* @method getWKTByFeatures
* @param feature 参数为feature对象
* @param code 坐标系
* @returns str 返回wkt数据
*/
function getWKTByFeature(feature, sourceCode, targetCode, type) {
try {
let view = map.getView();
if (!feature) {
return null;
}
let format = new ol.format.WKT();
if (feature instanceof Array) {
if (type) {
let arr = [];
for (let i = 0; i < feature.length; i++) {
arr.push(format.writeFeature(feature[i], {
//传入feature的坐标系
featureProjection: sourceCode || view.getProjection(),
//返回数据的坐标系
dataProjection: targetCode || view.getProjection()
}))
}
return arr.join('#');
} else {
return format.writeFeatures(feature, {
//传入feature的坐标系
featureProjection: sourceCode || view.getProjection(),
//返回数据的坐标系
dataProjection: targetCode || view.getProjection()
});
}
} else {
return format.writeFeature(feature, {
//传入feature的坐标系
featureProjection: sourceCode || view.getProjection(),
//返回数据的坐标系
dataProjection: targetCode || view.getProjection()
});
}
} catch (e) {
console.log(e);
return null
}
}
// 定位
function moveTo(layerTemp) {
layerTemp && map.getView().fit(layerTemp.getSource().getExtent(), {
duration: 1,//动画的持续时间,
callback: null,
});
}
// 注册投影坐标系
function registerEPSG() {
proj4.defs("EPSG:4214", "+proj=longlat +ellps=krass +towgs84=15.8,-154.4,-82.3,0,0,0,0 +no_defs +type=crs");
ol.proj.proj4.register(proj4);
proj4.defs("EPSG:4610", "+proj=longlat +ellps=IAU76 +no_defs +type=crs");
ol.proj.proj4.register(proj4);
proj4.defs("EPSG:2433", "+proj=tmerc +lat_0=0 +lon_0=108 +k=1 +x_0=500000 +y_0=0 +ellps=krass +towgs84=11.911,-154.833,-80.079,0,0,0,0 +units=m +no_defs +type=crs");
ol.proj.proj4.register(proj4);
proj4.defs("EPSG:4527", "+proj=tmerc +lat_0=0 +lon_0=117 +k=1 +x_0=39500000 +y_0=0 +ellps=GRS80 +units=m +no_defs +type=crs");
ol.proj.proj4.register(proj4);
proj4.defs("EPSG:4490", "+proj=longlat +ellps=GRS80 +no_defs +type=crs");
ol.proj.proj4.register(proj4);
proj4.defs("EPSG:4555", "+proj=longlat +ellps=krass +no_defs +type=crs");
ol.proj.proj4.register(proj4);
}
registerEPSG();
// 原始数据
let originData;
// 过程数据
let tempData;
// 转换方法
function transfer() {
// 原数据类型
let origin = document.getElementById("origin")
let originIndex = origin.selectedIndex;
let originSelect = origin.options[originIndex].value;
// 自定义投影坐标系
let originInputCode = document.getElementById("origin_epsg_code").value;
let originInputDefinition = document.getElementById("origin_epsg_definition").value;
// 如果填写自定义坐标系,则注册
if (originInputCode && originInputDefinition) {
proj4.defs(originInputCode, originInputDefinition);
ol.proj.proj4.register(proj4);
}
// 转换数据类型
var toData = document.getElementById("toData")
let toDataIndex = toData.selectedIndex;
let toDataSelect = toData.options[toDataIndex].value;
// 自定义转换投影坐标系
let toInputCode = document.getElementById("to_epsg_code").value;
let toInputDefinition = document.getElementById("to_epsg_definition").value;
// 如果填写自定义坐标系,则注册
if (toInputCode && toInputDefinition) {
proj4.defs(toInputCode, toInputDefinition);
ol.proj.proj4.register(proj4);
}
// 显示数据
tempData = document.getElementById("result").value;
// 记录原数据
originData = originData || tempData;
// 过程图形要素
let featureTemp = getFeatureByWKT(tempData || polygonStr,
originInputCode ? ol.proj.get(originInputCode) : ol.proj.get(originSelect), ol.proj.get('EPSG:4326'));
layer.getSource().addFeatures([featureTemp]);
moveTo(layer)
// 填充数据
document.getElementById("result").value = getWKTByFeature(featureTemp,
ol.proj.get('EPSG:4326'), toInputCode ? ol.proj.get(toInputCode) : ol.proj.get(toDataSelect));
// 重新设置下拉框类型
set_select_checked('origin', toDataSelect);
}
/**
* 设置select控件选中
* @param selectId select的id值
* @param checkValue 选中option的值
*/
function set_select_checked(selectId, checkValue) {
var select = document.getElementById(selectId);
for (var i = 0; i < select.options.length; i++) {
if (select.options[i].value == checkValue) {
select.options[i].selected = true;
break;
}
}
}
// 清空数据
function restore() {
layer.getSource().clear();
document.getElementById("result").value = '';
document.getElementById("origin").options[0].selected = true;
document.getElementById("toData").options[0].selected = true;
}
</script>
<button id="transfer" onClick="transfer()">转换</button>
<button id="restore" onClick="restore()">清除</button>
</body>
</html>
在线示例
Openlayers 自定义投影坐标系转换工具:OpenLayers projection transfer