[QGIS Commit] r9334 - in trunk/qgis: python/core python/gui src/app src/app/legend src/core src/gui src/plugins/gps_importer

svn_qgis at osgeo.org svn_qgis at osgeo.org
Mon Sep 15 16:51:02 EDT 2008


Author: timlinux
Date: 2008-09-15 16:51:01 -0400 (Mon, 15 Sep 2008)
New Revision: 9334

Modified:
   trunk/qgis/python/core/qgsvectorfilewriter.sip
   trunk/qgis/python/gui/qgisinterface.sip
   trunk/qgis/src/app/legend/qgslegendlayerfile.cpp
   trunk/qgis/src/app/qgisappinterface.cpp
   trunk/qgis/src/app/qgisappinterface.h
   trunk/qgis/src/core/qgsgeometry.cpp
   trunk/qgis/src/core/qgsgeometry.h
   trunk/qgis/src/core/qgsvectorfilewriter.cpp
   trunk/qgis/src/core/qgsvectorfilewriter.h
   trunk/qgis/src/core/qgsvectorlayer.cpp
   trunk/qgis/src/gui/qgisinterface.h
   trunk/qgis/src/plugins/gps_importer/qgsgpsplugin.cpp
Log:
zoomToActiveLayer instead of zoomActiveLayer. Also applied patch from Magnus Homann to correct issue where save as shapefile does not allow using CRS of project projection.

Modified: trunk/qgis/python/core/qgsvectorfilewriter.sip
===================================================================
--- trunk/qgis/python/core/qgsvectorfilewriter.sip	2008-09-15 14:32:48 UTC (rev 9333)
+++ trunk/qgis/python/core/qgsvectorfilewriter.sip	2008-09-15 20:51:01 UTC (rev 9334)
@@ -28,6 +28,7 @@
     static WriterError writeAsShapefile(QgsVectorLayer* layer,
                                         const QString& shapefileName,
                                         const QString& fileEncoding,
+                                        const QgsCoordinateReferenceSystem*,
                                         bool onlySelected = FALSE);
 
 

Modified: trunk/qgis/python/gui/qgisinterface.sip
===================================================================
--- trunk/qgis/python/gui/qgisinterface.sip	2008-09-15 14:32:48 UTC (rev 9333)
+++ trunk/qgis/python/gui/qgisinterface.sip	2008-09-15 20:51:01 UTC (rev 9334)
@@ -33,7 +33,7 @@
     //! Zoom to previous view extent
     virtual void zoomToPrevious()=0;
     //! Zoome to extent of the active layer
-    virtual void zoomActiveLayer()=0;
+    virtual void zoomToActiveLayer()=0;
 
     //! Add a vector layer
     virtual QgsVectorLayer* addVectorLayer(QString vectorLayerPath, QString baseName, QString providerKey)=0;

Modified: trunk/qgis/src/app/legend/qgslegendlayerfile.cpp
===================================================================
--- trunk/qgis/src/app/legend/qgslegendlayerfile.cpp	2008-09-15 14:32:48 UTC (rev 9333)
+++ trunk/qgis/src/app/legend/qgslegendlayerfile.cpp	2008-09-15 20:51:01 UTC (rev 9334)
@@ -24,10 +24,12 @@
 #include "qgslegendlayer.h"
 #include "qgslegendlayerfile.h"
 #include "qgsmaplayer.h"
+#include "qgsmaprenderer.h"
 #include "qgsrasterlayer.h"
 #include "qgsvectorfilewriter.h"
 #include "qgsvectorlayer.h"
 #include "qgsvectordataprovider.h"
+#include "qgsgenericprojectionselector.h"
 
 // attribute table
 #include "qgsattributetable.h"
@@ -225,6 +227,8 @@
 
 void QgsLegendLayerFile::saveAsShapefileGeneral( bool saveOnlySelection )
 {
+  QgsCoordinateReferenceSystem destCRS;
+
   if ( mLyr.layer()->type() != QgsMapLayer::VECTOR )
     return;
 
@@ -264,6 +268,33 @@
     shapefileName += ".shp";
   }
 
