save_as_vector.diff

Marco Hugentobler, 2010-02-17 10:33 PM

Download (15.9 KB)

View differences:

src/core/qgsvectorfilewriter.h (working copy)
53 53
      ErrProjection // added in 1.5
54 54
    };
55 55

  
56
    /** Write contents of vector layer to a shapefile */
56
    /** Write contents of vector layer to a shapefile
57
        @note: deprecated. Use writeAsVectorFormat instead*/
57 58
    static WriterError writeAsShapefile( QgsVectorLayer* layer,
58 59
                                         const QString& shapefileName,
59 60
                                         const QString& fileEncoding,
......
61 62
                                         bool onlySelected = FALSE,
62 63
                                         QString *errorMessage = 0 );
63 64

  
65
    /** Write contents of vector layer to an (OGR supported) vector formt
66
        @note: this method was added in version 1.5*/
67
    static WriterError writeAsVectorFormat( QgsVectorLayer* layer,
68
                                            const QString& fileName,
69
                                            const QString& fileEncoding,
70
                                            const QgsCoordinateReferenceSystem *destCRS,
71
                                            const QString& driverName = "ESRI Shapefile",
72
                                            bool onlySelected = FALSE,
73
                                            QString *errorMessage = 0 );
74

  
64 75
    /** create shapefile and initialize it */
65 76
    QgsVectorFileWriter( const QString& shapefileName,
66 77
                         const QString& fileEncoding,
......
69 80
                         const QgsCoordinateReferenceSystem* srs,
70 81
                         const QString& driverName = "ESRI Shapefile" );
71 82

  
83
    /**Returns map with format filter string as key and OGR format key as value*/
84
    static QMap< QString, QString> supportedFiltersAndFormats();
85

  
86
    /**Returns filter string that can be used for dialogs*/
87
    static QString fileFilterString();
88

  
89
    /**Creates a filter for an OGR driver key*/
90
    static QString filterForDriver( const QString& driverName );
91

  
72 92
    /** checks whether there were any errors in constructor */
73 93
    WriterError hasError();
74 94

  
src/core/qgsvectorfilewriter.cpp (working copy)
386 386
                                       bool onlySelected,
387 387
                                       QString *errorMessage )
388 388
{
389

  
389
  return writeAsVectorFormat( layer, shapefileName, fileEncoding, destCRS, "ESRI Shapefile", onlySelected, errorMessage );
390
#if 0
390 391
  const QgsCoordinateReferenceSystem* outputCRS;
391 392
  QgsCoordinateTransform* ct = 0;
392 393
  int shallTransform = false;
......
471 472
  }
472 473

  
473 474
  return NoError;
475
#endif //0
474 476
}
475 477

  
478
QgsVectorFileWriter::WriterError
479
QgsVectorFileWriter::writeAsVectorFormat( QgsVectorLayer* layer,
480
    const QString& fileName,
481
    const QString& fileEncoding,
482
    const QgsCoordinateReferenceSystem *destCRS,
483
    const QString& driverName,
484
    bool onlySelected,
485
    QString *errorMessage )
