1 /**********************************************************************************************
2 Copyright (C) 2014 Oliver Eichler <oliver.eichler@gmx.de>
3
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17 **********************************************************************************************/
18
19 #include "CMainWindow.h"
20 #include "gis/proj_x.h"
21 #include "helpers/mitab.h"
22 #include "overlay/refmap/CProjWizard.h"
23
24 #include <QtWidgets>
25
26 struct mitab_entry_t
27 {
28 QString name;
29 int idx;
30 };
31
mitabLessThan(const mitab_entry_t & s1,const mitab_entry_t & s2)32 static bool mitabLessThan(const mitab_entry_t& s1, const mitab_entry_t& s2)
33 {
34 return s1.name < s2.name;
35 }
36
CProjWizard(QLineEdit & line,QWidget * parent)37 CProjWizard::CProjWizard(QLineEdit& line, QWidget* parent)
38 : QDialog(parent)
39 , line(line)
40 {
41 setupUi(this);
42 QList<mitab_entry_t> list;
43 int idx = 0;
44
45 for(const MapInfoDatumInfo& di : asDatumInfoList)
46 {
47 mitab_entry_t entry;
48 entry.name = di.pszOGCDatumName;
49 if(!entry.name.isEmpty())
50 {
51 for(const MapInfoSpheroidInfo& si : asSpheroidInfoList)
52 {
53 if(si.nMapInfoId == di.nEllipsoid)
54 {
55 entry.name += tr(" (Spheroid: %1)").arg(si.pszMapinfoName);
56 }
57 }
58 }
59 entry.idx = idx;
60 list << entry;
61 ++idx;
62 }
63 qSort(list.begin(), list.end(), mitabLessThan);
64
65 for(const mitab_entry_t& entry : qAsConst(list))
66 {
67 comboDatum->addItem(entry.name, entry.idx);
68 }
69
70 comboHemisphere->addItem(tr("north"), "");
71 comboHemisphere->addItem(tr("south"), "+south");
72
73 connect(radioMercator, &QRadioButton::clicked, this, &CProjWizard::slotChange);
74 connect(radioWorldMercator, &QRadioButton::clicked, this, &CProjWizard::slotChange);
75 connect(radioUPSNorth, &QRadioButton::clicked, this, &CProjWizard::slotChange);
76 connect(radioUPSSouth, &QRadioButton::clicked, this, &CProjWizard::slotChange);
77 connect(radioUTM, &QRadioButton::clicked, this, &CProjWizard::slotChange);
78 connect(radioUserDef, &QRadioButton::clicked, this, &CProjWizard::slotChange);
79 connect(lineUserDef, &QLineEdit::textChanged, this, &CProjWizard::slotChange);
80
81 connect(spinUTMZone, static_cast<void (QSpinBox::*)(int) >(&QSpinBox::valueChanged), this, &CProjWizard::slotChange);
82 connect(comboDatum, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &CProjWizard::slotChange);
83 connect(comboHemisphere, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &CProjWizard::slotChange);
84
85 QString projstr = line.text();
86 QRegExp re2("\\s*\\+proj=merc \\+a=6378137 \\+b=6378137 \\+lat_ts=0.001 \\+lon_0=0.0 \\+x_0=0.0 \\+y_0=0 \\+k=1.0 \\+units=m \\+nadgrids=@null \\+no_defs");
87 QRegExp re3("\\s*\\+proj=merc\\s(.*)");
88 QRegExp re4("\\s*\\+proj=utm \\+zone=([0-9]+)\\s(.*)");
89
90 if(re2.exactMatch(projstr))
91 {
92 radioWorldMercator->setChecked(true);
93 }
94 else if(re3.exactMatch(projstr))
95 {
96 radioMercator->setChecked(true);
97 findDatum(re3.cap(1));
98 }
99 else if(re4.exactMatch(projstr))
100 {
101 radioUTM->setChecked(true);
102 spinUTMZone->setValue(re4.cap(1).toInt());
103
104 QString datum = re4.cap(2);
105 if(datum.startsWith("+south "))
106 {
107 datum = datum.mid(7);
108 comboHemisphere->setCurrentIndex(1);
109 }
110
111 findDatum(datum);
112 }
113
114 slotChange();
115 }
116
~CProjWizard()117 CProjWizard::~CProjWizard()
118 {
119 }
120
121
findDatum(const QString & str)122 void CProjWizard::findDatum(const QString& str)
123 {
124 QString cmp;
125 for(const MapInfoDatumInfo& di : asDatumInfoList)
126 {
127 cmp.clear();
128 if(di.pszOGCDatumName != QString())
129 {
130 for(const MapInfoSpheroidInfo& si : asSpheroidInfoList)
131 {
132 if(si.nMapInfoId == di.nEllipsoid)
133 {
134 cmp += QString("+a=%1 +b=%2 ").arg(si.dfA, 0, 'f', 4).arg(si.dfA * (1.0 - (1.0 / si.dfInvFlattening)), 0, 'f', 4);
135 cmp += QString("+towgs84=%1,%2,%3,%4,%5,%6,%7 ").arg(di.dfShiftX).arg(di.dfShiftY).arg(di.dfShiftZ).arg(di.dfDatumParm0).arg(di.dfDatumParm1).arg(di.dfDatumParm2).arg(di.dfDatumParm3);
136 cmp += "+units=m +no_defs";
137 break;
138 }
139 }
140 }
141
142 if(cmp == str)
143 {
144 comboDatum->setCurrentIndex(comboDatum->findText(di.pszOGCDatumName));
145 break;
146 }
147 }
148 }
149
150
slotChange()151 void CProjWizard::slotChange()
152 {
153 QString str;
154 if(radioMercator->isChecked())
155 {
156 str += "+proj=merc ";
157 }
158 else if(radioWorldMercator->isChecked())
159 {
160 str += "+proj=merc +a=6378137 +b=6378137 +lat_ts=0.001 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs";
161 labelResult->setText(str);
162 return;
163 }
164 else if(radioUPSNorth->isChecked())
165 {
166 str += "EPSG:32661";
167 }
168 else if(radioUPSSouth->isChecked())
169 {
170 str += "EPSG:32761";
171 }
172 else if(radioUTM->isChecked())
173 {
174 str += QString("+proj=utm +zone=%1 %2 ").arg(spinUTMZone->value()).arg(comboHemisphere->itemData(comboHemisphere->currentIndex()).toString());
175 }
176 else if(radioUserDef->isChecked())
177 {
178 str += lineUserDef->text() + " ";
179 }
180
181 int idx = comboDatum->itemData(comboDatum->currentIndex()).toInt();
182 const MapInfoDatumInfo& di = asDatumInfoList[idx];
183 if(di.pszOGCDatumName != QString())
184 {
185 for(const MapInfoSpheroidInfo& si : asSpheroidInfoList)
186 {
187 if(si.nMapInfoId == di.nEllipsoid)
188 {
189 str += QString("+a=%1 +b=%2 ").arg(si.dfA, 0, 'f', 4).arg(si.dfA * (1.0 - (1.0 / si.dfInvFlattening)), 0, 'f', 4);
190 str += QString("+towgs84=%1,%2,%3,%4,%5,%6,%7 ").arg(di.dfShiftX).arg(di.dfShiftY).arg(di.dfShiftZ).arg(di.dfDatumParm0).arg(di.dfDatumParm1).arg(di.dfDatumParm2).arg(di.dfDatumParm3);
191 str += "+units=m +no_defs";
192 break;
193 }
194 }
195 }
196
197 labelResult->setText(str);
198 }
199
200
accept()201 void CProjWizard::accept()
202 {
203 if (CProjWizard::validProjStr(labelResult->text()))
204 {
205 line.setText(labelResult->text());
206 line.setCursorPosition(0);
207 QDialog::accept();
208 }
209 }
210
211
validProjStr(const QString projStr)212 bool CProjWizard::validProjStr(const QString projStr)
213 {
214 return CProj::validProjStr(projStr, true, [](const QString& msg){
215 QMessageBox::warning(&CMainWindow::self(), tr("Error..."), msg, QMessageBox::Abort, QMessageBox::Abort);
216 });
217 }
218
219
220