Skip to content

Commit

Permalink
Reverse select CRS
Browse files Browse the repository at this point in the history
  • Loading branch information
m-kuhn committed Nov 19, 2021
1 parent c5ac87a commit 1b2dd54
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 52 deletions.
120 changes: 75 additions & 45 deletions src/providers/postgres/qgspostgresprovider.cpp
Expand Up @@ -351,16 +351,16 @@ QString QgsPostgresProvider::providerKey()
void QgsPostgresProvider::setTransaction( QgsTransaction *transaction )
{
// static_cast since layers cannot be added to a transaction of a non-matching provider
mTransaction = static_cast<QgsPostgresTransaction *>( transaction );
mTransaction = static_cast<QgsPostgresTransaction *>( transaction );
}

struct Ewkt
{
int srid = -1;
QString wkt;
int srid = -1;
QString wkt;
};

QgsReferencedGeometry QgsPostgresProvider::fromEwkt(const QString &ewkt, QgsPostgresConn *conn)
QgsReferencedGeometry QgsPostgresProvider::fromEwkt( const QString &ewkt, QgsPostgresConn *conn )
{
thread_local const QRegularExpression regularExpressionSRID( "^SRID=(\\d+);" );

Expand All @@ -379,55 +379,85 @@ QgsReferencedGeometry QgsPostgresProvider::fromEwkt(const QString &ewkt, QgsPost
return QgsReferencedGeometry( geom, sridToCoordSystem( ewktInfo.srid, conn ) );
}

QString QgsPostgresProvider::toEwkt(const QgsReferencedGeometry &geom)
QString QgsPostgresProvider::toEwkt( const QgsReferencedGeometry &geom, QgsPostgresConn *conn )
{
return QStringLiteral( "SRID=%1;%2" ).arg( QString::number( geom.crs().postgisSrid() ), geom.asWkt() );
return QStringLiteral( "SRID=%1;%2" ).arg( QString::number( crsToSrid( geom.crs(), conn ) ), geom.asWkt() );
}

QString QgsPostgresProvider::geomAttrToString(const QVariant &attr)
QString QgsPostgresProvider::geomAttrToString( const QVariant &attr, QgsPostgresConn *conn )
{
if ( attr.type() == QVariant::String )
return attr.toString();
else
return toEwkt( attr.value<QgsReferencedGeometry>() );
if ( attr.type() == QVariant::String )
return attr.toString();
else
return toEwkt( attr.value<QgsReferencedGeometry>(), conn );
}

QgsCoordinateReferenceSystem QgsPostgresProvider::sridToCoordSystem(int srid, QgsPostgresConn *conn)
static QMutex sMutex;
static QMap<int, QgsCoordinateReferenceSystem> sCrsCache;

int QgsPostgresProvider::crsToSrid( const QgsCoordinateReferenceSystem &crs, QgsPostgresConn *conn )
{
QgsCoordinateReferenceSystem crs;
QMutexLocker locker( &sMutex );
int srid = sCrsCache.key( crs );

static QMutex sMutex;
if ( srid > -1 )
return srid;
else
{
if ( conn )
{
QStringList authParts = crs.authid().split( ':' );
if ( authParts.size() != 2 )
return -1;
const QString authName = authParts.first();
const QString authId = authParts.last();
QgsPostgresResult result( conn->PQexec( QStringLiteral( "SELECT srid FROM spatial_ref_sys WHERE auth_name='%1' AND auth_srid=%2" ).arg( authName, authId ) ) );

QMutexLocker locker( &sMutex );
static QMap<int, QgsCoordinateReferenceSystem> sCrsCache;
if ( sCrsCache.contains( srid ) )
crs = sCrsCache.value( srid );
else
if ( result.PQresultStatus() == PGRES_TUPLES_OK )
{
if ( conn )
int srid = result.PQgetvalue( 0, 0 ).toInt();
sCrsCache.insert( srid, crs );
return srid;
}
}
}

return -1;
}

QgsCoordinateReferenceSystem QgsPostgresProvider::sridToCoordSystem( int srid, QgsPostgresConn *conn )
{
QgsCoordinateReferenceSystem crs;

QMutexLocker locker( &sMutex );
if ( sCrsCache.contains( srid ) )
crs = sCrsCache.value( srid );
else
{
if ( conn )
{
QgsPostgresResult result( conn->PQexec( QStringLiteral( "SELECT auth_name, auth_srid, srtext, proj4text FROM spatial_ref_sys WHERE srid=%1" ).arg( srid ) ) );
if ( result.PQresultStatus() == PGRES_TUPLES_OK )
{
const QString authName = result.PQgetvalue( 0, 0 );
const QString authSRID = result.PQgetvalue( 0, 1 );
const QString srText = result.PQgetvalue( 0, 2 );
bool ok = false;
if ( authName == QLatin1String( "EPSG" ) || authName == QLatin1String( "ESRI" ) )
{
QgsPostgresResult result( conn->PQexec( QStringLiteral( "SELECT auth_name, auth_srid, srtext, proj4text FROM spatial_ref_sys WHERE srid=%1" ).arg( srid ) ) );
if ( result.PQresultStatus() == PGRES_TUPLES_OK )
{
const QString authName = result.PQgetvalue( 0, 0 );
const QString authSRID = result.PQgetvalue( 0, 1 );
const QString srText = result.PQgetvalue( 0, 2 );
bool ok = false;
if ( authName == QLatin1String( "EPSG" ) || authName == QLatin1String( "ESRI" ) )
{
ok = crs.createFromUserInput( authName + ':' + authSRID );
}
if ( !ok && !srText.isEmpty() )
{
ok = crs.createFromUserInput( srText );
}
if ( !ok )
crs = QgsCoordinateReferenceSystem::fromProj( result.PQgetvalue( 0, 3 ) );
sCrsCache.insert( srid, crs );
}
ok = crs.createFromUserInput( authName + ':' + authSRID );
}
if ( !ok && !srText.isEmpty() )
{
ok = crs.createFromUserInput( srText );
}
if ( !ok )
crs = QgsCoordinateReferenceSystem::fromProj( result.PQgetvalue( 0, 3 ) );
sCrsCache.insert( srid, crs );
}
return crs;
}
}
return crs;
}

void QgsPostgresProvider::disconnectDb()
Expand Down Expand Up @@ -2528,7 +2558,7 @@ bool QgsPostgresProvider::addFeatures( QgsFeatureList &flist, Flags flags )
}
else if ( fieldTypeName == QLatin1String( "geometry" ) )
{
QString val = geomAttrToString( v );
QString val = geomAttrToString( v, connectionRO() );
values += QStringLiteral( "%1%2(%3)" )
.arg( delim,
connectionRO()->majorVersion() < 2 ? "geomfromewkt" : "st_geomfromewkt",
Expand Down Expand Up @@ -3135,7 +3165,7 @@ bool QgsPostgresProvider::changeAttributeValues( const QgsChangedAttributesMap &
}
else if ( fld.typeName() == QLatin1String( "geometry" ) )
{
QString val = geomAttrToString( siter.value() );
QString val = geomAttrToString( siter.value(), connectionRO() );

sql += QStringLiteral( "%1(%2)" )
.arg( connectionRO()->majorVersion() < 2 ? "geomfromewkt" : "st_geomfromewkt",
Expand Down Expand Up @@ -3501,7 +3531,7 @@ bool QgsPostgresProvider::changeFeatures( const QgsChangedAttributesMap &attr_ma

if ( fld.typeName() == QLatin1String( "geometry" ) )
{
QString val = geomAttrToString( siter.value() ) ;
QString val = geomAttrToString( siter.value(), connectionRO() ) ;
sql += QStringLiteral( "%1(%2)" )
.arg( connectionRO()->majorVersion() < 2 ? "geomfromewkt" : "st_geomfromewkt",
quotedValue( val ) );
Expand Down Expand Up @@ -4990,7 +5020,7 @@ QVariant QgsPostgresProvider::parseArray( const QString &txt, QVariant::Type typ

QVariant QgsPostgresProvider::convertValue( QVariant::Type type, QVariant::Type subType, const QString &value, const QString &typeName ) const
{
return convertValue( type, subType, value, typeName, connectionRO() );
return convertValue( type, subType, value, typeName, connectionRO() );
}

QVariant QgsPostgresProvider::convertValue( QVariant::Type type, QVariant::Type subType, const QString &value, const QString &typeName, QgsPostgresConn *conn )
Expand All @@ -5016,7 +5046,7 @@ QVariant QgsPostgresProvider::convertValue( QVariant::Type type, QVariant::Type
else
result = QVariant( type );
break;
case QVariant::UserType:
case QVariant::UserType:
result = fromEwkt( value, conn );
break;

Expand Down
15 changes: 8 additions & 7 deletions src/providers/postgres/qgspostgresprovider.h
Expand Up @@ -219,8 +219,8 @@ class QgsPostgresProvider final: public QgsVectorDataProvider
* \param value the value to convert
* \returns a QVariant of the given type or a null QVariant
*/
QVariant convertValue(QVariant::Type type, QVariant::Type subType, const QString &value, const QString &typeName) const;
static QVariant convertValue(QVariant::Type type, QVariant::Type subType, const QString &value, const QString &typeName, QgsPostgresConn *conn );
QVariant convertValue( QVariant::Type type, QVariant::Type subType, const QString &value, const QString &typeName ) const;
static QVariant convertValue( QVariant::Type type, QVariant::Type subType, const QString &value, const QString &typeName, QgsPostgresConn *conn );

QList<QgsRelation> discoverRelations( const QgsVectorLayer *self, const QList<QgsVectorLayer *> &layers ) const override;
QgsAttrPalIndexNameHash palAttributeIndexNames() const override;
Expand Down Expand Up @@ -279,7 +279,7 @@ class QgsPostgresProvider final: public QgsVectorDataProvider
static QVariant parseOtherArray( const QString &txt, QVariant::Type subType, const QString &typeName, QgsPostgresConn *conn );
static QVariant parseStringArray( const QString &txt );
static QVariant parseMultidimensionalArray( const QString &txt );
static QVariant parseArray(const QString &txt, QVariant::Type type, QVariant::Type subType, const QString &typeName, QgsPostgresConn *conn);
static QVariant parseArray( const QString &txt, QVariant::Type type, QVariant::Type subType, const QString &typeName, QgsPostgresConn *conn );


/**
Expand Down Expand Up @@ -503,10 +503,11 @@ class QgsPostgresProvider final: public QgsVectorDataProvider

std::unique_ptr< QgsPostgresListener > mListener;

static QgsReferencedGeometry fromEwkt(const QString &ewkt , QgsPostgresConn *conn);
static QString toEwkt( const QgsReferencedGeometry &geom );
static QString geomAttrToString( const QVariant& attr );
static QgsCoordinateReferenceSystem sridToCoordSystem(int srsId , QgsPostgresConn *conn);
static QgsReferencedGeometry fromEwkt( const QString &ewkt, QgsPostgresConn *conn );
static QString toEwkt( const QgsReferencedGeometry &geom, QgsPostgresConn *conn );
static QString geomAttrToString( const QVariant &attr, QgsPostgresConn *conn );
static int crsToSrid( const QgsCoordinateReferenceSystem &crs, QgsPostgresConn *conn );
static QgsCoordinateReferenceSystem sridToCoordSystem( int srsId, QgsPostgresConn *conn );

};

Expand Down

0 comments on commit 1b2dd54

Please sign in to comment.