24#include <QRegularExpression>
25#include <QRegularExpressionMatch>
27#include "moc_qgscrsdefinitionwidget.cpp"
34 connect( mButtonCalculate, &QPushButton::clicked,
this, &QgsCrsDefinitionWidget::pbnCalculate_clicked );
35 connect( mButtonCopyCRS, &QPushButton::clicked,
this, &QgsCrsDefinitionWidget::pbnCopyCRS_clicked );
36 connect( mButtonValidate, &QPushButton::clicked,
this, &QgsCrsDefinitionWidget::validateCurrent );
42 connect( mFormatComboBox, qOverload<int>( &QComboBox::currentIndexChanged ),
this, &QgsCrsDefinitionWidget::formatChanged );
71 switch ( nativeFormat )
81 whileBlocking( mFormatComboBox )->setCurrentIndex( mFormatComboBox->findData(
static_cast<int>( nativeFormat ) ) );
92 mFormatComboBox->setCurrentIndex( mFormatComboBox->findData(
static_cast<int>(
format ) ) );
97 return mTextEditParameters->toPlainText();
102 mTextEditParameters->setPlainText( definition );
105void QgsCrsDefinitionWidget::pbnCopyCRS_clicked()
107 auto selector = std::make_unique<QgsProjectionSelectionDialog>(
this );
108 if ( selector->exec() )
117void QgsCrsDefinitionWidget::validateCurrent()
119 const QString projDef = mTextEditParameters->toPlainText();
123 QgsScopedProjCollectingLogger projLogger;
130 PROJ_STRING_LIST warnings =
nullptr;
131 PROJ_STRING_LIST grammarErrors =
nullptr;
132 crs.reset( proj_create_from_wkt( context, projDef.toUtf8().constData(),
nullptr, &warnings, &grammarErrors ) );
133 QStringList warningStrings;
134 QStringList grammarStrings;
135 for (
auto iter = warnings; iter && *iter; ++iter )
136 warningStrings << QString( *iter );
137 for (
auto iter = grammarErrors; iter && *iter; ++iter )
138 grammarStrings << QString( *iter );
139 proj_string_list_destroy( warnings );
140 proj_string_list_destroy( grammarErrors );
144 QMessageBox::information(
this, tr(
"Custom Coordinate Reference System" ), tr(
"This WKT projection definition is valid." ) );
148 QMessageBox::warning(
this, tr(
"Custom Coordinate Reference System" ), tr(
"This WKT projection definition is not valid:" ) + QStringLiteral(
"\n\n" ) + warningStrings.join(
'\n' ) + grammarStrings.join(
'\n' ) );
155 const QString projCrsString = projDef + ( projDef.contains( QStringLiteral(
"+type=crs" ) ) ? QString() : QStringLiteral(
" +type=crs" ) );
156 crs.reset( proj_create( context, projCrsString.toUtf8().constData() ) );
159 QMessageBox::information(
this, tr(
"Custom Coordinate Reference System" ), tr(
"This proj projection definition is valid." ) );
163 QMessageBox::warning(
this, tr(
"Custom Coordinate Reference System" ), tr(
"This proj projection definition is not valid:" ) + QStringLiteral(
"\n\n" ) + projLogger.
errors().join(
'\n' ) );
170void QgsCrsDefinitionWidget::formatChanged()
172 QgsCoordinateReferenceSystem
crs;
173 QString newFormatString;
178 crs.createFromWkt( multiLineWktToSingleLine( mTextEditParameters->toPlainText() ) );
180 newFormatString =
crs.toProj();
187 QString proj = mTextEditParameters->toPlainText();
188 proj.replace( QLatin1String(
"+type=crs" ), QString() );
189 proj += QLatin1String(
" +type=crs" );
193 const QByteArray multiLineOption = QStringLiteral(
"MULTILINE=YES" ).toLocal8Bit();
194 const char *
const options[] = { multiLineOption.constData(),
nullptr };
195 newFormatString = QString( proj_as_wkt( pjContext,
crs.get(), PJ_WKT2_2019, options ) );
200 if ( !newFormatString.isEmpty() )
201 mTextEditParameters->setPlainText( newFormatString );
204void QgsCrsDefinitionWidget::pbnCalculate_clicked()
207 QString projDef = mTextEditParameters->toPlainText();
211 double latitude = mNorthWGS84Edit->text().toDouble( &okN );
212 double longitude = mEastWGS84Edit->text().toDouble( &okE );
216 QMessageBox::warning(
this, tr(
"Custom Coordinate Reference System" ), tr(
"Latitude and Longitude must be in decimal form." ) );
217 mProjectedXLabel->clear();
218 mProjectedYLabel->clear();
222 QgsCoordinateReferenceSystem target;
225 projDef = projDef + ( projDef.contains( QStringLiteral(
"+type=crs" ) ) ? QString() : QStringLiteral(
" +type=crs" ) );
235 QMessageBox::warning(
this, tr(
"Custom Coordinate Reference System" ), tr(
"This CRS projection definition is not valid." ) );
236 mProjectedXLabel->clear();
237 mProjectedYLabel->clear();
241 QgsCoordinateReferenceSystem source;
246 source = QgsCoordinateReferenceSystem(
"EPSG:4326" );
253 catch ( QgsNotSupportedException & )
258 const QgsCoordinateTransform transform( source, target, QgsCoordinateTransformContext() );
261 const QgsPointXY res = transform.transform( QgsPointXY( longitude, latitude ) );
263 mProjectedXLabel->setText( QLocale().toString( res.
x(),
'f', precision ) );
264 mProjectedYLabel->setText( QLocale().toString( res.
y(),
'f', precision ) );
266 catch ( QgsCsException &e )
268 mProjectedXLabel->setText( tr(
"Error" ) );
269 mProjectedYLabel->setText( tr(
"Error" ) );
270 QMessageBox::warning(
this, tr(
"Custom Coordinate Reference System" ), e.
what() );
274QString QgsCrsDefinitionWidget::multiLineWktToSingleLine(
const QString &wkt )
277 const thread_local QRegularExpression re( QStringLiteral(
"\\s*\\n\\s*" ), QRegularExpression::MultilineOption );
278 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.