You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kev/Drawer/Module/GeoSigmaDraw/ProjectionParameterAssistan...

552 lines
13 KiB
C++

1 month ago
#include "stdafx.h"
#include "ProjectionParameterAssistant.h"
#include <ProjectionLib/ProjectionParameter.h>
#include <map>
#include <sstream>
#include <algorithm>
#define _PROJECTION_GAUSS_TITLE "Gauss"
#define _PROJECTION_GAUSS_TITLE_LOWER "gauss"
#define _PROJECTION_UTM_TITLE "UTM"
#define _PROJECTION_UTM_TITLE_LOWER "utm"
#define _PROJECTION_LAMBER_TITLE "Lamber"
#define _PROJECTION_LAMBER_TITLE_LOWER "lamber"
#define _PROJECTION_MERCATOR_TITLE "Mercator"
#define _PROJECTION_MERCATOR_TITLE_LOWER "mercator"
#define _PROJECTION_ALBERS_TITLE "Albers"
#define _PROJECTION_ALBERS_TITLE_LOWER "albers"
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD>ʽ<EFBFBD><CABD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD> WD=%d ZN=%d CL=0 CT=0
class KeyValueParser
{
public:
bool Parse(char * kvStr);
bool GetValueStr(const char * kry, double & v);
private:
bool ParseToken(char * s, char * e);
private:
std::map<std::string, double> m_map;
};
ProjectionParameterAssistant * ProjectionParameterAssistant::m_pInstance = 0;
ProjectionParameterAssistant * ProjectionParameterAssistant::GetInstance()
{
if (m_pInstance == 0)
m_pInstance = new ProjectionParameterAssistant();
return m_pInstance;
}
void ProjectionParameterAssistant::SetParameter(SigmaProjectionParameter * para)
{
m_para = para;
}
ProjectionParameterAssistant::ProjectionParameterAssistant()
:m_para(0)
{
InitEllipsoidMap();
}
void ProjectionParameterAssistant::InitEllipsoidMap()
{
m_ellipsoidMap["china-1954"] = 0;
m_ellipsoidMap["china-1967"] = 1;
m_ellipsoidMap["china-1975"] = 2;
m_ellipsoidMap["china-1980"] = 3;
m_ellipsoidMap["china-1983"] = 4;
m_ellipsoidMap["wgs-60"] = 5;
m_ellipsoidMap["wgs-66"] = 6;
m_ellipsoidMap["wgs-72"] = 7;
m_ellipsoidMap["wgs-84"] = 8;
m_ellipsoidMap["bessel"] = 9;
m_ellipsoidMap["hayfard"] = 10;
m_ellipsoidMap["clarke-1866"] = 11;
m_ellipsoidMap["krasovsky"] = 12;
m_ellipsoidMap["youcunyi(china)"] = 13;
m_ellipsoidMap["grim-1"] = 14;
m_ellipsoidMap["grim-2"] = 15;
m_ellipsoidMap["gem-8"] = 16;
m_ellipsoidMap["gem-10"] = 17;
//<2F><><EFBFBD><EFBFBD>ͶӰ<CDB6><D3B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Զ<EFBFBD>ת<EFBFBD><D7AA><EFBFBD><EFBFBD>Ӧ
m_ellipsoidMap["54"] = 0;
m_ellipsoidMap["80"] = 1;
m_ellipsoidMap["1954"] = 0;
m_ellipsoidMap["1967"] = 1;
m_ellipsoidMap["1975"] = 2;
m_ellipsoidMap["1980"] = 3;
m_ellipsoidMap["1983"] = 4;
//-------------------------------------------
m_ellipsoidIntMap[0] = "China-1954";
m_ellipsoidIntMap[1] = "China-1967";
m_ellipsoidIntMap[2] = "China-1975";
m_ellipsoidIntMap[3] = "China-1980";
m_ellipsoidIntMap[4] = "China-1983";
m_ellipsoidIntMap[5] = "WGS-60";
m_ellipsoidIntMap[6] = "WGS-66";
m_ellipsoidIntMap[7] = "WGS-72";
m_ellipsoidIntMap[8] = "WGS-84";
m_ellipsoidIntMap[9] = "Bessel";
m_ellipsoidIntMap[10] = "Hayfard";
m_ellipsoidIntMap[11] = "Clarke-1866";
m_ellipsoidIntMap[12] = "Krasovsky";
m_ellipsoidIntMap[13] = "YouCunYi(china)";
m_ellipsoidIntMap[14] = "GRIM-1";
m_ellipsoidIntMap[15] = "GRIM-2";
m_ellipsoidIntMap[16] = "GEM-8";
m_ellipsoidIntMap[17] = "GEM-10";
}
//Projection
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Gauss <20><><EFBFBD><EFBFBD>,<2C><><EFBFBD><EFBFBD>[,<2C>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ߣ<EFBFBD><DFA3>ȷ<EFBFBD><C8B7><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE>ʽ<EFBFBD><CABD>] <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<2C><>λ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>[<5B>ϰ<EFBFBD><CFB0><EFBFBD>],<2C><><EFBFBD><EFBFBD>[<5B><><EFBFBD><EFBFBD>]
//[<5B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Taper <20><><EFBFBD><EFBFBD><EBBEAD><EFBFBD><EFBFBD><><CBAB>׼γ<D7BC><CEB3>γ<EFBFBD><CEB3>1,˫<><CBAB>׼γ<D7BC><CEB3>γ<EFBFBD><CEB3>2,<2C><><EFBFBD><EFBFBD>ԭ<EFBFBD><D4AD><EFBFBD><EFBFBD>γ<EFBFBD><CEB3> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<2C><>λ] <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>[<5B>ϰ<EFBFBD><CFB0><EFBFBD>],<2C><><EFBFBD><EFBFBD>[<5B><><EFBFBD><EFBFBD>]
int ProjectionParameterAssistant::ParseParameterFromString(CString & projStr)
{
if (m_para == 0)
return 0;
InitParameter();
char se[256], sp[256], sz[256], su[256], sa[256];
int t = sscanf(projStr, "%s%s%s%s%s", se, sp, sz, su, sa);
if (t < 2)
return 0;
std::string ellipsoidStr(se);
m_para->ellipsoidKind = GetIndexOfEllipsoid(ellipsoidStr);
if (m_para->ellipsoidKind == -1)
return 0;
std::string typeStr(sp);
if (GetPrjectionType(typeStr) == 0)
{
m_para->projection = _PROJECTION_GAUSS;
m_para->coordinate_type = _XY_BL_BL;
m_para->coordinate_unit = _XY_BL_DEGREE;
return 2;
}
if (t == 2)
return 2;
switch (m_para->projection)
{
case _PROJECTION_GAUSS:
case _PROJECTION_UTM:
{
CString str = sz;
int flags = 0;
str.MakeUpper();
str.Replace("AUTO", "-1");
int r = sscanf(str, "%d,%d,%lf,%u", &m_para->w, &m_para->zone, &m_para->m_dCustomCenterLongitude, &flags);
if (flags & _XY_MODE_WITH_ZONE)
m_para->bZone = 1;
else
m_para->bZone = 0;
if (flags & _XY_MODE_CUSTOM)
m_para->bCustomCenterLongitude = 1;//EnableCustomCenterLongitude(TRUE);
else
m_para->bCustomCenterLongitude = 0;
}
break;
case _PROJECTION_LAMBERT:
sscanf(sz, "%lf,%lf,%lf,%lf", &m_para->conic_OriginLongitude, &m_para->conic_b1, &m_para->conic_b2, &m_para->conic_OriginLatitude);
break;
}
if (t == 3)
{
m_para->coordinate_type = _XY_XY_XY;
m_para->coordinate_unit = _XY_XY_KM;
return 3;
}
sscanf(su, "%d,%d", &m_para->coordinate_type, &m_para->coordinate_unit);
if (t == 5)
sscanf(sa, "%ld,%ld", &m_para->latitude, &m_para->longitude);
return 5;
}
bool ProjectionParameterAssistant::GenerateOtherString(std::string & otherStrOut)
{
if (m_para == 0)
return false;
char buffer[512];
memset(buffer, 0, sizeof(buffer));
if (m_para->projection == _PROJECTION_GAUSS || m_para->projection == _PROJECTION_UTM)
{
if (m_para->bCustomCenterLongitude == 1)
snprintf(buffer, sizeof(buffer)-1, "WD=%d ZN=%d CL=%d CT=1", m_para->w, m_para->zone, (int)m_para->m_dCustomCenterLongitude);
else
snprintf(buffer, sizeof(buffer)-1, "WD=%d ZN=%d CL=0 CT=0", m_para->w, m_para->zone);
otherStrOut = buffer;
return true;
}
else if (m_para->projection == _PROJECTION_LAMBERT)
{
//<2F><><EFBFBD><EFBFBD>ʹ<EFBFBD>öȷ<C3B6><C8B7><EFBFBD><EFBFBD>ĸ<EFBFBD>ʽ<EFBFBD><CABD>ʾ <20><><EFBFBD><EFBFBD>120<32><30>30<33><30>30<33><30><EFBFBD><EFBFBD>д<EFBFBD><D0B4> 1203030 <20><><EFBFBD><EFBFBD>ֱ<EFBFBD><D6B1><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͺ<EFBFBD><CDBA><EFBFBD>
snprintf(buffer, sizeof(buffer)-1, "L0=%d B1=%d B2=%d BS=%d",
(int)m_para->conic_OriginLongitude, (int)m_para->conic_b1, (int)m_para->conic_b2, (int)m_para->conic_OriginLatitude);
otherStrOut = buffer;
return true;
}
return false;
}
int ProjectionParameterAssistant::GetProjectStr(std::string & projStrOut)
{
if (m_para == 0)
return -1;
char buffer[512];
memset(buffer, 0, sizeof(buffer));
char su[512];
memset(su, 0, sizeof(su));
char sz[512];
memset(sz, 0, sizeof(sz));
char sa[512];
memset(sa, 0, sizeof(sa));
std::string sp;
GetPrjectionName(sp);
if (sp.empty())
return -1;
auto ite = m_ellipsoidIntMap.find(m_para->ellipsoidKind);
if (ite == m_ellipsoidIntMap.end())
return -1;
std::string ellipsoidName = (*ite).second;
snprintf(su, sizeof(su)-1, "%d,%d", m_para->coordinate_type, m_para->coordinate_unit);
int flag = m_para->bZone;
flag = flag << 1; //<2F>Ƿ<EFBFBD><C7B7>д<EFBFBD><D0B4><EFBFBD>д<EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD>flag<61>ĵڶ<C4B5>λ
flag |= m_para->bCustomCenterLongitude;;
switch (m_para->projection)
{
case _PROJECTION_GAUSS:
case _PROJECTION_UTM:
if (m_para->bCustomCenterLongitude)
snprintf(sz, sizeof(sz) - 1, "%d,%d,%f,%d", m_para->w, m_para->zone, m_para->m_dCustomCenterLongitude, flag);
else
snprintf(sz, sizeof(sz) - 1, "%d,%d,0,%d", m_para->w, m_para->zone, flag);
//sz.Format("%d,%d,0,%u", w, zone, m_nFlags);
//dfFloatToString(sccl, m_dCustomCenterLongitude, 8);
//if (IsCustomCenterLongitude())
// sz.Format("%d,%d,%s,%u", w, zone, sccl, m_nFlags);
//else
// sz.Format("%d,%d,0,%u", w, zone, m_nFlags);
break;
case _PROJECTION_LAMBERT:
{
snprintf(sz, sizeof(sz) - 1, "%f,%f,%f,%f",
m_para->conic_OriginLongitude, m_para->conic_b1, m_para->conic_b2, m_para->conic_OriginLatitude);
}
break;
}
snprintf(sa, sizeof(sa)-1, "%d,%d", m_para->latitude, m_para->longitude);
snprintf(buffer, sizeof(buffer)-1, "%s %s %s %s %s", ellipsoidName.c_str(), sp.c_str(), sz, su, sa);
projStrOut = buffer;
return 1;
}
void ProjectionParameterAssistant::InitParameter()
{
m_para->zone = -1;
m_para->w = 6;
m_para->projection = _PROJECTION_GAUSS;
m_para->m_dScaleFactor = 1.0;
m_para->ellipsoidKind = 3; //China-1980
m_para->coordinate_type = _XY_XY_XY;
m_para->coordinate_unit = _XY_XY_M;
m_para->conic_OriginLongitude = 0;
m_para->conic_OriginLatitude = 0;
m_para->conic_b1 = m_para->conic_b2 = 0;
m_para->m_dCustomCenterLongitude = 0;
m_para->latitude = _AREA_NORTH_LATITUDE;
m_para->longitude = _AREA_EAST_LONGITUDE;
//m_para->flags = _XY_MODE_WITH_ZONE;
m_para->bZone = 1;
m_para->bCustomCenterLongitude = 0;
}
//<2F><>˹ͶӰʱ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͶӰʱ
bool ProjectionParameterAssistant::FillOtherParameter(std::string & otherStr)
{
if (m_para->projection == _PROJECTION_GAUSS || m_para->projection == _PROJECTION_UTM)
return ProcessForGuass(otherStr);
else if (m_para->projection == _PROJECTION_LAMBERT)
return ProcessForLambert(otherStr);
return false;
}
int ProjectionParameterAssistant::GetPrjectionType(std::string & type)
{
std::string typeStr = type;
std::transform(typeStr.begin(), typeStr.end(), typeStr.begin(), tolower);
int rt = 1;
if (typeStr == _PROJECTION_GAUSS_TITLE_LOWER)
{
m_para->projection = _PROJECTION_GAUSS;
m_para->m_dScaleFactor = 1.0;
}
else if (typeStr == _PROJECTION_UTM_TITLE_LOWER)
{
m_para->projection = _PROJECTION_UTM;
m_para->m_dScaleFactor = 0.9996;
}
else if (typeStr == "taper" || typeStr == _PROJECTION_LAMBER_TITLE_LOWER)
m_para->projection = _PROJECTION_LAMBERT;
else if (typeStr == _PROJECTION_MERCATOR_TITLE_LOWER)
m_para->projection = _PROJECTION_MERCATOR;
else if (typeStr == _PROJECTION_ALBERS_TITLE_LOWER)
m_para->projection = _PROJECTION_ALBERS;
else
rt = 0;
return rt;
}
int ProjectionParameterAssistant::GetIndexOfEllipsoid(std::string & ellipsoidStr)
{
std::string str = ellipsoidStr;
std::transform(str.begin(), str.end(), str.begin(), tolower);
auto ite = m_ellipsoidMap.find(str);
if (ite == m_ellipsoidMap.end())
return -1;
return (*ite).second;
}
void ProjectionParameterAssistant::GetPrjectionName(std::string & projNameOut)
{
if (m_para == 0)
return;
switch (m_para->projection)
{
case _PROJECTION_GAUSS:
projNameOut = _PROJECTION_GAUSS_TITLE;
break;
case _PROJECTION_UTM:
projNameOut = _PROJECTION_UTM_TITLE;
break;
case _PROJECTION_LAMBERT:
projNameOut = "Taper";
break;
case _PROJECTION_MERCATOR:
projNameOut = _PROJECTION_MERCATOR_TITLE;
break;
case _PROJECTION_ALBERS:
projNameOut = _PROJECTION_ALBERS_TITLE;
break;
default:
break;
}
}
bool ProjectionParameterAssistant::ProcessForGuass(std::string & otherStr)
{
//WD=%d ZN=%d CL=0 CT=0
std::string str(otherStr);
KeyValueParser parser;
if (parser.Parse((char *)str.c_str()) == false)
return false;
double w = 0;
if (parser.GetValueStr("WD", w) == false)
return false;
double zone = 0;
if (parser.GetValueStr("ZN", zone) == false)
return false;
double cl = 0;
if (parser.GetValueStr("CL", cl) == false)
return false;
double ct = 0;
if (parser.GetValueStr("CT", ct) == false)
return false;
m_para->w = w;
m_para->zone = zone;
m_para->m_dCustomCenterLongitude = cl;
int ctInt = (int)ct;
if (ctInt != 0 && ctInt != 1)
return false;
m_para->bCustomCenterLongitude = ctInt;
return true;
}
bool ProjectionParameterAssistant::ProcessForLambert(std::string & otherStr)
{
//L0=%f B1=%f B2=%f BS=%f
std::string str(otherStr);
KeyValueParser parser;
if (parser.Parse((char *)str.c_str()) == false)
return false;
double L0 = 0;
if (parser.GetValueStr("L0", L0) == false)
return false;
double B1 = 0;
if (parser.GetValueStr("B1", B1) == false)
return false;
double B2 = 0;
if (parser.GetValueStr("B2", B2) == false)
return false;
double BS = 0;
if (parser.GetValueStr("BS", BS) == false)
return false;
m_para->conic_OriginLongitude = L0;
m_para->conic_b1 = B1;
m_para->conic_b2 = B2;
m_para->conic_OriginLatitude = BS;
return true;
}
bool KeyValueParser::Parse(char * kvStr)
{
if (kvStr == 0)
return false;
char * p = kvStr;
if (*p == '\0')
return false;
while (*p != '\0') //ȥ<><C8A5><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7><EFBFBD>Ŀո<C4BF>
{
if (*p == ' ')
{
p++;
}
else
break;
}
char * pStart = p; //Token<65><6E><EFBFBD><EFBFBD>
while (*p != '\0')
{
if (*p == ' ')
{
if (ParseToken(pStart, p - 1) == false)
return false;
//<2F>Ƴ<EFBFBD>p<EFBFBD><70><EFBFBD>Ŀո<C4BF>
while (true)
{
p++;
if (*p != ' ')
{
pStart = p;
break;
}
if (*p == '\0')
return true;
}
}
if (*(p + 1) == 0) //<2F><><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD>β<EFBFBD><CEB2><EFBFBD><EFBFBD>
{
ParseToken(pStart, p);
}
p++;
}
return true;
}
bool KeyValueParser::GetValueStr(const char * key, double & v)
{
if (key == 0)
return false;
auto ite = m_map.find(key);
if (ite == m_map.end())
return false;
v = (*ite).second;
return true;
}
bool KeyValueParser::ParseToken(char * s, char * e)
{
if (e <= s)
return false;
char * p1 = s; //<2F>õ<EFBFBD><C3B5>Ⱥ<EFBFBD>֮ǰ<D6AE><C7B0>λ<EFBFBD><CEBB>
while (p1 < e)
{
if (*p1 == '=')
break;
p1++;
}
if (p1 == e) //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD> Ҳû<D2B2>ҵ<EFBFBD><D2B5>Ⱥ<EFBFBD>
return false;
if (s == p1)
return false;
*p1 = '\0'; //<2F><>ȡkey
std::string key(s);
if (key.empty())
return false;
p1++; //<2F><><EFBFBD><EFBFBD><EFBFBD>Ⱥ<EFBFBD>
if (p1 > e)
return false;
std::string valueStr;
while (p1 <= e)
{
valueStr.push_back(*p1);
p1++;
}
std::istringstream convert(valueStr);
double v = 0;
if (!(convert >> v))
{
return false;
}
m_map[key] = v;
return true;
}