486
{
487
  const QgsCoordinateReferenceSystem* outputCRS;
488
  QgsCoordinateTransform* ct = 0;
489
  int shallTransform = false;
476 490

  
491
  if ( destCRS && destCRS->isValid() )
492
  {
493
    // This means we should transform
494
    outputCRS = destCRS;
495
    shallTransform = true;
496
  }
497
  else
498
  {
499
    // This means we shouldn't transform, use source CRS as output (if defined)
500
    outputCRS = &layer->srs();
501
  }
502
  QgsVectorFileWriter* writer =
503
    new QgsVectorFileWriter( fileName, fileEncoding, layer->pendingFields(), layer->wkbType(), outputCRS, driverName );
504

  
505
  // check whether file creation was successful
506
  WriterError err = writer->hasError();
507
  if ( err != NoError )
508
  {
509
    if ( errorMessage )
510
      *errorMessage = writer->errorMessage();
511
    delete writer;
512
    return err;
513
  }
514

  
515
  QgsAttributeList allAttr = layer->pendingAllAttributesList();
516
  QgsFeature fet;
517

  
518
  layer->select( allAttr, QgsRectangle(), true );
519

  
520
  const QgsFeatureIds& ids = layer->selectedFeaturesIds();
521

  
522
  // Create our transform
523
  if ( destCRS )
524
  {
525
    ct = new QgsCoordinateTransform( layer->srs(), *destCRS );
526
  }
527

  
528
  // Check for failure
529
  if ( ct == NULL )
530
  {
531
    shallTransform = false;
532
  }
533

  
534
  // write all features
535
  while ( layer->nextFeature( fet ) )
536
  {
537
    if ( onlySelected && !ids.contains( fet.id() ) )
538
      continue;
539

  
540
    if ( shallTransform )
541
    {
542
      try
543
      {
544
        fet.geometry()->transform( *ct );
545
      }
546
      catch ( QgsCsException &e )
547
      {
548
        delete ct;
549
        delete writer;
550

  
551
        QString msg = QObject::tr( "Failed to transform a point while drawing a feature of type '%1'. Writing stopped. (Exception: %2)" )
552
                      .arg( fet.typeName() ).arg( e.what() );
553
        QgsLogger::warning( msg );
554
        if ( errorMessage )
555
          *errorMessage = msg;
556

  
557
        return ErrProjection;
558
      }
559
    }
560
    writer->addFeature( fet );
561
  }
562

  
563
  delete writer;
564

  
565
  if ( shallTransform )
566
  {
567
    delete ct;
568
  }
569

  
570
  return NoError;
571
}
572

  
573

  
477 574
bool QgsVectorFileWriter::deleteShapeFile( QString theFileName )
478 575
{
479 576
  QFileInfo fi( theFileName );
......
498 595

  
499 596
  return ok;
500 597
}
598

  
599
QMap< QString, QString> QgsVectorFileWriter::supportedFiltersAndFormats()
600
{
601
  QMap<QString, QString> resultMap;
602

  
603
  QgsApplication::registerOgrDrivers();
604
  int const drvCount = OGRGetDriverCount();
605

  
606
  QString drvName;
607
  QString filterString;
608
  for ( int i = 0; i < drvCount; ++i )
609
  {
610
    OGRSFDriverH drv = OGRGetDriver( i );
611
    if ( drv )
612
    {
613
      drvName = OGR_Dr_GetName( drv );
614
      if ( OGR_Dr_TestCapability( drv, ODrCCreateDataSource ) != 0 )
615
      {
616
        //add driver name and filter to map
617
        filterString = QgsVectorFileWriter::filterForDriver( drvName );
618
        if ( !filterString.isEmpty() )
619
        {
620
          resultMap.insert( filterString, drvName );
621
        }
622
      }
623
    }
624
  }
625

  
626
  return resultMap;
627
}
628

  
629
QString QgsVectorFileWriter::fileFilterString()
630
{
631
  QString filterString;
632
  QMap< QString, QString> driverFormatMap = QgsVectorFileWriter::supportedFiltersAndFormats();
633
  QMap< QString, QString>::const_iterator it = driverFormatMap.constBegin();
634
  for ( ; it != driverFormatMap.constEnd(); ++it )
635
  {
636
    filterString += it.key();
637
  }
638
  return filterString;
639
}
640

  
641
QString QgsVectorFileWriter::filterForDriver( const QString& driverName )
642
{
643
  QString longName;
644
  QString glob;
645

  
646
  if ( driverName.startsWith( "AVCE00" ) )
647
  {
648
    longName = "Arc/Info ASCII Coverage";
649
    glob = "*.e00";
650
  }
651
  else if ( driverName.startsWith( "BNA" ) )
652
  {
653
    longName = "Atlas BNA";
654
    glob = "*.bna";
655
  }
656
  else if ( driverName.startsWith( "CSV" ) )
657
  {
658
    longName = "Comma Separated Value";
659
    glob = "*.csv";
660
  }
661
  else if ( driverName.startsWith( "ESRI" ) )
662
  {
663
    longName = "ESRI Shapefiles";
664
    glob = "*.shp";
665
  }
666
  else if ( driverName.startsWith( "FMEObjects Gateway" ) )
667
  {
668
    longName = "FMEObjects Gateway";
669
    glob = "*.fdd";
670
  }
671
  else if ( driverName.startsWith( "GeoJSON" ) )
672
  {
673
    longName = "GeoJSON";
674
    glob = "*.geojson";
675
  }
676
  else if ( driverName.startsWith( "GeoRSS" ) )
677
  {
678
    longName = "GeoRSS";
679
    glob = "*.xml";
680
  }
681
  else if ( driverName.startsWith( "GML" ) )
682
  {
683
    longName = "Geography Markup Language";
684
    glob = "*.gml";
685
  }
686
  else if ( driverName.startsWith( "GMT" ) )
687
  {
688
    longName = "GMT";
689
    glob = "*.gmt";
690
  }
691
  else if ( driverName.startsWith( "GPX" ) )
692
  {
693
    longName = "GPX";
694
    glob = "*.gpx";
695
  }
696
  else if ( driverName.startsWith( "Interlis 1" ) )
697
  {
698
    longName = "INTERLIS 1";
699
    glob = "*.itf *.xml *.ili";
700
  }
701
  else if ( driverName.startsWith( "Interlis 2" ) )
702
  {
703
    longName = "INTERLIS 2";
704
    glob = "*.itf *.xml *.ili";
705
  }
706
  else if ( driverName.startsWith( "KML" ) )
707
  {
708
    longName = "KML";
709
    glob = "*.kml" ;
710
  }
711
  else if ( driverName.startsWith( "MapInfo File" ) )
712
  {
713
    longName = "Mapinfo File";
714
    glob = "*.mif *.tab";
715
  }
716
  else if ( driverName.startsWith( "DGN" ) )
717
  {
718
    longName = "Microstation DGN";
719
    glob = "*.dgn";
720
  }
721
  else if ( driverName.startsWith( "S57" ) )
722
  {
723
    longName = "S-57 Base file";
724
    glob = "*.000";
725
  }
726
  else if ( driverName.startsWith( "SDTS" ) )
727
  {
728
    longName = "Spatial Data Transfer Standard";
729
    glob = "*catd.ddf";
730
  }
731
  else if ( driverName.startsWith( "SQLite" ) )
732
  {
733
    longName = "SQLite";
734
    glob = "*.sqlite";
735
  }
736
  else if ( driverName.startsWith( "VRT" ) )
737
  {
738
    longName = "VRT - Virtual Datasource ";
739
    glob = "*.vrt";
740
  }
741
  else if ( driverName.startsWith( "XPlane" ) )
742
  {
743
    longName = "X-Plane/Flighgear";
744
    glob = "apt.dat nav.dat fix.dat awy.dat";
745
  }
746
  else
747
  {
748
    return QString();
749
  }
750
  return "[OGR] " + longName + " (" + glob.toLower() + " " + glob.toUpper() + ");;";
751
}
src/app/legend/qgslegendlayer.h (working copy)
87 87
    void saveAsShapefile();
