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.

git-svn-id: http://svn.osgeo.org/qgis/trunk@9334 c8812cc2-4d05-0410-92ff-de0c093fc19c
This commit is contained in:
timlinux 2008-09-15 20:51:01 +00:00
parent 4c8f30aaa0
commit 2659556af1
12 changed files with 246 additions and 8 deletions

View File

@ -28,6 +28,7 @@ public:
static WriterError writeAsShapefile(QgsVectorLayer* layer,
const QString& shapefileName,
const QString& fileEncoding,
const QgsCoordinateReferenceSystem*,
bool onlySelected = FALSE);

View File

@ -33,7 +33,7 @@ class QgisInterface : QObject
//! 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;

View File

@ -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::saveSelectionAsShapefile()
void QgsLegendLayerFile::saveAsShapefileGeneral( bool saveOnlySelection )
{
QgsCoordinateReferenceSystem destCRS;
if ( mLyr.layer()->type() != QgsMapLayer::VECTOR )
return;
@ -264,6 +268,33 @@ void QgsLegendLayerFile::saveAsShapefileGeneral( bool saveOnlySelection )
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 @@ void QgsLegendLayerFile::saveAsShapefileGeneral( bool saveOnlySelection )
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();

View File

@ -52,7 +52,7 @@ void QgisAppInterface::zoomToPrevious()
qgis->zoomToPrevious();
}
void QgisAppInterface::zoomActiveLayer()
void QgisAppInterface::zoomToActiveLayer()
{
qgis->zoomToLayerExtent();
}

View File

@ -48,7 +48,7 @@ class QgisAppInterface : public QgisInterface
//! 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 );

View File

@ -2993,6 +2993,132 @@ int QgsGeometry::translate( double dx, double dy )
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::translateVertex( int& wkbPosition, double dx, double dy, bool
}
}
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 )

View File

@ -30,6 +30,7 @@ email : morb at ozemail dot com dot au
#endif
#include "qgspoint.h"
#include "qgscoordinatetransform.h"
/** polyline is represented as a vector of points */
typedef QVector<QgsPoint> QgsPolyline;
@ -233,6 +234,10 @@ class CORE_EXPORT QgsGeometry
@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 @@ class CORE_EXPORT QgsGeometry
@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

View File

@ -294,18 +294,36 @@ QgsVectorFileWriter::WriterError
QgsVectorFileWriter::writeAsShapefile( QgsVectorLayer* layer,
const QString& shapefileName,
const QString& fileEncoding,
const QgsCoordinateReferenceSystem* destCRS,
bool onlySelected )
{
QgsVectorDataProvider* provider = layer->dataProvider();
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 @@ QgsVectorFileWriter::writeAsShapefile( QgsVectorLayer* layer,
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;
}

View File

@ -55,6 +55,7 @@ class CORE_EXPORT QgsVectorFileWriter
static WriterError writeAsShapefile( QgsVectorLayer* layer,
const QString& shapefileName,
const QString& fileEncoding,
const QgsCoordinateReferenceSystem *destCRS,
bool onlySelected = FALSE );

View File

@ -3301,7 +3301,8 @@ void QgsVectorLayer::drawFeature( QPainter* p,
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

View File

@ -66,7 +66,7 @@ class GUI_EXPORT QgisInterface : public QObject
//! 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;

View File

@ -556,6 +556,8 @@ void QgsGPSPlugin::setupBabel()
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"] =