24 #include "qgsogrprovider.h"
27 #include <cpl_error.h>
28 #include <QJsonDocument>
31 #include <QTextStream>
32 #include <QDataStream>
34 #include "ogr_srs_api.h"
40 #define OGR_F_IsFieldSetAndNotNull OGR_F_IsFieldSet
47 OGR_DS_Destroy( source );
53 OGR_G_DestroyGeometry( geometry );
58 OGR_Fld_Destroy( definition );
63 OGR_F_Destroy( feature );
80 CPLPushErrorHandler( CPLQuietErrorHandler );
81 GDALDeleteDataset( driver, path.toUtf8().constData() );
93 GDALDestroyWarpOptions( options );
105 feature.
setId( OGR_F_GetFID( ogrFet ) );
108 if ( !readOgrFeatureGeometry( ogrFet, feature ) )
113 if ( !readOgrFeatureAttributes( ogrFet, fields, feature, encoding ) )
128 int fieldCount = OGR_F_GetFieldCount( ogrFet );
129 for (
int i = 0; i < fieldCount; ++i )
131 OGRFieldDefnH fldDef = OGR_F_GetFieldDefnRef( ogrFet, i );
138 QString name = encoding ? encoding->toUnicode( OGR_Fld_GetNameRef( fldDef ) ) : QString::fromUtf8( OGR_Fld_GetNameRef( fldDef ) );
139 QVariant::Type varType;
140 switch ( OGR_Fld_GetType( fldDef ) )
143 if ( OGR_Fld_GetSubType( fldDef ) == OFSTBoolean )
144 varType = QVariant::Bool;
146 varType = QVariant::Int;
149 varType = QVariant::LongLong;
152 varType = QVariant::Double;
155 varType = QVariant::Date;
158 varType = QVariant::Time;
161 varType = QVariant::DateTime;
164 #if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(2,4,0)
165 if ( OGR_Fld_GetSubType( fldDef ) == OFSTJSON )
166 varType = QVariant::Map;
168 varType = QVariant::String;
172 varType = QVariant::String;
182 if ( attIndex < 0 || attIndex >= fields.
count() )
190 return getOgrFeatureAttribute( ogrFet, field, attIndex, encoding, ok );
195 if ( !ogrFet || attIndex < 0 )
202 OGRFieldDefnH fldDef = OGR_F_GetFieldDefnRef( ogrFet, attIndex );
209 QgsDebugMsg( QStringLiteral(
"ogrFet->GetFieldDefnRef(attindex) returns NULL" ) );
220 switch ( field.
type() )
222 case QVariant::String:
225 value = QVariant( encoding->toUnicode( OGR_F_GetFieldAsString( ogrFet, attIndex ) ) );
227 value = QVariant( QString::fromUtf8( OGR_F_GetFieldAsString( ogrFet, attIndex ) ) );
231 value = QVariant( OGR_F_GetFieldAsInteger( ogrFet, attIndex ) );
234 value = QVariant(
bool( OGR_F_GetFieldAsInteger( ogrFet, attIndex ) ) );
236 case QVariant::LongLong:
237 value = QVariant( OGR_F_GetFieldAsInteger64( ogrFet, attIndex ) );
239 case QVariant::Double:
240 value = QVariant( OGR_F_GetFieldAsDouble( ogrFet, attIndex ) );
243 case QVariant::DateTime:
246 int year, month, day, hour, minute, second, tzf;
248 OGR_F_GetFieldAsDateTime( ogrFet, attIndex, &year, &month, &day, &hour, &minute, &second, &tzf );
249 if ( field.
type() == QVariant::Date )
250 value = QDate( year, month, day );
251 else if ( field.
type() == QVariant::Time )
252 value = QTime( hour, minute, second );
254 value = QDateTime( QDate( year, month, day ), QTime( hour, minute, second ) );
258 case QVariant::ByteArray:
261 const GByte *b = OGR_F_GetFieldAsBinary( ogrFet, attIndex, &size );
265 QByteArray ba = QByteArray::fromRawData(
reinterpret_cast<const char *
>( b ), size );
274 if ( field.
subType() == QVariant::String )
277 char **lst = OGR_F_GetFieldAsStringList( ogrFet, attIndex );
278 const int count = CSLCount( lst );
281 for (
int i = 0; i < count; i++ )
284 list << encoding->toUnicode( lst[i] );
286 list << QString::fromUtf8( lst[i] );
293 Q_ASSERT_X(
false,
"QgsOgrUtils::getOgrFeatureAttribute",
"unsupported field type" );
305 value = QJsonDocument::fromJson( encoding->toUnicode( OGR_F_GetFieldAsString( ogrFet, attIndex ) ).toUtf8() ).toVariant();
307 value = QJsonDocument::fromJson( QString::fromUtf8( OGR_F_GetFieldAsString( ogrFet, attIndex ) ).toUtf8() ).toVariant();
311 Q_ASSERT_X(
false,
"QgsOgrUtils::getOgrFeatureAttribute",
"unsupported field type" );
318 value = QVariant( QString() );
334 for (
int idx = 0; idx < fields.
count(); ++idx )
336 QVariant value = getOgrFeatureAttribute( ogrFet, fields, idx, encoding, &ok );
350 OGRGeometryH geom = OGR_F_GetGeometryRef( ogrFet );
354 feature.
setGeometry( ogrGeometryToQgsGeometry( geom ) );
364 OGR_G_GetPointZM( geom, 0, &x, &y, &z, &m );
365 return qgis::make_unique< QgsPoint >( wkbType, x, y, z, m );
370 std::unique_ptr< QgsMultiPoint > mp = qgis::make_unique< QgsMultiPoint >();
372 const int count = OGR_G_GetGeometryCount( geom );
373 mp->reserve( count );
374 for (
int i = 0; i < count; ++i )
386 int count = OGR_G_GetPointCount( geom );
387 QVector< double > x( count );
388 QVector< double > y( count );
390 double *pz =
nullptr;
396 double *pm =
nullptr;
403 OGR_G_GetPointsZM( geom, x.data(),
sizeof(
double ), y.data(),
sizeof(
double ), pz,
sizeof(
double ), pm,
sizeof(
double ) );
410 std::unique_ptr< QgsMultiLineString > mp = qgis::make_unique< QgsMultiLineString >();
412 const int count = OGR_G_GetGeometryCount( geom );
413 mp->reserve( count );
414 for (
int i = 0; i < count; ++i )
424 switch ( ogrGeomType )
426 case wkbUnknown:
return QgsWkbTypes::Type::Unknown;
427 case wkbPoint:
return QgsWkbTypes::Type::Point;
428 case wkbLineString:
return QgsWkbTypes::Type::LineString;
429 case wkbPolygon:
return QgsWkbTypes::Type::Polygon;
430 case wkbMultiPoint:
return QgsWkbTypes::Type::MultiPoint;
431 case wkbMultiLineString:
return QgsWkbTypes::Type::MultiLineString;
432 case wkbMultiPolygon:
return QgsWkbTypes::Type::MultiPolygon;
433 case wkbGeometryCollection:
return QgsWkbTypes::Type::GeometryCollection;
434 case wkbCircularString:
return QgsWkbTypes::Type::CircularString;
435 case wkbCompoundCurve:
return QgsWkbTypes::Type::CompoundCurve;
436 case wkbCurvePolygon:
return QgsWkbTypes::Type::CurvePolygon;
437 case wkbMultiCurve:
return QgsWkbTypes::Type::MultiCurve;
438 case wkbMultiSurface:
return QgsWkbTypes::Type::MultiSurface;
439 case wkbCurve:
return QgsWkbTypes::Type::Unknown;
440 case wkbSurface:
return QgsWkbTypes::Type::Unknown;
441 case wkbPolyhedralSurface:
return QgsWkbTypes::Type::Unknown;
442 case wkbTIN:
return QgsWkbTypes::Type::Unknown;
443 case wkbTriangle:
return QgsWkbTypes::Type::Triangle;
445 case wkbNone:
return QgsWkbTypes::Type::NoGeometry;
446 case wkbLinearRing:
return QgsWkbTypes::Type::LineString;
448 case wkbCircularStringZ:
return QgsWkbTypes::Type::CircularStringZ;
449 case wkbCompoundCurveZ:
return QgsWkbTypes::Type::CompoundCurveZ;
450 case wkbCurvePolygonZ:
return QgsWkbTypes::Type::CurvePolygonZ;
451 case wkbMultiCurveZ:
return QgsWkbTypes::Type::MultiCurveZ;
452 case wkbMultiSurfaceZ:
return QgsWkbTypes::Type::MultiSurfaceZ;
453 case wkbCurveZ:
return QgsWkbTypes::Type::Unknown;
454 case wkbSurfaceZ:
return QgsWkbTypes::Type::Unknown;
455 case wkbPolyhedralSurfaceZ:
return QgsWkbTypes::Type::Unknown;
456 case wkbTINZ:
return QgsWkbTypes::Type::Unknown;
457 case wkbTriangleZ:
return QgsWkbTypes::Type::TriangleZ;
459 case wkbPointM:
return QgsWkbTypes::Type::PointM;
460 case wkbLineStringM:
return QgsWkbTypes::Type::LineStringM;
461 case wkbPolygonM:
return QgsWkbTypes::Type::PolygonM;
462 case wkbMultiPointM:
return QgsWkbTypes::Type::MultiPointM;
463 case wkbMultiLineStringM:
return QgsWkbTypes::Type::MultiLineStringM;
464 case wkbMultiPolygonM:
return QgsWkbTypes::Type::MultiPolygonM;
465 case wkbGeometryCollectionM:
return QgsWkbTypes::Type::GeometryCollectionM;
466 case wkbCircularStringM:
return QgsWkbTypes::Type::CircularStringM;
467 case wkbCompoundCurveM:
return QgsWkbTypes::Type::CompoundCurveM;
468 case wkbCurvePolygonM:
return QgsWkbTypes::Type::CurvePolygonM;
469 case wkbMultiCurveM:
return QgsWkbTypes::Type::MultiCurveM;
470 case wkbMultiSurfaceM:
return QgsWkbTypes::Type::MultiSurfaceM;
471 case wkbCurveM:
return QgsWkbTypes::Type::Unknown;
472 case wkbSurfaceM:
return QgsWkbTypes::Type::Unknown;
473 case wkbPolyhedralSurfaceM:
return QgsWkbTypes::Type::Unknown;
474 case wkbTINM:
return QgsWkbTypes::Type::Unknown;
475 case wkbTriangleM:
return QgsWkbTypes::Type::TriangleM;
477 case wkbPointZM:
return QgsWkbTypes::Type::PointZM;
478 case wkbLineStringZM:
return QgsWkbTypes::Type::LineStringZM;
479 case wkbPolygonZM:
return QgsWkbTypes::Type::PolygonZM;
480 case wkbMultiPointZM:
return QgsWkbTypes::Type::MultiPointZM;
481 case wkbMultiLineStringZM:
return QgsWkbTypes::Type::MultiLineStringZM;
482 case wkbMultiPolygonZM:
return QgsWkbTypes::Type::MultiPolygonZM;
483 case wkbGeometryCollectionZM:
return QgsWkbTypes::Type::GeometryCollectionZM;
484 case wkbCircularStringZM:
return QgsWkbTypes::Type::CircularStringZM;
485 case wkbCompoundCurveZM:
return QgsWkbTypes::Type::CompoundCurveZM;
486 case wkbCurvePolygonZM:
return QgsWkbTypes::Type::CurvePolygonZM;
487 case wkbMultiCurveZM:
return QgsWkbTypes::Type::MultiCurveZM;
488 case wkbMultiSurfaceZM:
return QgsWkbTypes::Type::MultiSurfaceZM;
489 case wkbCurveZM:
return QgsWkbTypes::Type::Unknown;
490 case wkbSurfaceZM:
return QgsWkbTypes::Type::Unknown;
491 case wkbPolyhedralSurfaceZM:
return QgsWkbTypes::Type::Unknown;
492 case wkbTINZM:
return QgsWkbTypes::Type::Unknown;
493 case wkbTriangleZM:
return QgsWkbTypes::Type::TriangleZM;
495 case wkbPoint25D:
return QgsWkbTypes::Type::PointZ;
496 case wkbLineString25D:
return QgsWkbTypes::Type::LineStringZ;
497 case wkbPolygon25D:
return QgsWkbTypes::Type::PolygonZ;
498 case wkbMultiPoint25D:
return QgsWkbTypes::Type::MultiPointZ;
499 case wkbMultiLineString25D:
return QgsWkbTypes::Type::MultiLineStringZ;
500 case wkbMultiPolygon25D:
return QgsWkbTypes::Type::MultiPolygonZ;
501 case wkbGeometryCollection25D:
return QgsWkbTypes::Type::GeometryCollectionZ;
505 return QgsWkbTypes::Type::Unknown;
513 const auto ogrGeomType = OGR_G_GetGeometryType( geom );
548 if ( wkbFlatten( wkbType ) == wkbGeometryCollection )
551 if ( OGR_G_GetGeometryCount( geom ) >= 1 &&
552 wkbFlatten( OGR_G_GetGeometryType( OGR_G_GetGeometryRef( geom, 0 ) ) ) == wkbTIN )
554 auto newGeom = OGR_G_ForceToMultiPolygon( OGR_G_Clone( geom ) );
555 auto ret = ogrGeometryToQgsGeometry( newGeom );
556 OGR_G_DestroyGeometry( newGeom );
562 int memorySize = OGR_G_WkbSize( geom );
563 unsigned char *wkb =
new unsigned char[memorySize];
567 uint32_t origGeomType;
568 memcpy( &origGeomType, wkb + 1,
sizeof( uint32_t ) );
569 bool hasZ = ( origGeomType >= 1000 && origGeomType < 2000 ) || ( origGeomType >= 3000 && origGeomType < 4000 );
570 bool hasM = ( origGeomType >= 2000 && origGeomType < 3000 ) || ( origGeomType >= 3000 && origGeomType < 4000 );
573 if ( origGeomType % 1000 == 16 )
576 int nDims = 2 + hasZ + hasM;
579 unsigned char *wkbptr = wkb;
585 memcpy( wkbptr, &newMultiType,
sizeof( uint32_t ) );
590 memcpy( &numGeoms, wkb + 5,
sizeof( uint32_t ) );
594 for ( uint32_t i = 0; i < numGeoms; ++i )
600 memcpy( wkbptr, &newSingleType,
sizeof( uint32_t ) );
601 wkbptr +=
sizeof( uint32_t );
605 memcpy( &nRings, wkbptr,
sizeof( uint32_t ) );
606 wkbptr +=
sizeof( uint32_t );
608 for ( uint32_t j = 0; j < nRings; ++j )
611 memcpy( &nPoints, wkbptr,
sizeof( uint32_t ) );
612 wkbptr +=
sizeof( uint32_t ) +
sizeof(
double ) * nDims * nPoints;
616 else if ( origGeomType % 1000 == 15 )
621 memcpy( wkb + 1, &newType,
sizeof( uint32_t ) );
632 if (
string.isEmpty() )
635 QString randomFileName = QStringLiteral(
"/vsimem/%1" ).arg( QUuid::createUuid().toString() );
638 QByteArray ba =
string.toUtf8();
639 VSIFCloseL( VSIFileFromMemBuffer( randomFileName.toUtf8().constData(),
reinterpret_cast< GByte *
>( ba.data() ),
640 static_cast< vsi_l_offset
>( ba.size() ), FALSE ) );
645 VSIUnlink( randomFileName.toUtf8().constData() );
649 OGRLayerH ogrLayer = OGR_DS_GetLayer( hDS.get(), 0 );
653 VSIUnlink( randomFileName.toUtf8().constData() );
658 while ( oFeat.reset( OGR_L_GetNextFeature( ogrLayer ) ), oFeat )
660 QgsFeature feat = readOgrFeature( oFeat.get(), fields, encoding );
666 VSIUnlink( randomFileName.toUtf8().constData() );
674 if (
string.isEmpty() )
677 QString randomFileName = QStringLiteral(
"/vsimem/%1" ).arg( QUuid::createUuid().toString() );
680 QByteArray ba =
string.toUtf8();
681 VSIFCloseL( VSIFileFromMemBuffer( randomFileName.toUtf8().constData(),
reinterpret_cast< GByte *
>( ba.data() ),
682 static_cast< vsi_l_offset
>( ba.size() ), FALSE ) );
687 VSIUnlink( randomFileName.toUtf8().constData() );
691 OGRLayerH ogrLayer = OGR_DS_GetLayer( hDS.get(), 0 );
695 VSIUnlink( randomFileName.toUtf8().constData() );
701 if ( oFeat.reset( OGR_L_GetNextFeature( ogrLayer ) ), oFeat )
703 fields = readOgrFields( oFeat.get(), encoding );
707 VSIUnlink( randomFileName.toUtf8().constData() );
716 for (
qgssize i = 0; stringList[i]; ++i )
718 strings.append( QString::fromUtf8( stringList[i] ) );
729 char *pszWkt =
nullptr;
730 #if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(3,0,0)
731 const QByteArray multiLineOption = QStringLiteral(
"MULTILINE=NO" ).toLocal8Bit();
732 const QByteArray formatOption = QStringLiteral(
"FORMAT=WKT2" ).toLocal8Bit();
733 const char *
const options[] = {multiLineOption.constData(), formatOption.constData(),
nullptr};
734 OSRExportToWktEx( srs, &pszWkt, options );
736 OSRExportToWkt( srs, &pszWkt );
739 const QString res( pszWkt );
746 const QString wkt = OGRSpatialReferenceToWkt( srs );
755 const QString cpgEncoding = readShapefileEncodingFromCpg( path );
756 if ( !cpgEncoding.isEmpty() )
759 return readShapefileEncodingFromLdid( path );
764 #if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(3,1,0)
766 QgsOgrLayerUniquePtr layer = QgsOgrProviderUtils::getLayer( path,
false, QStringList(), 0, errCause,
false );
767 return layer ? layer->GetMetadataItem( QStringLiteral(
"ENCODING_FROM_CPG" ), QStringLiteral(
"SHAPEFILE" ) ) : QString();
769 if ( !QFileInfo::exists( path ) )
773 const QFileInfo fi( path );
774 const QString baseName = fi.completeBaseName();
775 const QString cpgPath = fi.dir().filePath( QStringLiteral(
"%1.%2" ).arg( baseName, fi.suffix() == QLatin1String(
"SHP" ) ? QStringLiteral(
"CPG" ) : QStringLiteral(
"cpg" ) ) );
776 if ( QFile::exists( cpgPath ) )
778 QFile cpgFile( cpgPath );
779 if ( cpgFile.open( QIODevice::ReadOnly ) )
781 QTextStream cpgStream( &cpgFile );
782 const QString cpgString = cpgStream.readLine();
785 if ( !cpgString.isEmpty() )
790 int cpgCodePage = cpgString.toInt( &ok );
791 if ( ok && ( ( cpgCodePage >= 437 && cpgCodePage <= 950 )
792 || ( cpgCodePage >= 1250 && cpgCodePage <= 1258 ) ) )
794 return QStringLiteral(
"CP%1" ).arg( cpgCodePage );
796 else if ( cpgString.startsWith( QLatin1String(
"8859" ) ) )
798 if ( cpgString.length() > 4 && cpgString.at( 4 ) ==
'-' )
799 return QStringLiteral(
"ISO-8859-%1" ).arg( cpgString.mid( 5 ) );
801 return QStringLiteral(
"ISO-8859-%1" ).arg( cpgString.mid( 4 ) );
803 else if ( cpgString.startsWith( QLatin1String(
"UTF-8" ), Qt::CaseInsensitive ) ||
804 cpgString.startsWith( QLatin1String(
"UTF8" ), Qt::CaseInsensitive ) )
805 return QStringLiteral(
"UTF-8" );
806 else if ( cpgString.startsWith( QLatin1String(
"ANSI 1251" ), Qt::CaseInsensitive ) )
807 return QStringLiteral(
"CP1251" );
819 #if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(3,1,0)
821 QgsOgrLayerUniquePtr layer = QgsOgrProviderUtils::getLayer( path,
false, QStringList(), 0, errCause,
false );
822 return layer ? layer->GetMetadataItem( QStringLiteral(
"ENCODING_FROM_LDID" ), QStringLiteral(
"SHAPEFILE" ) ) : QString();
827 if ( !QFileInfo::exists( path ) )
831 const QFileInfo fi( path );
832 const QString baseName = fi.completeBaseName();
835 const QString dbfPath = fi.dir().filePath( QStringLiteral(
"%1.%2" ).arg( baseName, fi.suffix() == QLatin1String(
"SHP" ) ? QStringLiteral(
"DBF" ) : QStringLiteral(
"dbf" ) ) );
836 if ( QFile::exists( dbfPath ) )
838 QFile dbfFile( dbfPath );
839 if ( dbfFile.open( QIODevice::ReadOnly ) )
842 QDataStream dbfIn( &dbfFile );
843 dbfIn.setByteOrder( QDataStream::LittleEndian );
853 case 1: nCP = 437;
break;
854 case 2: nCP = 850;
break;
855 case 3: nCP = 1252;
break;
856 case 4: nCP = 10000;
break;
857 case 8: nCP = 865;
break;
858 case 10: nCP = 850;
break;
859 case 11: nCP = 437;
break;
860 case 13: nCP = 437;
break;
861 case 14: nCP = 850;
break;
862 case 15: nCP = 437;
break;
863 case 16: nCP = 850;
break;
864 case 17: nCP = 437;
break;
865 case 18: nCP = 850;
break;
866 case 19: nCP = 932;
break;
867 case 20: nCP = 850;
break;
868 case 21: nCP = 437;
break;
869 case 22: nCP = 850;
break;
870 case 23: nCP = 865;
break;
871 case 24: nCP = 437;
break;
872 case 25: nCP = 437;
break;
873 case 26: nCP = 850;
break;
874 case 27: nCP = 437;
break;
875 case 28: nCP = 863;
break;
876 case 29: nCP = 850;
break;
877 case 31: nCP = 852;
break;
878 case 34: nCP = 852;
break;
879 case 35: nCP = 852;
break;
880 case 36: nCP = 860;
break;
881 case 37: nCP = 850;
break;
882 case 38: nCP = 866;
break;
883 case 55: nCP = 850;
break;
884 case 64: nCP = 852;
break;
885 case 77: nCP = 936;
break;
886 case 78: nCP = 949;
break;
887 case 79: nCP = 950;
break;
888 case 80: nCP = 874;
break;
889 case 87:
return QStringLiteral(
"ISO-8859-1" );
890 case 88: nCP = 1252;
break;
891 case 89: nCP = 1252;
break;
892 case 100: nCP = 852;
break;
893 case 101: nCP = 866;
break;
894 case 102: nCP = 865;
break;
895 case 103: nCP = 861;
break;
896 case 104: nCP = 895;
break;
897 case 105: nCP = 620;
break;
898 case 106: nCP = 737;
break;
899 case 107: nCP = 857;
break;
900 case 108: nCP = 863;
break;
901 case 120: nCP = 950;
break;
902 case 121: nCP = 949;
break;
903 case 122: nCP = 936;
break;
904 case 123: nCP = 932;
break;
905 case 124: nCP = 874;
break;
906 case 134: nCP = 737;
break;
907 case 135: nCP = 852;
break;
908 case 136: nCP = 857;
break;
909 case 150: nCP = 10007;
break;
910 case 151: nCP = 10029;
break;
911 case 200: nCP = 1250;
break;
912 case 201: nCP = 1251;
break;
913 case 202: nCP = 1254;
break;
914 case 203: nCP = 1253;
break;
915 case 204: nCP = 1257;
break;
921 return QStringLiteral(
"CP%1" ).arg( nCP );