QGIS API Documentation 4.3.0-Master (ffcfc20b9b4)
Loading...
Searching...
No Matches
qgsalgorithmdefineprojection.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsalgorithmdefineprojection.cpp
3 ---------------------
4 begin : February 2025
5 copyright : (C) 2025 by Alexander Bruy
6 email : alexander dot bruy at gmail dot com
7 ***************************************************************************/
8
9/***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
19
20#include "qgsproviderregistry.h"
21#include "qgsvectorlayer.h"
22
23#include <QString>
24
25using namespace Qt::StringLiterals;
26
28
29QString QgsDefineProjectionAlgorithm::name() const
30{
31 return u"definecurrentprojection"_s;
32}
33
34QString QgsDefineProjectionAlgorithm::displayName() const
35{
36 return QObject::tr( "Define projection" );
37}
38
39QStringList QgsDefineProjectionAlgorithm::tags() const
40{
41 return QObject::tr( "layer,shp,prj,qpj,change,alter" ).split( ',' );
42}
43
44QString QgsDefineProjectionAlgorithm::group() const
45{
46 return QObject::tr( "Vector general" );
47}
48
49QString QgsDefineProjectionAlgorithm::groupId() const
50{
51 return u"vectorgeneral"_s;
52}
53
54QString QgsDefineProjectionAlgorithm::shortHelpString() const
55{
56 return QObject::tr(
57 "This algorithm sets an existing layer's projection to the provided CRS without reprojecting features. "
58 "Contrary to the \"Assign projection\" algorithm, it will not output a new layer.\n\n"
59 "If the input layer is a shapefile, the .prj file will be overwritten — or created if "
60 "missing — to match the provided CRS."
61 );
62}
63
64QString QgsDefineProjectionAlgorithm::shortDescription() const
65{
66 return QObject::tr( "Sets an existing layer's projection to the provided CRS without reprojecting features." );
67}
68
69QgsDefineProjectionAlgorithm *QgsDefineProjectionAlgorithm::createInstance() const
70{
71 return new QgsDefineProjectionAlgorithm();
72}
73
74void QgsDefineProjectionAlgorithm::initAlgorithm( const QVariantMap & )
75{
76 addParameter( new QgsProcessingParameterVectorLayer( u"INPUT"_s, QObject::tr( "Input shapefile" ), QList<int>() << static_cast<int>( Qgis::ProcessingSourceType::VectorAnyGeometry ) ) );
77 addParameter( new QgsProcessingParameterCrs( u"CRS"_s, QObject::tr( "CRS" ), QgsCoordinateReferenceSystem( "EPSG:4326" ) ) );
78 addOutput( new QgsProcessingOutputVectorLayer( u"OUTPUT"_s, QObject::tr( "Layer with projection" ) ) );
79}
80
81bool QgsDefineProjectionAlgorithm::prepareAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
82{
83 QGS_MARK_ALGORITHM_SOURCE
84
85 QgsVectorLayer *layer = parameterAsVectorLayer( parameters, u"INPUT"_s, context );
86 const QgsCoordinateReferenceSystem crs = parameterAsCrs( parameters, u"CRS"_s, context );
87
88 if ( !layer )
89 throw QgsProcessingException( QObject::tr( "Invalid input layer" ) );
90
91 mLayerId = layer->id();
92
93 if ( layer->providerType().compare( u"ogr"_s, Qt::CaseSensitivity::CaseInsensitive ) == 0 )
94 {
95 const QVariantMap parts = QgsProviderRegistry::instance()->decodeUri( layer->providerType(), layer->dataProvider()->dataSourceUri() );
96 QString layerPath;
97 if ( parts.size() > 0 )
98 {
99 layerPath = parts.value( u"path"_s ).toString();
100 }
101
102 if ( !layerPath.isEmpty() && layerPath.endsWith( u".shp"_s, Qt::CaseSensitivity::CaseInsensitive ) )
103 {
104 const QString filePath = layerPath.chopped( 4 );
105 const QString wkt = crs.toWkt( Qgis::CrsWktVariant::Wkt1Esri );
106
107 QFile prjFile( filePath + ".prj"_L1 );
108 if ( prjFile.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
109 {
110 QTextStream stream( &prjFile );
111 stream << wkt << Qt::endl;
112 }
113 else
114 {
115 feedback->pushWarning( QObject::tr( "Failed to open .prj file for writing." ) );
116 }
117
118 QFile qpjFile( filePath + ".qpj"_L1 );
119 if ( qpjFile.exists() )
120 {
121 qpjFile.remove();
122 }
123 }
124 else
125 {
126 feedback->pushWarning( QObject::tr( "Data source isn't a shapefile, skipping .prj creation" ) );
127 }
128 }
129 else
130 {
131 feedback->pushInfo( QObject::tr( "Data source isn't a shapefile, skipping .prj creation" ) );
132 }
133
134 layer->setCrs( crs );
135 layer->triggerRepaint();
136
137 return true;
138}
139
140QVariantMap QgsDefineProjectionAlgorithm::processAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
141{
142 Q_UNUSED( parameters );
143 Q_UNUSED( context );
144 Q_UNUSED( feedback );
145
146 QVariantMap results;
147 results.insert( u"OUTPUT"_s, mLayerId );
148 return results;
149}
150
@ VectorAnyGeometry
Any vector layer with geometry.
Definition qgis.h:3749
@ Wkt1Esri
WKT1 as traditionally output by ESRI software, deriving from OGC 99-049.
Definition qgis.h:2602
Represents a coordinate reference system (CRS).
QString toWkt(Qgis::CrsWktVariant variant=Qgis::CrsWktVariant::Wkt1Gdal, bool multiline=false, int indentationWidth=4) const
Returns a WKT representation of this CRS.
Contains information about the context in which a processing algorithm is executed.
Custom exception class for processing related exceptions.
Base class for providing feedback from a processing algorithm.
virtual void pushInfo(const QString &info)
Pushes a general informational message from the algorithm.
virtual void pushWarning(const QString &warning)
Pushes a warning informational message from the algorithm.
A vector layer output for processing algorithms.
A coordinate reference system parameter for processing algorithms.
A vector layer (with or without geometry) parameter for processing algorithms.
QVariantMap decodeUri(const QString &providerKey, const QString &uri)
Breaks a provider data source URI into its component paths (e.g.
static QgsProviderRegistry * instance(const QString &pluginPath=QString())
Means of accessing canonical single instance.
Represents a vector layer which manages a vector based dataset.