Skip to content

Commit f36bfa5

Browse files
author
gsherman
committedApr 5, 2010
Implementation of the "Add New Spatialite Layer/Database" feature.
Squashed commit of the following: commit e6e01ec0b3955d1cf9cb2756dfcf1aac27a0725e Author: Gary Sherman <gsherman@geoapt.com> Date: Sun Apr 4 17:45:05 2010 -0800 Implementation of the add new spatialite layer dialog with ability to search for epsg srid commit c1d46e35715e4f8baa137800c88483f612ebcb89 Author: Gary Sherman <gsherman@geoapt.com> Date: Sun Apr 4 17:44:23 2010 -0800 Spatialite database template used when creating a new database commit 6d4fd8d80e610d6f0f6d22ed49815134292924c5 Author: Gary Sherman <gsherman@geoapt.com> Date: Sun Apr 4 17:43:31 2010 -0800 Context help for the Add New Spatialite Layer dialog commit 1a6398be174d62df1bf74428bcf898b8d1ea8455 Author: Gary Sherman <gsherman@geoapt.com> Date: Sun Apr 4 17:42:51 2010 -0800 Dialog for finding an SRID from the spatialite spatial_ref_sys table commit 197a65c134ed06b12fd6c8d96900dcf8197f802d Author: Gary Sherman <gsherman@geoapt.com> Date: Sat Apr 3 11:32:58 2010 -0800 Renamed the spatialite srids dialog selector to the proper form commit 66c7cafa78f71b7f06504fe3b7bd4577614bfe67 Author: Gary Sherman <gsherman@geoapt.com> Date: Fri Apr 2 22:25:09 2010 -0800 Implemented create new db. Can now create a new db and an empty layer in one pass. commit 088730293ad4722e7d6045e8661e6c28488b8cae Author: Gary Sherman <gsherman@geoapt.com> Date: Fri Apr 2 20:43:12 2010 -0800 Adjust new spatialite layer dialog. Add field for geometry column name commit d7c60012ddce6a70d0512bc9195524e6d672b372 Author: Gary Sherman <gsherman@geoapt.com> Date: Fri Apr 2 12:46:49 2010 -0800 New spatialite layer menu item does not show up if qgis is built with internal spatialite commit 1343dfe7ac7868c38e8b7bd17ef1dd5a4a04ebad Author: Gary Sherman <gsherman@geoapt.com> Date: Fri Apr 2 11:35:26 2010 -0800 Test of geometry column creation in the dialog commit c8785f4aaee9d5b08fe0c0dd6f6bbfcd9cf6c7a5 Author: Gary Sherman <gsherman@geoapt.com> Date: Wed Mar 31 21:39:03 2010 -0800 Added multi geometry types to the radio button group commit 06350192b9dfa6d6cc5c6ac9c4d0b1a65f260476 Author: Gary Sherman <gsherman@geoapt.com> Date: Wed Mar 31 21:13:20 2010 -0800 SQL for creating the new spatialite table complete---still needs the code to actually push it to the database commit 0e05d6ab9904d003d9c7c7704f53392fc478cee1 Author: Gary Sherman <gsherman@geoapt.com> Date: Wed Mar 31 21:12:25 2010 -0800 Added field for the layer name to be created commit 3c372b4da3097981d824c2dbb7a661c916d9cf7b Author: Gary Sherman <gsherman@Macintosh.local> Date: Tue Mar 30 21:39:10 2010 -0800 Removed unneeded fields from the spatialite dialog (width and precision). Added methods for getting the attributes commit 1871db18a5d87f22caf9a34001c879eaf7f58342 Author: Gary Sherman <gsherman@Macintosh.local> Date: Fri Mar 19 20:51:34 2010 -0800 Renamed ui file commit a42e578afac13d2a9e984faedc79d0d206b48c66 Author: Gary Sherman <gsherman@Macintosh.local> Date: Fri Mar 19 20:51:00 2010 -0800 Added dialog for displaying and selecting a spatialite srid commit d0c48bc2317d175fa13c4e52fb6d4f0b10a58518 Author: Gary Sherman <gsherman@Macintosh.local> Date: Fri Mar 19 19:41:07 2010 -0800 More work on the dialog to create a new spatialite layer commit cc6d8a4e48e42c865eec9da3d2ad1e900fbbe295 Author: Gary Sherman <gsherman@Macintosh.local> Date: Thu Mar 18 20:51:08 2010 -0800 Wire the new spatialite layer dialog into qgisapp commit c5a54601fd9b76e46aeb534f92a605cd744ae768 Author: Gary Sherman <gsherman@Macintosh.local> Date: Thu Mar 18 20:50:18 2010 -0800 Dialog implementation for creating a new spatialite layer git-svn-id: http://svn.osgeo.org/qgis/trunk@13240 c8812cc2-4d05-0410-92ff-de0c093fc19c
1 parent 868a157 commit f36bfa5

