[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