+  destCRS = vlayer->srs();
+  // Find out if we have projections enabled or not
+  if ( QgisApp::instance()->mapCanvas()->mapRenderer()->projectionsEnabled() )
+  {
+    destCRS = QgisApp::instance()->mapCanvas()->mapRenderer()->destinationSrs();
+  }
+  
+  QgsGenericProjectionSelector * mySelector = new QgsGenericProjectionSelector();
+  mySelector->setSelectedCrsId( destCRS.srsid() );
+  mySelector->setMessage(tr("Select the coordinate reference system for the saved shapefile.") +
+                         tr("The data points will be transformed from the layer coordinate reference system."));
+
+  if ( mySelector->exec() )
+  {
+    QgsCoordinateReferenceSystem srs( mySelector->selectedCrsId(), QgsCoordinateReferenceSystem::QGIS_CRSID );
+    destCRS = srs;
+    //   destCRS->createFromId(mySelector->selectedCrsId(), QgsCoordinateReferenceSystem::QGIS_CRSID)
+  }
+  else
+  {
+    // Aborted CS selection, don't save.
+    delete mySelector;
+    return;
+  }
+
+  delete mySelector;
+
   // overwrite the file - user will already have been prompted
   // to verify they want to overwrite by the file dialog above
   if ( QFile::exists( shapefileName ) )
@@ -273,11 +304,12 @@
       return;
     }
   }
+
   // ok if the file existed it should be deleted now so we can continue...
   QApplication::setOverrideCursor( Qt::WaitCursor );
 
   QgsVectorFileWriter::WriterError error;
-  error = QgsVectorFileWriter::writeAsShapefile( vlayer, shapefileName, encoding, saveOnlySelection );
+  error = QgsVectorFileWriter::writeAsShapefile( vlayer, shapefileName, encoding, &destCRS, saveOnlySelection );
 
   QApplication::restoreOverrideCursor();
 

Modified: trunk/qgis/src/app/qgisappinterface.cpp
===================================================================
--- trunk/qgis/src/app/qgisappinterface.cpp	2008-09-15 14:32:48 UTC (rev 9333)
+++ trunk/qgis/src/app/qgisappinterface.cpp	2008-09-15 20:51:01 UTC (rev 9334)
@@ -52,7 +52,7 @@
   qgis->zoomToPrevious();
 }
 
-void QgisAppInterface::zoomActiveLayer()
+void QgisAppInterface::zoomToActiveLayer()
 {
   qgis->zoomToLayerExtent();
 }

Modified: trunk/qgis/src/app/qgisappinterface.h
===================================================================
--- trunk/qgis/src/app/qgisappinterface.h	2008-09-15 14:32:48 UTC (rev 9333)
+++ trunk/qgis/src/app/qgisappinterface.h	2008-09-15 20:51:01 UTC (rev 9334)
@@ -48,7 +48,7 @@
     //! Zoom map to previous extent
     void zoomToPrevious();
     //! Zoom to active layer
-    void zoomActiveLayer();
+    void zoomToActiveLayer();
 
     //! Add a vector layer
     QgsVectorLayer* addVectorLayer( QString vectorLayerPath, QString baseName, QString providerKey );

Modified: trunk/qgis/src/core/qgsgeometry.cpp
===================================================================
--- trunk/qgis/src/core/qgsgeometry.cpp	2008-09-15 14:32:48 UTC (rev 9333)
+++ trunk/qgis/src/core/qgsgeometry.cpp	2008-09-15 20:51:01 UTC (rev 9334)
@@ -2993,6 +2993,132 @@
   return 0;
 }
 
