在之前的一篇博客中,介绍了经纬度坐标系的关系,WGS84是世界大地坐标系,属于原始坐标系,在商用中,需要通过火星加密算法将经纬度做转换,转换之后的坐标,称为国测局坐标,也叫火星坐标系,简称GCJ02。这个过程称为坐标偏移算法。反过来,我们将GCJ02坐标系转为WGS84就是纠偏算法,严格来说,他们不是一对正向与反向的可逆操作,但是有理论公式可以推导。
ceres库是一个c++开源库,用来解决非线性优化问题,可以解决边界约束鲁棒非线性最小二乘法优化问题(Ceres Solver 1 is an open source C++ library for modeling and solving large, complicated optimization problems. It can be used to solve Non-linear Least Squares problems with bounds constraints and general unconstrained optimization problems),通过这个库,我们几乎可以将GCJ02精确转换为WGS84坐标。下面来看示例。
代码是从github上拿过来的。
c++头文件:
/***************************************************************************
*
* This class WGStoGCJ implements geodetic coordinate transform between geodetic
* coordinate in WGS84 coordinate system and geodetic coordinate in GCJ-02
* coordinate system.
*
* details: https://blog.youkuaiyun.com/gudufuyun/article/details/106738942
*
* Copyright (c) 2020. All rights reserved.
*
* kikkimo
* School of Remote Sensing and Information Engineering,
* WuHan University,
* Wuhan, Hubei, P.R. China. 430079
* fywhu@outlook.com
*
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#pragma once
#include <utility>
#ifdef _WGSTOGCJ_API
#if (defined _WIN32 || defined WINCE || defined __CYGWIN__)
#define WGSTOGCJ_API_EXPORTS __declspec(dllexport)
#elif defined __GNUC__ && __GNUC__ >= 4
#define WGSTOGCJ_API_EXPORTS __attribute__((visibility("default")))
#endif
#endif
#ifndef WGSTOGCJ_API_EXPORTS
#define WGSTOGCJ_API_EXPORTS
#endif
/**
* \brief Covert geodetic coordinate in WGS84 coordinate system to geodetic coordinate
* in GCJ-02 coordinate system
*
* \param [in] wgs84lon: longitude in WGS84 coordinate system [unit:degree]
* \param [in] wgs84lat: latitude in WGS84 coordinate system [unit:degree]
* \return Returns geodetic coordinate in GCJ-02 coordinate system
* \time 15:47:38 2020/06/12
*/
WGSTOGCJ_API_EXPORTS std::pair<double, double>
Wgs2Gcj(const double& wgs84lon, const double& wgs84lat);
/**
* \brief Covert geodetic coordinate in GCJ-02 coordinate system to geodetic coordinate
* in WGS84 coordinate system
*
* \param [in] gcj02lon: longitude in GCJ-02 coordinate system [unit:degree]
* \param [in] gcj02lat: latitude in GCJ-02 coordinate system [unit:degree]
* \return Returns geodetic coordinate in WGS84 coordinate system
* \remark simple linear iteration
* \detail
* \time 15:51:13 2020/06/12
*/
std::pair<double, double> __declspec(dllexport)
Gcj2Wgs_SimpleIteration(const double& gcj02lon, const double& gcj02lat);
/**
* \brief Covert geodetic coordinate in GCJ-02 coordinate system to geodetic coordinate
* in WGS84 coordinate system
*
* \param [in] gcj02lon: longitude in GCJ-02 coordinate system [unit:degree]
* \param [in] gcj02lat: latitude in GCJ-02 coordinate system [unit:degree]
* \return Returns geodetic coordinate in WGS84 coordinate system
* \remark the encryption formula is known and use an auto-differentiable cost function
* \time 15:51:13 2020/06/12
*/
WGSTOGCJ_API_EXPORTS std::pair<double, double>
Gcj2Wgs_AutoDiff(const double& gcj02lon, const double& gcj02lat);
/**
* \brief Covert geodetic coordinate in GCJ-02 coordinate system to geodetic coordinate
* in WGS84 coordinate system
*
* \param [in] gcj02lon: longitude in GCJ-02 coordinate system [unit:degree]
* \param [in] gcj02lat: latitude in GCJ-02 coordinate system [unit:degree]
* \return Returns geodetic coordinate in WGS84 coordinate system
* \remark the encryption formula is unknown but we can covert point in WGS84 to point
* in GCJ-02 with an API,then use the numerical derivation method to solve the
* problem
* \detail Assuming the encryption formula is
*
* gcj02lon = Wg