|
45 | 45 | #include <QFile> |
46 | 46 | #include <QMessageBox> |
47 | 47 |
|
| 48 | +#include <ogr_srs_api.h> |
| 49 | + |
48 | 50 | extern "C" |
49 | 51 | { |
50 | 52 | #include <sqlite3.h> |
@@ -630,18 +632,80 @@ QgsVectorLayer *QgsOfflineEditing::copyVectorLayer( QgsVectorLayer *layer, sqlit |
630 | 632 | } |
631 | 633 | case GPKG: |
632 | 634 | { |
633 | | - QgsVectorFileWriter::SaveVectorOptions options; |
634 | | - options.driverName = QStringLiteral( "GPKG" ); |
635 | | - options.layerName = tableName; |
636 | | - options.actionOnExistingFile = QgsVectorFileWriter::CreateOrOverwriteLayer; |
637 | | - options.onlySelectedFeatures = onlySelected; |
638 | | - |
639 | | - QString error; |
640 | | - if ( QgsVectorFileWriter::writeAsVectorFormat( layer, offlineDbPath, options, &error ) != QgsVectorFileWriter::NoError ) |
| 635 | + // Set options |
| 636 | + char **options = nullptr; |
| 637 | + |
| 638 | + options = CSLSetNameValue( options, "OVERWRITE", "YES" ); |
| 639 | + options = CSLSetNameValue( options, "IDENTIFIER", layer->name().toUtf8().constData() ); |
| 640 | + options = CSLSetNameValue( options, "DESCRIPTION", layer->dataComment().toUtf8().constData() ); |
| 641 | +#if 0 |
| 642 | + options = CSLSetNameValue( options, "FID", featureId.toUtf8().constData() ); |
| 643 | +#endif |
| 644 | + |
| 645 | + if ( layer->isSpatial() ) |
| 646 | + { |
| 647 | + options = CSLSetNameValue( options, "GEOMETRY_COLUMN", "geom" ); |
| 648 | + options = CSLSetNameValue( options, "SPATIAL_INDEX", "YES" ); |
| 649 | + } |
| 650 | + |
| 651 | + OGRSFDriverH hDriver = nullptr; |
| 652 | + OGRSpatialReferenceH hSRS = OSRNewSpatialReference( layer->crs().toWkt().toLocal8Bit().data() ); |
| 653 | + gdal::ogr_datasource_unique_ptr hDS( OGROpen( offlineDbPath.toUtf8().constData(), true, &hDriver ) ); |
| 654 | + OGRLayerH hLayer = OGR_DS_CreateLayer( hDS.get(), tableName.toUtf8().constData(), hSRS, static_cast<OGRwkbGeometryType>( layer->wkbType() ), options ); |
| 655 | + CSLDestroy( options ); |
| 656 | + if ( hSRS ) |
| 657 | + OSRRelease( hSRS ); |
| 658 | + if ( !hLayer ) |
| 659 | + { |
| 660 | + showWarning( tr( "Creation of layer failed (OGR error: %1)" ).arg( QString::fromUtf8( CPLGetLastErrorMsg() ) ) ); |
| 661 | + return nullptr; |
| 662 | + } |
| 663 | + |
| 664 | + const QgsFields providerFields = layer->dataProvider()->fields(); |
| 665 | + for ( const auto &field : providerFields ) |
| 666 | + { |
| 667 | + const QString fieldName( field.name() ); |
| 668 | + const QVariant::Type type = field.type(); |
| 669 | + OGRFieldType ogrType( OFTString ); |
| 670 | + if ( type == QVariant::Int ) |
| 671 | + ogrType = OFTInteger; |
| 672 | + else if ( type == QVariant::LongLong ) |
| 673 | + ogrType = OFTInteger64; |
| 674 | + else if ( type == QVariant::Double ) |
| 675 | + ogrType = OFTReal; |
| 676 | + else if ( type == QVariant::Time ) |
| 677 | + ogrType = OFTTime; |
| 678 | + else if ( type == QVariant::Date ) |
| 679 | + ogrType = OFTDate; |
| 680 | + else if ( type == QVariant::DateTime ) |
| 681 | + ogrType = OFTDateTime; |
| 682 | + else |
| 683 | + ogrType = OFTString; |
| 684 | + |
| 685 | + int ogrWidth = field.length(); |
| 686 | + |
| 687 | + gdal::ogr_field_def_unique_ptr fld( OGR_Fld_Create( fieldName.toUtf8().constData(), ogrType ) ); |
| 688 | + OGR_Fld_SetWidth( fld.get(), ogrWidth ); |
| 689 | + |
| 690 | + if ( OGR_L_CreateField( hLayer, fld.get(), true ) != OGRERR_NONE ) |
| 691 | + { |
| 692 | + showWarning( tr( "Creation of field %1 failed (OGR error: %2)" ) |
| 693 | + .arg( fieldName, QString::fromUtf8( CPLGetLastErrorMsg() ) ) ); |
| 694 | + return nullptr; |
| 695 | + } |
| 696 | + } |
| 697 | + |
| 698 | + // In GDAL >= 2.0, the driver implements a deferred creation strategy, so |
| 699 | + // issue a command that will force table creation |
| 700 | + CPLErrorReset(); |
| 701 | + OGR_L_ResetReading( hLayer ); |
| 702 | + if ( CPLGetLastErrorType() != CE_None ) |
641 | 703 | { |
642 | | - showWarning( tr( "Packaging layer %1 failed: %2" ).arg( layer->name(), error ) ); |
| 704 | + QString msg( tr( "Creation of layer failed (OGR error: %1)" ).arg( QString::fromUtf8( CPLGetLastErrorMsg() ) ) ); |
| 705 | + showWarning( msg ); |
643 | 706 | return nullptr; |
644 | 707 | } |
| 708 | + hDS.reset(); |
645 | 709 |
|
646 | 710 | QString uri = QStringLiteral( "%1|layername=%2" ).arg( offlineDbPath, tableName ); |
647 | 711 | newLayer = new QgsVectorLayer( uri, layer->name() + " (offline)", QStringLiteral( "ogr" ) ); |
|
0 commit comments