+int QgsGeometry::transform( QgsCoordinateTransform& ct )
+{
+  if ( mDirtyWkb )
+  {
+    exportGeosToWkb();
+  }
+
+  if ( !mGeometry )
+  {
+    QgsDebugMsg( "WKB geometry not available!" );
+    return 1;
+  }
+
+  QGis::WKBTYPE wkbType;
+  memcpy( &wkbType, &( mGeometry[1] ), sizeof( int ) );
+  bool hasZValue = false;
+  int wkbPosition = 5;
+
+  switch ( wkbType )
+  {
+    case QGis::WKBPoint25D:
+    case QGis::WKBPoint:
+    {
+      transformVertex( wkbPosition, ct, hasZValue );
+    }
+    break;
+
+    case QGis::WKBLineString25D:
+      hasZValue = true;
+    case QGis::WKBLineString:
+    {
+      int* npoints = ( int* )( &mGeometry[wkbPosition] );
+      wkbPosition += sizeof( int );
+      for ( int index = 0;index < *npoints;++index )
+      {
+        transformVertex( wkbPosition, ct, hasZValue );
+      }
+      break;
+    }
+
+    case QGis::WKBPolygon25D:
+      hasZValue = true;
+    case QGis::WKBPolygon:
+    {
+      int* nrings = ( int* )( &( mGeometry[wkbPosition] ) );
+      wkbPosition += sizeof( int );
+      int* npoints;
+
+      for ( int index = 0;index < *nrings;++index )
+      {
+        npoints = ( int* )( &( mGeometry[wkbPosition] ) );
+        wkbPosition += sizeof( int );
+        for ( int index2 = 0;index2 < *npoints;++index2 )
+        {
+          transformVertex( wkbPosition, ct, hasZValue );
+        }
+      }
+      break;
+    }
+
+    case QGis::WKBMultiPoint25D:
+      hasZValue = true;
+    case QGis::WKBMultiPoint:
+    {
+      int* npoints = ( int* )( &( mGeometry[wkbPosition] ) );
+      wkbPosition += sizeof( int );
+      for ( int index = 0;index < *npoints;++index )
+      {
+        wkbPosition += ( sizeof( int ) + 1 );
+        transformVertex( wkbPosition, ct, hasZValue );
+      }
+      break;
+    }
+
+    case QGis::WKBMultiLineString25D:
+      hasZValue = true;
+    case QGis::WKBMultiLineString:
+    {
+      int* nlines = ( int* )( &( mGeometry[wkbPosition] ) );
+      int* npoints = 0;
+      wkbPosition += sizeof( int );
+      for ( int index = 0;index < *nlines;++index )
+      {
+        wkbPosition += ( sizeof( int ) + 1 );
+        npoints = ( int* )( &( mGeometry[wkbPosition] ) );
+        wkbPosition += sizeof( int );
+        for ( int index2 = 0; index2 < *npoints; ++index2 )
+        {
+          transformVertex( wkbPosition, ct, hasZValue );
+        }
+      }
+      break;
+    }
+
+    case QGis::WKBMultiPolygon25D:
+      hasZValue = true;
+    case QGis::WKBMultiPolygon:
+    {
+      int* npolys = ( int* )( &( mGeometry[wkbPosition] ) );
+      int* nrings;
+      int* npoints;
+      wkbPosition += sizeof( int );
+      for ( int index = 0;index < *npolys;++index )
+      {
+        wkbPosition += ( 1 + sizeof( int ) ); //skip endian and polygon type
+        nrings = ( int* )( &( mGeometry[wkbPosition] ) );
+        wkbPosition += sizeof( int );
+        for ( int index2 = 0;index2 < *nrings;++index2 )
+        {
+          npoints = ( int* )( &( mGeometry[wkbPosition] ) );
+          wkbPosition += sizeof( int );
+          for ( int index3 = 0;index3 < *npoints;++index3 )
+          {
+            transformVertex( wkbPosition, ct, hasZValue );
+          }
+        }
+      }
+    }
+
+    default:
+      break;
+  }
+  mDirtyGeos = true;
+  return 0;
+}
+
 int QgsGeometry::splitGeometry( const QList<QgsPoint>& splitLine, QList<QgsGeometry*>& newGeometries )
 {
   int returnCode = 0;
@@ -4569,6 +4695,31 @@
   }
 }
 