14 files changed

+1449
-8
lines changed
 

‎resources/CMakeLists.txt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
2-
INSTALL(FILES srs.db qgis.db qgis_help.db symbology-ng-style.xml
3-
DESTINATION ${QGIS_DATA_DIR}/resources)
4-
5-
SUBDIRS(context_help)
1+
2+
INSTALL(FILES srs.db qgis.db qgis_help.db symbology-ng-style.xml spatialite.db
3+
DESTINATION ${QGIS_DATA_DIR}/resources)
4+
5+
SUBDIRS(context_help)
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<h3>Create a New Spatialite Layer</h3>
2+
You can use this dialog to create a new Spatialite database and/or an empty Spatialite layer for editing. See below for an explanation of the dialog inputs.
3+
<h4>Database</h4>
4+
Choose the database from the drop-down list. This list is created from your saved Spatialite connections. If you don't have a saved connection or want to create a new database, click on the button (<label>...</label>) to the right of the drop-down. If you create a new database you will have to add it to your Spatialite connections in the <i>Add Spatialite Table(s)</i> dialog.
5+
<h4>Layer name</h4>
6+
Enter a name for the layer you want to create. The name should be one word. You can use underscores in the name if you like.
7+
<h4>Geometry column</h4>
8+
Enter a name for the geometry column or accept the default.
9+
<h4>Type</h4>
10+
Choose the type of layer you want to create.
11+
<h4>EPSG SRID</h4>
12+
Enter the EPSG number for the spatial reference id (SRID). By default the SRID for WGS 84 is filled in for you. Click on <label>Find SRID</label> button to change the coordinate reference system of the layer if needed. The SRID must exist within the spatial_ref_sys in your Spatialite database. You can search for the SRID using partial matches on both name and SRID.
13+
<h4>New attribute</h4>
14+
Add the desired attributes by clicking on the <label>Add to attributes list</label> button after you have specified a name and type for the attribute. Only real, integer, and string attributes are supported.<br/>
15+
Width and precision are irrelevant in a Spatialite database so you do not have to specify these.
16+
<h4>Attributes list</h4>
17+
In this section you can see the list of attributes. To delete one of them, click on it and choose <label>Remove selected attribute</label> button.
18+
19+
<p>
20+
To create the layer, click on <label>Apply</label>. The layer will be created and you will be returned to the dialog. From here you can click <label>Close</label> or change the parameters to create additional layers.

‎resources/spatialite.db

577 KB
Binary file not shown.

