Openlayers使用Proj4js坐标转换cgcs2000分带(zone)投影的问题

问题源于使用4528投影按照官网示例定义view时地图一片空白,于是开始了对Proj4js和投影转换的抽丝剥茧,这里记录下了解的知识和最后的结论。

官网示例和Proj4js的使用

OL示例见wms-image-custom-proj
这里简单介绍下proj4,我认知的proj4是基于一些约定参数组成的用于定义坐标参考的一组参数,和WKT相比更简约,省略了WKT里的完整参数定义。比如4528的wkt

PROJCRS["CGCS2000 / 3-degree Gauss-Kruger zone 40",
    BASEGEOGCRS["China Geodetic Coordinate System 2000",
        DATUM["China 2000",
            ELLIPSOID["CGCS2000",6378137,298.257222101,
                LENGTHUNIT["metre",1]]],
        PRIMEM["Greenwich",0,
            ANGLEUNIT["degree",0.0174532925199433]],
        ID["EPSG",4490]],
    CONVERSION["3-degree Gauss-Kruger zone 40",
        METHOD["Transverse Mercator",
            ID["EPSG",9807]],
        PARAMETER["Latitude of natural origin",0,
            ANGLEUNIT["degree",0.0174532925199433],
            ID["EPSG",8801]],
        PARAMETER["Longitude of natural origin",120,
            ANGLEUNIT["degree",0.0174532925199433],
            ID["EPSG",8802]],
        PARAMETER["Scale factor at natural origin",1,
            SCALEUNIT["unity",1],
            ID["EPSG",8805]],
        PARAMETER["False easting",40500000,
            LENGTHUNIT["metre",1],
            ID["EPSG",8806]],
        PARAMETER["False northing",0,
            LENGTHUNIT["metre",1],
            ID["EPSG",8807]]],
    CS[Cartesian,2],
        AXIS["northing (X)",north,
            ORDER[1],
            LENGTHUNIT["metre",1]],
        AXIS["easting (Y)",east,
            ORDER[2],
            LENGTHUNIT["metre",1]],
    USAGE[
        SCOPE["Cadastre, engineering survey, topographic mapping (large scale)."],
        AREA["China - onshore between 118°30'E and 121°30'E."],
        BBOX[24.43,118.5,53.33,121.5]],
    ID["EPSG",4528]]

它的proj4

+proj=tmerc +lat_0=0 +lon_0=120 +k=1 +x_0=40500000 +y_0=0 +ellps=GRS80 +units=m +no_defs

详细介绍见参考
我对该示例做了简化,去掉了范围,更换图层为OSM,在vue里测试

import Map from "ol/Map";
import View from "ol/View";
import * as Layer from "ol/layer";
import * as Source from "ol/source";
import Projection from "ol/proj/Projection";
import { fromLonLat } from "ol/proj";
import proj4 from "proj4";
import { register } from "ol/proj/proj4";
  private mounted() {
  	// 这里定义编码和proj4参数
    proj4.defs(
      "EPSG:4549",
      "+proj=tmerc +lat_0=0 +lon_0=120 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
    );
    // 注册之后就可以使用epsg编码调用
    register(proj4);
    // 定义了底图 用的OSM
    const base = new Layer.Tile({
      source: new Source.OSM(),
    });

    const projection = new Projection({
      code: "EPSG:4549",
      units: "m",
    });

    // 初始化地图对象
    const map = new Map({
      layers: [base],
      target: "map",
      view: new View({
        projection,
        center: fromLonLat([120.015, 36.408], "EPSG:4549"),
        zoom: 8,
      }),
    });
  }

获取Proj4的方法

比较方便的方法是在https://epsg.io/里查询,但我一直访问不了,作为替代可以在QGIS里查询
点击右下角的坐标参考按钮,很直观,亲测和网站里获取的是一样的
在这里插入图片描述

2000带投影的Proj4的问题

如果使用epsg:4528的proj4和编码,地图会一片空白还不报错。我尝试了其他坐标系,有的行有的不行,对比之后发现凡是以‘CGCS2000 / 3-degree Gauss-Kruger zone’开头的都不行,而同样是两千带投影的‘CGCS2000 / 3-degree Gauss-Kruger CM’系列就没事
在这里插入图片描述
在这里插入图片描述
这两个坐标系范围啥的都一样,我对比了下他俩的proj4

4528(CGCS2000 / 3-degree Gauss-Kruger zone 40)
+proj=tmerc +lat_0=0 +lon_0=120 +k=1 +x_0=40500000 +y_0=0 +ellps=GRS80 +units=m +no_defs
4549(CGCS2000 / 3-degree Gauss-Kruger CM 120E)
+proj=tmerc +lat_0=0 +lon_0=120 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs

除了+x_0的值,其他都一毛一样,所以问题八成出在这个参数上

如何治标不治本

研究了下,4528(CGCS2000 / 3-degree Gauss-Kruger zone 40)的+x_0的值40500000,代表40带,偏移500000米,如果去掉前边代表带号的40,就和4549的完全一样了。
估计是这种带号+偏移量的赋值方式不被支持,所以在使用4528的proj4时地图空白。
那么一种治标不治本的解决方法就来了,直接使用4549代替4528,或者使用4528,但是移除‘+x_0=40500000’里代表带号的‘40’。
4528 但是去掉了带号40

如果有更好的建议欢迎提出,也欢迎指出错误,毕竟当初学的东西基本忘光了,很多都是基于猜测。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值