|
- #include "util/util.h"
- #include "geo/private/math/math.h"
- #include "geo/private/coord/gauss.h"
-
- namespace ns
- {
- namespace geo
- {
-
- // BeiJing54 -> Gauss-Kruger
- const char* Wgs84Proj4Init = "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs";
-
- GaussConverter::GaussConverter(double centerMeridian, double bandWidth, double pm)
- : m_pm(pm), m_bandWidth(bandWidth)
- {
- m_ctx = pj_ctx_alloc();
- // m_ctx=proj_context_create();
- m_beiJing54Proj = pj_init_plus_ctx(m_ctx, Wgs84Proj4Init);
-
- m_centralMeridian = unifyCentralMeridian(centerMeridian);
-
- char str[128] = {0};
- sprintf(str,
- "+proj=tmerc +ellps=WGS84 +lon_0=%.2fe +x_0=500000 +y_0=0 +lon_wrap=180 +units=m +k=1.0",
- m_centralMeridian);
- m_centralProj = pj_init_plus_ctx(m_ctx, str);
- }
-
- GaussConverter::~GaussConverter()
- {
- if (m_centralProj)
- pj_free(m_centralProj);
- if (m_beiJing54Proj)
- pj_free(m_beiJing54Proj);
- if (m_ctx)
- pj_ctx_free(m_ctx);
- // proj_context_destroy(m_ctx);
- }
-
- int GaussConverter::reset(double centerLon, double bandWidth, double pm)
- {
- if (are_equal(bandWidth, 0) && are_equal(pm, 0))
- {
- double c = unifyCentralMeridian(centerLon);
- if (are_equal(c, m_centralMeridian))
- return 0;
- }
- else
- {
- m_bandWidth = bandWidth;
- m_pm = pm;
- }
-
- pj_free(m_centralProj);
-
- m_centralMeridian = unifyCentralMeridian(centerLon);
-
- char str[128] = {0};
- sprintf(
- str,
- "+proj=tmerc +ellps=WGS84 +lon_0=%.2fe +x_0=500000 +y_0=0 +lon_wrap=180 +units=m +k=1.0",
- m_centralMeridian);
- m_centralProj = pj_init_plus_ctx(m_ctx, str);
-
- return 0;
- }
-
- bool GaussConverter::reset(std::string pjParamsStr)
- {
- pj_free(m_centralProj);
-
- m_centralProj = pj_init_plus_ctx(m_ctx, pjParamsStr.c_str());
-
- if (m_centralProj)
- {
- return calcCenterLon(pjParamsStr, m_centralMeridian);
- }
- return false;
- }
-
- bool GaussConverter::calcCenterLon(std::string params, double& cenLon)
- {
- std::vector<std::string> subs = util::split(params, " ");
- for (auto& s : subs)
- {
- if (util::startswith(s, "+lon_0="))
- {
- std::string numStr = s.substr(7);
- numStr = util::trim(numStr, " ");
- if (util::isNum(numStr))
- {
- cenLon = std::stod(numStr.c_str());
- return true;
- }
- }
- }
- return false;
- }
-
- double GaussConverter::unifyCentralMeridian(double lon)
- {
- m_zone = static_cast<unsigned>(std::floor((lon - m_pm) / m_bandWidth)) + 1;
- return getCentralMeridian(m_zone);
- }
-
- PointD GaussConverter::wgs842Gauss(const PointD& p) const
- {
- double x = p.x * DEG_TO_RAD;
- double y = p.y * DEG_TO_RAD;
- double z = 0.0;
- pj_transform(m_beiJing54Proj, m_centralProj, 1, 1, &x, &y, &z);
- return PointD(x, y, p.z);
- }
-
- PointD GaussConverter::gauss2Wgs84(const PointD& p) const
- {
- double x = p.x, y = p.y, z = 0.0;
- pj_transform(m_centralProj, m_beiJing54Proj, 1, 1, &x, &y, &z);
- return PointD(x * RAD_TO_DEG, y * RAD_TO_DEG, p.z);
- }
-
- } // namespace geo
- } // namespace ns
|