‎src/app/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ SET(QGIS_APP_SRCS
2424
qgsdelattrdialog.cpp
2525
qgsdisplayangle.cpp
2626
qgsfieldcalculator.cpp
27+
qgsnewspatialitelayerdialog.cpp
2728
qgsnewvectorlayerdialog.cpp
2829
qgsgraduatedsymboldialog.cpp
2930
qgshelpviewer.cpp
@@ -58,6 +59,7 @@ SET(QGIS_APP_SRCS
5859
qgsnewhttpconnection.cpp
5960
qgsnumericsortlistviewitem.cpp
6061
qgsoptions.cpp
62+
qgsspatialitesridsdialog.cpp
6163
qgspastetransformations.cpp
6264
qgspointrotationitem.cpp
6365
qgspluginitem.cpp
@@ -143,6 +145,7 @@ SET (QGIS_APP_MOC_HDRS
143145
qgsfieldcalculator.h
144146
qgsformannotationdialog.h
145147
qgsmaptoolmeasureangle.h
148+
qgsnewspatialitelayerdialog.h
146149
qgsnewvectorlayerdialog.h
147150
qgsgraduatedsymboldialog.h
148151
qgshelpviewer.h
@@ -178,6 +181,7 @@ SET (QGIS_APP_MOC_HDRS
178181
qgswmssourceselect.h
179182
qgssinglesymboldialog.h
180183
qgssnappingdialog.h
184+
qgsspatialitesridsdialog.h
181185
qgsuniquevaluedialog.h
182186
qgsvectorlayerproperties.h
183187
qgsdbtablemodel.h
@@ -330,6 +334,7 @@ IF (WITH_INTERNAL_SPATIALITE)
330334
INCLUDE_DIRECTORIES(../core/spatialite/headers/spatialite)
331335
ELSE (WITH_INTERNAL_SPATIALITE)
332336
INCLUDE_DIRECTORIES(${SQLITE3_INCLUDE_DIR})
337+
ADD_DEFINITIONS(-DEXTERNAL_SPATIALITE)
333338
ENDIF (WITH_INTERNAL_SPATIALITE)
334339

335340
IF (POSTGRES_FOUND)

‎src/app/qgisapp.cpp

Lines changed: 225 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@
214214
#endif
215215
#ifdef HAVE_SPATIALITE
216216
#include "qgsspatialitesourceselect.h"
217+
#include "qgsnewspatialitelayerdialog.h"
217218
#endif
218219

219220
#include "qgspythonutils.h"
@@ -936,11 +937,18 @@ void QgisApp::createActions()
936937

937938
// Layer Menu Items
938939

939-
mActionNewVectorLayer = new QAction( getThemeIcon( "mActionNewVectorLayer.png" ), tr( "New Vector Layer..." ), this );
940-
shortcuts->registerAction( mActionNewVectorLayer, tr( "Ctrl+Shift+N", "Create a New Vector Layer" ) );
941-
mActionNewVectorLayer->setStatusTip( tr( "Create a New Vector Layer" ) );
940+
mActionNewVectorLayer = new QAction( getThemeIcon( "mActionNewVectorLayer.png" ), tr( "New Vector Layer (shapefile)..." ), this );
941+
shortcuts->registerAction( mActionNewVectorLayer, tr( "Ctrl+Shift+N", "Create a New Vector Layer (shapefile)" ) );
942+
mActionNewVectorLayer->setStatusTip( tr( "Create a New Vector Layer (shapefile)" ) );
942943
connect( mActionNewVectorLayer, SIGNAL( triggered() ), this, SLOT( newVectorLayer() ) );
943944

945+
#ifdef HAVE_SPATIALITE
946+
mActionNewSpatialiteLayer = new QAction( getThemeIcon( "mActionNewVectorLayer.png" ), tr( "New Spatialite Layer ..." ), this );
947+
shortcuts->registerAction( mActionNewSpatialiteLayer, tr( "Ctrl+Shift+S", "Create a New Spatialite Layer " ) );
948+
mActionNewSpatialiteLayer->setStatusTip( tr( "Create a New Spatialite Layer " ) );
949+
connect( mActionNewSpatialiteLayer, SIGNAL( triggered() ), this, SLOT( newSpatialiteLayer() ) );
950+
#endif
951+
944952
mActionAddOgrLayer = new QAction( getThemeIcon( "mActionAddOgrLayer.png" ), tr( "Add Vector Layer..." ), this );
945953
shortcuts->registerAction( mActionAddOgrLayer, tr( "Ctrl+Shift+V", "Add a Vector Layer" ) );
946954
mActionAddOgrLayer->setStatusTip( tr( "Add a Vector Layer" ) );
@@ -1411,7 +1419,14 @@ void QgisApp::createMenus()
14111419

14121420
mLayerMenu = menuBar()->addMenu( tr( "&Layer" ) );
14131421

1422+
#ifdef HAVE_SPATIALITE
1423+
QMenu *newLayerMenu = mLayerMenu->addMenu( tr( "New ") );
1424+
newLayerMenu->addAction( mActionNewVectorLayer );
1425+
newLayerMenu->addAction( mActionNewSpatialiteLayer );
1426+
#else
14141427
mLayerMenu->addAction( mActionNewVectorLayer );
1428+
#endif
1429+
14151430
mLayerMenu->addAction( mActionAddOgrLayer );
14161431
mLayerMenu->addAction( mActionAddRasterLayer );
14171432
#ifdef HAVE_POSTGRESQL
@@ -3082,6 +3097,213 @@ void QgisApp::newVectorLayer()
30823097
addVectorLayers( fileNames, enc, "file" );
30833098
}
30843099

3100+
void QgisApp::newSpatialiteLayer()
3101+
{
3102+
if ( mMapCanvas && mMapCanvas->isDrawing() )
3103+
{
3104+
return;
3105+
}
3106+
3107+
QgsNewSpatialiteLayerDialog spatialiteDialog( this );
3108+
if ( spatialiteDialog.exec() == QDialog::Rejected )
3109+
{
3110+
return;
3111+
}
3112+
3113+
QString geometrytype = spatialiteDialog.selectedType();
3114+
//QString fileformat = geomDialog.selectedFileFormat();
3115+
QString crsId = spatialiteDialog.selectedCrsId();
3116+
QString databaseName = spatialiteDialog.databaseName();
3117+
QString newLayerName = spatialiteDialog.layerName();
3118+
//QgsDebugMsg( QString( "New file format will be: %1" ).arg( fileformat ) );
3119+
3120+
// Get the list containing the name/type pairs for each attribute
3121+
QList<QStringList> * items = spatialiteDialog.attributes( );
3122+
3123+
// Build up the sql statement for creating the table
3124+
//
3125+
QString sql = QString("create table %1 (id integer primary key autoincrement").arg(newLayerName);
3126+
// iterate through the field names and add them to the create statement
3127+
// (use indexed access since this is just as fast as iterators
3128+
for ( int i = 0; i < items->size(); ++i )
3129+
{
3130+
QStringList field = items->at(i);
3131+
sql += QString(", %1 %2").arg(field.at(0)).arg(field.at(1));
3132+
}
3133+
// complete the create table statement
3134+
sql += ")";
3135+
std::cout << "Creating table in database " << databaseName.toUtf8().data() << std::endl;
3136+
std::cout << sql.toUtf8().data() << std::endl; // OK
3137+
3138+
QString sqlAddGeom = QString("select AddGeometryColumn('%1', 'geom', %2, '%3', 2)").arg(newLayerName).arg(crsId).arg(geometrytype);
3139+
std::cout << sqlAddGeom.toUtf8().data() << std::endl; // OK
3140+
QString sqlCreateIndex = QString("select CreateSpatialIndex('%1', 'geom')").arg(newLayerName);
3141+
std::cout << sqlCreateIndex.toUtf8().data() << std::endl; // OK
3142+
3143+
sqlite3 *db;
3144+
int rc = sqlite3_open( databaseName.toUtf8(), &db );
3145+
if ( rc != SQLITE_OK )
3146+
{
3147+
QMessageBox::warning( this, "Spatialite Database", tr( "Unable to open the database: %1").arg(databaseName ) );
3148+
}
3149+
else
3150+
{
3151+
char * errmsg;
3152+
rc = sqlite3_exec( db, sql.toUtf8(), NULL, NULL, &errmsg);
3153+
if ( rc != SQLITE_OK )
3154+
{
3155+
QMessageBox::warning( this, tr( "Error deleting bookmark" ),
3156+
tr( "Failed to create the Spatialite table %1. The database returned:\n%2" ).arg( newLayerName ).arg( errmsg ) );
3157+
sqlite3_free( errmsg );
3158+
}
3159+
else
3160+
{
3161+
// create the geometry column and the spatial index
3162+
rc = sqlite3_exec( db, sqlAddGeom.toUtf8(), NULL, NULL, &errmsg);
3163+
if ( rc != SQLITE_OK )
3164+
{
3165+
QMessageBox::warning( this, tr( "Error Creating Geometry Column" ),
3166+
tr( "Failed to create the geometry column. The database returned:\n%1" ).arg( errmsg ) );
3167+
sqlite3_free( errmsg );
3168+
}
3169+
else
3170+
{
3171+
// create the spatial index
3172+
rc = sqlite3_exec( db, sqlCreateIndex.toUtf8(), NULL, NULL, &errmsg);
3173+
if ( rc != SQLITE_OK )
3174+
{
3175+
QMessageBox::warning( this, tr( "Error Creating Spatial Index" ),
3176+
tr( "Failed to create the spatial index. The database returned:\n%1" ).arg( errmsg ) );
3177+
sqlite3_free( errmsg );
3178+
}
3179+
}
3180+
}
3181+
3182+
3183+
}
3184+
3185+
3186+
/*
3187+
bool haveLastUsedFilter = false; // by default, there is no last
3188+
// used filter
3189+
QString enc;
3190+
QString fileName;
3191+
3192+
QSettings settings; // where we keep last used filter in
3193+
// persistent state
3194+
3195+
haveLastUsedFilter = settings.contains( "/UI/lastVectorFileFilter" );
3196+
QString lastUsedFilter = settings.value( "/UI/lastVectorFileFilter",
3197+
QVariant( QString::null ) ).toString();
3198+
3199+
QString lastUsedDir = settings.value( "/UI/lastVectorFileFilterDir",
3200+
"." ).toString();
3201+
3202+
QgsDebugMsg( "Saving vector file dialog without filters: " );
3203+
3204+
QgsEncodingFileDialog* openFileDialog = new QgsEncodingFileDialog( this,
3205+
tr( "Save As" ), lastUsedDir, "", QString( "" ) );
3206+
3207+
// allow for selection of more than one file
3208+
openFileDialog->setFileMode( QFileDialog::AnyFile );
3209+
openFileDialog->setAcceptMode( QFileDialog::AcceptSave );
3210+
openFileDialog->setConfirmOverwrite( true );
3211+
3212+
if ( haveLastUsedFilter ) // set the filter to the last one used
3213+
{
3214+
openFileDialog->selectFilter( lastUsedFilter );
3215+
}
3216+
3217+
int res;
3218+
while (( res = openFileDialog->exec() ) == QDialog::Accepted )
3219+
{
3220+
fileName = openFileDialog->selectedFiles().first();
3221+
3222+
if ( fileformat == "ESRI Shapefile" )
3223+
{
3224+
if ( !isValidShapeFileName( fileName ) )
3225+
{
3226+
fileName += ".shp";
3227+
}
3228+
3229+
if ( !isValidShapeFileName( fileName ) )
3230+
{
3231+
QMessageBox::information( this,
3232+
tr( "New Shapefile" ),
3233+
tr( "Shapefiles must end on .shp" ) );
3234+
continue;
3235+
}
3236+
}
3237+
3238+
break;
3239+
}
3240+
3241+
if ( res == QDialog::Rejected )
3242+
{
3243+
delete openFileDialog;
3244+
return;
3245+
}
3246+
3247+
enc = openFileDialog->encoding();
3248+
3249+
// If the file exists, delete it otherwise we'll end up loading that
3250+
// file, which can cause problems (e.g., if the file contains
3251+
// linestrings, but we're wanting to create points, we'll end up
3252+
// with a linestring file).
3253+
if ( fileformat == "ESRI Shapefile" )
3254+
{
3255+
QgsVectorFileWriter::deleteShapeFile( fileName );
3256+
}
3257+
else
3258+
{
3259+
QFile::remove( fileName );
3260+
}
3261+
3262+
settings.setValue( "/UI/lastVectorFileFilter", openFileDialog->selectedFilter() );
3263+
3264+
settings.setValue( "/UI/lastVectorFileFilterDir", openFileDialog->directory().absolutePath() );
3265+
3266+
delete openFileDialog;
3267+
3268+
//try to create the new layer with OGRProvider instead of QgsVectorFileWriter
3269+
QgsProviderRegistry * pReg = QgsProviderRegistry::instance();
3270+
QString ogrlib = pReg->library( "ogr" );
3271+
// load the data provider
3272+
QLibrary* myLib = new QLibrary( ogrlib );
3273+
bool loaded = myLib->load();
3274+
if ( loaded )
3275+
{
3276+
QgsDebugMsg( "ogr provider loaded" );
3277+
3278+
typedef bool ( *createEmptyDataSourceProc )( const QString&, const QString&, const QString&, QGis::WkbType,
3279+
const std::list<std::pair<QString, QString> >&, const QgsCoordinateReferenceSystem * );
3280+
createEmptyDataSourceProc createEmptyDataSource = ( createEmptyDataSourceProc ) cast_to_fptr( myLib->resolve( "createEmptyDataSource" ) );
3281+
if ( createEmptyDataSource )
3282+
{
3283+
if ( geometrytype != QGis::WKBUnknown )
3284+
{
3285+
QgsCoordinateReferenceSystem srs( crsId, QgsCoordinateReferenceSystem::InternalCrsId );
3286+
createEmptyDataSource( fileName, fileformat, enc, geometrytype, attributes, &srs );
3287+
}
3288+
else
3289+
{
3290+
QgsDebugMsg( "geometry type not recognised" );
3291+
return;
3292+
}
3293+
}
3294+
else
3295+
{
3296+
QgsDebugMsg( "Resolving newEmptyDataSource(...) failed" );
3297+
}
3298+
}
3299+
3300+
//then add the layer to the view
3301+
QStringList fileNames;
3302+
fileNames.append( fileName );
3303+
//todo: the last parameter will change accordingly to layer type
3304+
addVectorLayers( fileNames, enc, "file" );
3305+
*/
3306+
}
30853307
void QgisApp::fileOpen()
30863308
{
30873309
if ( mMapCanvas && mMapCanvas->isDrawing() )

‎src/app/qgisapp.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,7 @@ class QgisApp : public QMainWindow
265265
QAction *actionViewSeparator3() { return mActionViewSeparator3; }
266266

267267
QAction *actionNewVectorLayer() { return mActionNewVectorLayer; }
268+
QAction *actionNewSpatialLiteLayer() { return mActionNewSpatialiteLayer; }
268269
QAction *actionAddOgrLayer() { return mActionAddOgrLayer; }
269270
QAction *actionAddRasterLayer() { return mActionAddRasterLayer; }
270271
QAction *actionAddPgLayer() { return mActionAddPgLayer; }
@@ -488,6 +489,8 @@ class QgisApp : public QMainWindow
488489
void fileNew( bool thePromptToSaveFlag );
489490
//! Create a new empty vector layer
490491
void newVectorLayer();
492+
//! Create a new empty spatialite layer
493+
void newSpatialiteLayer();
491494
//! Print the current map view frame
492495
void newPrintComposer();
493496
void showComposerManager();
@@ -859,6 +862,7 @@ class QgisApp : public QMainWindow
859862
QAction *mActionAnnotation;
860863

861864
QAction *mActionNewVectorLayer;
865+
QAction *mActionNewSpatialiteLayer;
862866
QAction *mActionAddOgrLayer;
863867
QAction *mActionAddRasterLayer;
864868
QAction *mActionAddPgLayer;

0 commit comments

Comments
 (0)
Please sign in to comment.