24#include <QRegularExpression>
25#include <QRegularExpressionMatch>
28#include "moc_qgscrsdefinitionwidget.cpp"
30using namespace Qt::StringLiterals;
37 connect( mButtonCalculate, &QPushButton::clicked,
this, &QgsCrsDefinitionWidget::pbnCalculate_clicked );
38 connect( mButtonCopyCRS, &QPushButton::clicked,
this, &QgsCrsDefinitionWidget::pbnCopyCRS_clicked );
39 connect( mButtonValidate, &QPushButton::clicked,
this, &QgsCrsDefinitionWidget::validateCurrent );
45 connect( mFormatComboBox, qOverload<int>( &QComboBox::currentIndexChanged ),
this, &QgsCrsDefinitionWidget::formatChanged );
74 switch ( nativeFormat )
84 whileBlocking( mFormatComboBox )->setCurrentIndex( mFormatComboBox->findData(
static_cast<int>( nativeFormat ) ) );
95 mFormatComboBox->setCurrentIndex( mFormatComboBox->findData(
static_cast<int>(
format ) ) );
100 return mTextEditParameters->toPlainText();
105 mTextEditParameters->setPlainText( definition );
108void QgsCrsDefinitionWidget::pbnCopyCRS_clicked()
110 auto selector = std::make_unique<QgsProjectionSelectionDialog>(
this );
111 if ( selector->exec() )
120void QgsCrsDefinitionWidget::validateCurrent()
122 const QString projDef = mTextEditParameters->toPlainText();
126 QgsScopedProjCollectingLogger projLogger;
133 PROJ_STRING_LIST warnings =
nullptr;
134 PROJ_STRING_LIST grammarErrors =
nullptr;
135 crs.reset( proj_create_from_wkt( context, projDef.toUtf8().constData(),
nullptr, &warnings, &grammarErrors ) );
136 QStringList warningStrings;
137 QStringList grammarStrings;
138 for (
auto iter = warnings; iter && *iter; ++iter )
139 warningStrings << QString( *iter );
140 for (
auto iter = grammarErrors; iter && *iter; ++iter )
141 grammarStrings << QString( *iter );
142 proj_string_list_destroy( warnings );
143 proj_string_list_destroy( grammarErrors );
147 QMessageBox::information(
this, tr(
"Custom Coordinate Reference System" ), tr(
"This WKT projection definition is valid." ) );
151 QMessageBox::warning(
this, tr(
"Custom Coordinate Reference System" ), tr(
"This WKT projection definition is not valid:" ) + u
"\n\n"_s + warningStrings.join(
'\n' ) + grammarStrings.join(
'\n' ) );
158 const QString projCrsString = projDef + ( projDef.contains( u
"+type=crs"_s ) ? QString() : u
" +type=crs"_s );
159 crs.reset( proj_create( context, projCrsString.toUtf8().constData() ) );
162 QMessageBox::information(
this, tr(
"Custom Coordinate Reference System" ), tr(
"This proj projection definition is valid." ) );
166 QMessageBox::warning(
this, tr(
"Custom Coordinate Reference System" ), tr(
"This proj projection definition is not valid:" ) + u
"\n\n"_s + projLogger.
errors().join(
'\n' ) );
173void QgsCrsDefinitionWidget::formatChanged()
175 QgsCoordinateReferenceSystem
crs;
176 QString newFormatString;
181 crs.createFromWkt( multiLineWktToSingleLine( mTextEditParameters->toPlainText() ) );
183 newFormatString =
crs.toProj();
190 QString proj = mTextEditParameters->toPlainText();
191 proj.replace(
"+type=crs"_L1, QString() );
192 proj +=
" +type=crs"_L1;
196 const QByteArray multiLineOption = u
"MULTILINE=YES"_s.toLocal8Bit();
197 const char *
const options[] = { multiLineOption.constData(),
nullptr };
198 newFormatString = QString( proj_as_wkt( pjContext,
crs.get(), PJ_WKT2_2019, options ) );
203 if ( !newFormatString.isEmpty() )
204 mTextEditParameters->setPlainText( newFormatString );
207void QgsCrsDefinitionWidget::pbnCalculate_clicked()
210 QString projDef = mTextEditParameters->toPlainText();
214 double latitude = mNorthWGS84Edit->text().toDouble( &okN );
215 double longitude = mEastWGS84Edit->text().toDouble( &okE );
219 QMessageBox::warning(
this, tr(
"Custom Coordinate Reference System" ), tr(
"Latitude and Longitude must be in decimal form." ) );
220 mProjectedXLabel->clear();
221 mProjectedYLabel->clear();
225 QgsCoordinateReferenceSystem target;
228 projDef = projDef + ( projDef.contains( u
"+type=crs"_s ) ? QString() : u
" +type=crs"_s );
238 QMessageBox::warning(
this, tr(
"Custom Coordinate Reference System" ), tr(
"This CRS projection definition is not valid." ) );
239 mProjectedXLabel->clear();
240 mProjectedYLabel->clear();
244 QgsCoordinateReferenceSystem source;
249 source = QgsCoordinateReferenceSystem(
"EPSG:4326" );
256 catch ( QgsNotSupportedException & )
261 const QgsCoordinateTransform transform( source, target, QgsCoordinateTransformContext() );
264 const QgsPointXY res = transform.transform( QgsPointXY( longitude, latitude ) );
266 mProjectedXLabel->setText( QLocale().toString( res.
x(),
'f', precision ) );
267 mProjectedYLabel->setText( QLocale().toString( res.
y(),
'f', precision ) );
269 catch ( QgsCsException &e )
271 mProjectedXLabel->setText( tr(
"Error" ) );
272 mProjectedYLabel->setText( tr(
"Error" ) );
273 QMessageBox::warning(
this, tr(
"Custom Coordinate Reference System" ), e.
what() );
277QString QgsCrsDefinitionWidget::multiLineWktToSingleLine(
const QString &wkt )
280 const thread_local QRegularExpression re( u
"\\s*\\n\\s*"_s, QRegularExpression::MultilineOption );
281 res.replace( re, QString() );
CrsDefinitionFormat
CRS definition formats.
@ Wkt
WKT format (always recommended over proj string format).
@ Proj
Proj string format.
@ Preferred
Preferred format, matching the most recent WKT ISO standard. Currently an alias to WKT2_2019,...
Represents a coordinate reference system (CRS).
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
QgsCoordinateReferenceSystem toGeographicCrs() const
Returns the geographic CRS associated with this CRS object.
static QgsCoordinateReferenceSystem fromProj(const QString &proj)
Creates a CRS from a proj style formatted string.
QString toWkt(Qgis::CrsWktVariant variant=Qgis::CrsWktVariant::Wkt1Gdal, bool multiline=false, int indentationWidth=4) const
Returns a WKT representation of this CRS.
QString celestialBodyName() const
Attempts to retrieve the name of the celestial body associated with the CRS (e.g.
static QgsCoordinateReferenceSystem fromWkt(const QString &wkt)
Creates a CRS from a WKT spatial ref sys definition string.
static PJ_CONTEXT * get()
Returns a thread local instance of a proj context, safe for use in the current thread.
std::unique_ptr< PJ, ProjPJDeleter > proj_pj_unique_ptr
Scoped Proj PJ object.
QStringList errors() const
Returns the (possibly empty) list of collected errors.
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.