基于proj4.js实现在web端定义坐标系及应用

一、背景

        proj4是一个JavaScript库,它专注于地图投影的表达以及转换。采用一种非常简单明了的投影表达--PROJ4,比其它的投影定义简单,明显。很容易就能看到各种地理坐标系和地图投影的参数,同时它有强大的坐标转换功能。
目前 proj4支持的坐标参考系有
在这里插入图片描述

二、 下载proj4的包

http://trac.osgeo.org/proj4js/wiki/Download

三、 引用proj4的包

三种方式:
1、npm install proj4
2、从proj4的下载地址下载对应版本,然后从下载的包中的dist/文件夹中手动获取proj4.js文件。
3、如果不想下载,可以引用在线的proj4js包,托管在cdn上:https://cdnjs.com/libraries/proj4js。

四、proj4参数详解

        有关各种投影的参数定义,可参考https://epsg.io/或者http://spatialreference.org;如果已有定义,可搜索并查看其投影参数。如果没有定义,需要用户自定义投影,可通过defs 定义 EPSGCODE来创建投影,defs 内容为参考投影参数:分别包括名称、投影、转换到 WGS84 坐标系(三参数、七参数)、椭球长半轴、扁率、原点纬线、中央经线、两条标准纬线、东偏移量、北偏移量和单位等。
比如从https://epsg.io网站中获得EPSG:3395的WKT描述:
在这里插入图片描述
或者从http://spatialreference.org/ref/epsg/3395/proj4/网站可以获得EPSG:3395的投影参数:
+proj=merc +lon_0=0 +k=1 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m +no_defs

proj4常用定义参数:
+proj 投影坐标系统名称
+a 椭球体长半轴长度
+alpha 用于斜墨卡托和其它几个可能的投影
+axis 轴方向
+b 椭球体短半轴长度
+datum 基准面名
+ellps 椭球体名
+k 比例因子(old name)
+k_0 比例因子(new name)
+lat_0 维度起点
+lat_1 标准平行纬线第一条
+lat_2 标准平行纬线第二条
+lat_ts 有效纬度范围
+lon_0 中央经线
+lonc 经度用于斜墨卡托和其它几个可能的投影
+pm 备用本初子午线
+proj 投影名
+south 表示南半球UTM区域
+to_meter 乘数,转换地图单位为1.0m
+towgs84 3或7参数基准面转换
+units meters(米), US survey feet(美国测量英尺),等.
+vto_meter 垂直变换为米.
+vunits 垂直单位.
+x_0 东伪偏移
+y_0 北伪偏移
+zone UTM区域

五、 proj4在web端的应用,以iClient for Openlayer为例

        OpenLayers默认只支持EPSG:4326和EPSG:3857。但是在实际的SuperMap iClient Openlayer开发中,必然会遇到很多默认不支持的坐标系,对于默认不支持的坐标系SuperMap iClient Openlayer集成了proj4.js库,可以直接通过proj4.defs()来自定义坐标系。

开发代码:
1、 加载proj4库文件

 <script type="text/javascript" include='proj4' src="../../dist/openlayers/include-openlayers.js"></script>

2、对接自定义坐标系地图

    var map, url ="http://localhost:8090/iserver/services/map-ugcv5-3395map/rest/maps/3395map";
	
	//定义3395坐标系
	 proj4.defs("EPSG:3395","+proj=merc +lon_0=0 +k=1 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs");
	  
	// 计算resolutions
	  getResolutions = function (zoom, scale, targetMinZoom, targetMaxZoom) {
            var res = scaleToResolution(scale);
            var minRes = res * Math.pow(2, zoom - targetMinZoom);
            var resolutions = [];
            for (var index = 0; index < targetMaxZoom - targetMinZoom + 1; index++) {
                resolutions.push(minRes / Math.pow(2, index));
            }
            return resolutions;

        }
        scaleToResolution = function (scale) {
            var inchPerMeter = 1 / 0.0254;
            return 1 / (scale * 96 * inchPerMeter);
        };
        //第0级比例尺是0.000000015625
    var resolutions = getResolutions(0,0.000000015625,0,6);
    var projection =ol.proj.get('EPSG:3395');
        //新的投影必设地图范围
        projection.setExtent([8374565.292377971,1866182.1613285837,1.4947981223720774E7,7070412.849097984]);  
    //对接3395地图 
    map = new ol.Map({
        target: 'map',
        controls: ol.control.defaults({attributionOptions: {collapsed: false}})
            .extend([new ol.supermap.control.Logo()]),
        view: new ol.View({
            center: [11661273.258049373,4468297.505213284],
            zoom: 0,
            projection: projection,
            resolutions: resolutions
        })
    });
    var layer = new ol.layer.Tile({
       source: new ol.source.TileSuperMapRest({
            url: url,
            //手动构建自定义目标的TileGrid
			tileGrid: new ol.tilegrid.TileGrid({
						extent: [8374565.292377971,1866182.1613285837,1.4947981223720774E7,7070412.849097984],
						resolutions: resolutions
						}),
            wrapX: true,
			
        }),
        projection:projection
    });
    map.addLayer(layer);

3、坐标系转换

//将经纬度4326的坐标系转换成3395
var pointCoord=ol.proj.transform([100.33,32.280000018770551],'EPSG:4326','EPSG:3395');
 console.log(pointCoord);//转换后的结果[11168684.511289138, 3777303.8282244676]

//用转换后的坐标构造矢量要素
var pointFeature = {
  "type": "Feature",
  "geometry": {
    "type": "Point",
    "coordinates": [pointCoord[0],pointCoord[1]]
  },
  "properties": {
    "name": "Dinagat Islands"
  }
}
//创建矢量图层,并将要素添加到矢量图层上
 var vectorSource = new ol.source.Vector({
                features: (new ol.format.GeoJSON()).readFeatures(pointFeature),
                wrapX: false
            });
  var resultLayer = new ol.layer.Vector({
                source: vectorSource
            });
 map.addLayer(resultLayer);

六、转换的结果及代码

地图信息:在这里插入图片描述
web端对接的地图以及转换后的点位置:
在这里插入图片描述
范例代码链接:
https://download.csdn.net/download/supermapsupport/11081781

  • 4
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值