88 88
    void saveSelectionAsShapefile();
89 89

  
90
    void saveAsVectorFile();
91
    void saveSelectionAsVectorFile();
92

  
90 93
    /**update the layer's icon to show whether is in editing mode or in overview */
91 94
    void updateIcon();
92 95

  
......
111 114
    /**Save as shapefile (called from saveAsShapefile and saveSelectionAsShapefile)*/
112 115
    void saveAsShapefileGeneral( bool saveOnlySelection );
113 116

  
117
    void saveAsVectorFileGeneral( bool saveOnlySelection );
118

  
114 119
  private:
115 120
    /** Helper method to make the font bold from all ctors.
116 121
     *  Not to be confused with setFont() which is inherited
src/app/legend/qgslegendlayer.cpp (working copy)
423 423
      }
424 424
    }
425 425

  
426
    // save as shapefile
427
    theMenu.addAction( tr( "Save as shapefile..." ), this, SLOT( saveAsShapefile() ) );
426
    // save as vector file
427
    theMenu.addAction( tr( "Save as..." ), this, SLOT( saveAsVectorFile() ) );
428 428

  
429
    // save selection as shapefile
430
    QAction* saveSelectionAction = theMenu.addAction( tr( "Save selection as shapefile..." ), this, SLOT( saveSelectionAsShapefile() ) );
429
    // save selection as vector file
430
    QAction* saveSelectionAsAction = theMenu.addAction( tr( "Save selection as..." ), this, SLOT( saveSelectionAsVectorFile() ) );
431 431
    if ( vlayer->selectedFeatureCount() == 0 )
432 432
    {
433
      saveSelectionAction->setEnabled( false );
433
      saveSelectionAsAction->setEnabled( false );
434 434
    }
435 435

  
436 436
    theMenu.addSeparator();
......
460 460
  saveAsShapefileGeneral( TRUE );
461 461
}
462 462

  
463
void QgsLegendLayer::saveAsVectorFile()
464
{
465
  saveAsVectorFileGeneral( false );
466
}
467

  
468
void QgsLegendLayer::saveSelectionAsVectorFile()
469
{
470
  saveAsVectorFileGeneral( true );
471
}
472

  
463 473
//////////
464 474

  
465 475
void QgsLegendLayer::setVisible( bool visible )
......
492 502
  legend()->updateOverview();
493 503
}
494 504

  
505
void QgsLegendLayer::saveAsVectorFileGeneral( bool saveOnlySelection )
506
{
507
  if ( mLyr.layer()->type() != QgsMapLayer::VectorLayer )
508
    return;
495 509

  
510
  QgsVectorLayer* vlayer = qobject_cast<QgsVectorLayer *>( mLyr.layer() );
496 511

  
512
  //get output name and format
513
  QSettings settings;
514
  QString filter =  QString( "Shapefiles (*.shp)" );
515
  QString dirName = settings.value( "/UI/lastVectorfileDir", "." ).toString();
516
  QString filterString = QgsVectorFileWriter::fileFilterString();
517
  QString selectedFilter = settings.value( "/UI/lastVectorFilter", "[OGR] ESRI Shapefiles (*.shp *.SHP)" ).toString();
518
  QString outputFile = QFileDialog::getSaveFileName( 0, tr( "Save layer as..." ), dirName, filterString, &selectedFilter );
519
  if ( outputFile.isNull() )
520
  {
521
    return; //cancelled
522
  }
497 523

  
524
  settings.setValue( "/UI/lastVectorfileDir", QFileInfo( outputFile ).absolutePath() );
525
  settings.setValue( "/UI/lastVectorFilter", selectedFilter );
526

  
527
  QMap< QString, QString> filterDriverMap = QgsVectorFileWriter::supportedFiltersAndFormats();
528
  QMap< QString, QString>::const_iterator it = filterDriverMap.find( selectedFilter + ";;" );
529
  if ( it == filterDriverMap.constEnd() )
530
  {
531
    return; //unknown format
532
  }
533

  
534
  QString driverKey = *it;
535

  
536
  //output CRS
537
  QgsCoordinateReferenceSystem destCRS = vlayer->srs();
538
  // Find out if we have projections enabled or not
539
  if ( QgisApp::instance()->mapCanvas()->mapRenderer()->hasCrsTransformEnabled() )
540
  {
541
    destCRS = QgisApp::instance()->mapCanvas()->mapRenderer()->destinationSrs();
542
  }
543

  
544
  QgsGenericProjectionSelector * mySelector = new QgsGenericProjectionSelector();
545
  mySelector->setSelectedCrsId( destCRS.srsid() );
546
  mySelector->setMessage( tr( "Select the coordinate reference system for the saved shapefile. "
547
                              "The data points will be transformed from the layer coordinate reference system." ) );
548

  
549
  if ( mySelector->exec() )
550
  {
551
    QgsCoordinateReferenceSystem srs( mySelector->selectedCrsId(), QgsCoordinateReferenceSystem::InternalCrsId );
552
    destCRS = srs;
553
    //   destCRS->createFromId(mySelector->selectedCrsId(), QgsCoordinateReferenceSystem::InternalCrsId)
554
  }
555
  else
556
  {
557
    // Aborted CS selection, don't save.
558
    delete mySelector;
559
    return;
560
  }
561
  delete mySelector;
562

  
563
  // overwrite the file - user will already have been prompted
564
  // to verify they want to overwrite by the file dialog above
565
  // might not even exists in the given case.
566
  if ( driverKey == "ESRI Shapefile" )
567
  {
568
    // add the extension if not present
569
    if ( !outputFile.endsWith( ".shp", Qt::CaseInsensitive ) )
570
    {
571
      outputFile += ".shp";
572
    }
573
    QgsVectorFileWriter::deleteShapeFile( outputFile );
574
  }
575

  
576
  QString errorMessage;
577
  QgsVectorFileWriter::WriterError error;
578
  error = QgsVectorFileWriter::writeAsVectorFormat( vlayer, outputFile, "utf-8", &destCRS, driverKey, saveOnlySelection, &errorMessage );
579
}
580

  
581

  
498 582
void QgsLegendLayer::saveAsShapefileGeneral( bool saveOnlySelection )
499 583
{
500 584
  QgsCoordinateReferenceSystem destCRS;
python/core/qgsvectorfilewriter.sip (working copy)
31 31
                                        const QgsCoordinateReferenceSystem*,
32 32
                                        bool onlySelected = FALSE);
33 33

  
34
    /** Write contents of vector layer to an (OGR supported) vector formt
35
        @note: this method was added in version 1.5*/
36
    static WriterError writeAsVectorFormat( QgsVectorLayer* layer,
37
                                            const QString& fileName,
38
                                            const QString& fileEncoding,
39
                                            const QgsCoordinateReferenceSystem *destCRS,
40
                                            const QString& driverName = "ESRI Shapefile",
41
                                            bool onlySelected = FALSE,
42
                                            QString *errorMessage = 0 );
43

  
34 44
    /** create shapefile and initialize it */
35 45
    QgsVectorFileWriter(const QString& shapefileName,
36 46
                        const QString& fileEncoding,
......
38 48
                        QGis::WkbType geometryType,
39 49
                        const QgsCoordinateReferenceSystem* srs,
40 50
			const QString& driverName = "ESRI Shapefile" );
51

  
52
    /**Returns map with format filter string as key and OGR format key as value*/
53
    static QMap< QString, QString> supportedFiltersAndFormats();
54

  
55
    /**Returns filter string that can be used for dialogs*/
56
    static QString fileFilterString();
57

  
58
    /**Creates a filter for an OGR driver key*/
59
    static QString filterForDriver( const QString& driverName );
41 60
    
42 61
    /** checks whether there were any errors in constructor */
43 62
    WriterError hasError();