+void QgsGeometry::transformVertex( int& wkbPosition, QgsCoordinateTransform& ct, bool hasZValue )
+{
+  double x, y, z;
+
+
+  x = *(( double * )( &( mGeometry[wkbPosition] ) ) );
+  y = *(( double * )( &( mGeometry[wkbPosition + sizeof( double )] ) ) );
+  z = 0.0; // Ignore Z for now.
+
+  ct.transformInPlace( x, y, z);
+
+  // new x-coordinate
+  memcpy( &( mGeometry[wkbPosition] ), &x, sizeof( double ) );
+  wkbPosition += sizeof( double );
+
+  // new y-coordinate
+  memcpy( &( mGeometry[wkbPosition] ), &y, sizeof( double ) );
+  wkbPosition += sizeof( double );
+
+  if ( hasZValue )
+  {
+    wkbPosition += sizeof( double );
+  }
+}
+
 int QgsGeometry::splitLinearGeometry( GEOSGeometry *splitLine, QList<QgsGeometry*>& newGeometries )
 {
   if ( !splitLine )

Modified: trunk/qgis/src/core/qgsgeometry.h
===================================================================
--- trunk/qgis/src/core/qgsgeometry.h	2008-09-15 14:32:48 UTC (rev 9333)
+++ trunk/qgis/src/core/qgsgeometry.h	2008-09-15 20:51:01 UTC (rev 9334)
@@ -30,6 +30,7 @@
 #endif
 
 #include "qgspoint.h"
+#include "qgscoordinatetransform.h"
 
 /** polyline is represented as a vector of points */
 typedef QVector<QgsPoint> QgsPolyline;
@@ -233,6 +234,10 @@
      @return 0 in case of success*/
     int translate( double dx, double dy );
 
+    /**Transform this geometry as described by CoordinateTranasform ct
+     @return 0 in case of success*/
+    int transform( QgsCoordinateTransform& ct );
+
     /**Splits this geometry according to a given line. Note that the geometry is only splitted once. If there are several intersections
      between geometry and splitLine, only the first one is considered.
     @param splitLine the line that splits the geometry
@@ -380,6 +385,13 @@
     @param hasZValue 25D type?*/
     void translateVertex( int& wkbPosition, double dx, double dy, bool hasZValue );
 
+    /**Transforms a single vertex by ct.
+     @param ptr pointer to the wkb fragment containing the vertex
+    @param wkbPosition position in wkb array. Is increased automatically by the function
+    @param ct the QgsCoordinateTransform
+    @param hasZValue 25D type?*/
+    void transformVertex( int& wkbPosition, QgsCoordinateTransform& ct, bool hasZValue );
+
     //helper functions for geometry splitting
 
     /**Splits line/multiline geometries

Modified: trunk/qgis/src/core/qgsvectorfilewriter.cpp
===================================================================
--- trunk/qgis/src/core/qgsvectorfilewriter.cpp	2008-09-15 14:32:48 UTC (rev 9333)
+++ trunk/qgis/src/core/qgsvectorfilewriter.cpp	2008-09-15 20:51:01 UTC (rev 9334)
@@ -294,18 +294,36 @@
 QgsVectorFileWriter::writeAsShapefile( QgsVectorLayer* layer,
                                        const QString& shapefileName,
                                        const QString& fileEncoding,
+                                       const QgsCoordinateReferenceSystem* destCRS,
                                        bool onlySelected )
 {
 
+  const QgsCoordinateReferenceSystem* outputCRS;
+  QgsCoordinateTransform* ct;
+
   QgsVectorDataProvider* provider = layer->dataProvider();
+  int shallTransform = false;
 
+  if ( destCRS && destCRS->isValid() )
+  {
+    // This means we should transform
+    outputCRS = destCRS;
+    shallTransform = true;
+  } else {
+    // This means we shouldn't transform, use source CRS as output (if defined)
+    outputCRS = &layer->srs();
+  }  
   QgsVectorFileWriter* writer = new QgsVectorFileWriter( shapefileName,
-      fileEncoding, provider->fields(), provider->geometryType(), &layer->srs() );
+      fileEncoding, provider->fields(), provider->geometryType(), outputCRS );
 
   // check whether file creation was successful
   WriterError err = writer->hasError();
   if ( err != NoError )
   {
+    if (ct != NULL)
+    {
+      delete ct;
+    }
     delete writer;
     return err;
   }
@@ -317,17 +335,37 @@
 
   const QgsFeatureIds& ids = layer->selectedFeaturesIds();
 
+  // Create our transform
+  if (destCRS)
+  {
+    ct = new QgsCoordinateTransform(layer->srs(), *destCRS);
+  }
+
+  // Check for failure
+  if (ct == NULL)
+  {
+    shallTransform = false;
+  }
+
   // write all features
   while ( provider->getNextFeature( fet ) )
   {
     if ( onlySelected && !ids.contains( fet.featureId() ) )
       continue;
 
+    if ( shallTransform )
+    {
+      fet.geometry()->transform(*ct);
+    }
     writer->addFeature( fet );
   }
 
   delete writer;
 
+  if (shallTransform)
+  {
+    delete ct;
+  }
   return NoError;
 }
 

Modified: trunk/qgis/src/core/qgsvectorfilewriter.h
===================================================================
--- trunk/qgis/src/core/qgsvectorfilewriter.h	2008-09-15 14:32:48 UTC (rev 9333)
+++ trunk/qgis/src/core/qgsvectorfilewriter.h	2008-09-15 20:51:01 UTC (rev 9334)
@@ -55,6 +55,7 @@
     static WriterError writeAsShapefile( QgsVectorLayer* layer,
                                          const QString& shapefileName,
                                          const QString& fileEncoding,
+                                         const QgsCoordinateReferenceSystem *destCRS,
                                          bool onlySelected = FALSE );
 
 

Modified: trunk/qgis/src/core/qgsvectorlayer.cpp
===================================================================
--- trunk/qgis/src/core/qgsvectorlayer.cpp	2008-09-15 14:32:48 UTC (rev 9333)
+++ trunk/qgis/src/core/qgsvectorlayer.cpp	2008-09-15 20:51:01 UTC (rev 9334)
@@ -3301,7 +3301,8 @@
         transformPoint( x, y, theMapToPixelTransform, ct );
         //QPointF pt(x - (marker->width()/2),  y - (marker->height()/2));
         //QPointF pt(x/markerScaleFactor - (marker->width()/2),  y/markerScaleFactor - (marker->height()/2));
-        QPointF pt( x, y );
+        QPointF pt( x*rasterScaleFactor - ( marker->width() / 2 ),  y*rasterScaleFactor - ( marker->height() / 2 ) );
+        //QPointF pt( x, y );
 
 #if defined(Q_WS_X11)
         // Work around a +/- 32768 limitation on coordinates in X11

Modified: trunk/qgis/src/gui/qgisinterface.h
===================================================================
--- trunk/qgis/src/gui/qgisinterface.h	2008-09-15 14:32:48 UTC (rev 9333)
+++ trunk/qgis/src/gui/qgisinterface.h	2008-09-15 20:51:01 UTC (rev 9334)
@@ -66,7 +66,7 @@
     //! Zoom to previous view extent
     virtual void zoomToPrevious() = 0;
     //! Zoome to extent of the active layer
-    virtual void zoomActiveLayer() = 0;
+    virtual void zoomToActiveLayer() = 0;
 
     //! Add a vector layer
     virtual QgsVectorLayer* addVectorLayer( QString vectorLayerPath, QString baseName, QString providerKey ) = 0;

Modified: trunk/qgis/src/plugins/gps_importer/qgsgpsplugin.cpp
===================================================================
--- trunk/qgis/src/plugins/gps_importer/qgsgpsplugin.cpp	2008-09-15 14:32:48 UTC (rev 9333)
+++ trunk/qgis/src/plugins/gps_importer/qgsgpsplugin.cpp	2008-09-15 20:51:01 UTC (rev 9334)
@@ -556,6 +556,8 @@
   if ( mBabelPath.isEmpty() )
     mBabelPath = "gpsbabel";
   // the importable formats
+  mImporters["Shapefile"] =
+    new QgsSimpleBabelFormat( "shape", true, true, true );
   mImporters["Geocaching.com .loc"] =
     new QgsSimpleBabelFormat( "geo", true, false, false );
   mImporters["Magellan Mapsend"] =



More information about the QGIS-commit mailing list