Skip to content

Commit

Permalink
Merge pull request #3656 from nirvn/processing_import_to_spatialite
Browse files Browse the repository at this point in the history
[processing] add "Import into Spatialite" algorithm
  • Loading branch information
nyalldawson authored Oct 30, 2016
2 parents 29ce141 + 121f48d commit a117df2
Show file tree
Hide file tree
Showing 5 changed files with 157 additions and 5 deletions.
3 changes: 3 additions & 0 deletions python/plugins/processing/algs/help/qgis.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,9 @@ qgis:hublines:
qgis:hypsometriccurves: >
This algorithm computes hypsometric curves for an input Digital Elevation Model. Curves are produced as table files in an output folder specified by the user.

qgis:importintospatialite: >
This algorithms imports a vector layer into a Spatialite database, creating a new table.

qgis:importintopostgis: >
This algorithms imports a vector layer into a PostGIS database, creating a new table.

Expand Down
8 changes: 5 additions & 3 deletions python/plugins/processing/algs/qgis/ImportIntoPostGIS.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ def defineCharacteristics(self):
self.addParameter(ParameterString(self.SCHEMA,
self.tr('Schema (schema name)'), 'public'))
self.addParameter(ParameterString(self.TABLENAME,
self.tr('Table to import to (leave blank to use layer name)')))
self.tr('Table to import to (leave blank to use layer name)'), optional=True))
self.addParameter(ParameterTableField(self.PRIMARY_KEY,
self.tr('Primary key field'), self.INPUT, optional=True))
self.addParameter(ParameterString(self.GEOMETRY_COLUMN,
Expand Down Expand Up @@ -100,8 +100,10 @@ def processAlgorithm(self, progress):
layerUri = self.getParameterValue(self.INPUT)
layer = dataobjects.getObjectFromUri(layerUri)

table = self.getParameterValue(self.TABLENAME).strip()
if table == '':
table = self.getParameterValue(self.TABLENAME)
if table:
table.strip()
if not table or table == '':
table = layer.name()
table = "_".join(table.split(".")[:-1])
table = table.replace(' ', '').lower()[0:62]
Expand Down
137 changes: 137 additions & 0 deletions python/plugins/processing/algs/qgis/ImportIntoSpatialite.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
# -*- coding: utf-8 -*-

"""
***************************************************************************
ImportIntoSpatialite.py
---------------------
Date : October 2016
Copyright : (C) 2016 by Mathieu Pellerin
Email : nirvn dot asia at gmail dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************
"""

__author__ = 'Mathieu Pellerin'
__date__ = 'October 2016'
__copyright__ = '(C) 2012, Mathieu Pellerin'

# This will get replaced with a git SHA1 when you do a git archive

__revision__ = '$Format:%H$'

from qgis.PyQt.QtCore import QSettings
from qgis.core import QgsDataSourceUri, QgsVectorLayerImport

from processing.core.GeoAlgorithm import GeoAlgorithm
from processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
from processing.core.parameters import ParameterBoolean
from processing.core.parameters import ParameterVector
from processing.core.parameters import ParameterString
from processing.core.parameters import ParameterSelection
from processing.core.parameters import ParameterTableField
from processing.tools import dataobjects, spatialite


class ImportIntoSpatialite(GeoAlgorithm):

DATABASE = 'DATABASE'
TABLENAME = 'TABLENAME'
INPUT = 'INPUT'
OVERWRITE = 'OVERWRITE'
CREATEINDEX = 'CREATEINDEX'
GEOMETRY_COLUMN = 'GEOMETRY_COLUMN'
LOWERCASE_NAMES = 'LOWERCASE_NAMES'
DROP_STRING_LENGTH = 'DROP_STRING_LENGTH'
FORCE_SINGLEPART = 'FORCE_SINGLEPART'
PRIMARY_KEY = 'PRIMARY_KEY'
ENCODING = 'ENCODING'

def defineCharacteristics(self):
self.name, self.i18n_name = self.trAlgorithm('Import into Spatialite')
self.group, self.i18n_group = self.trAlgorithm('Database')
self.addParameter(ParameterVector(self.INPUT, self.tr('Layer to import')))
self.addParameter(ParameterVector(self.DATABASE, self.tr('File database'), False, False))
self.addParameter(ParameterString(self.TABLENAME, self.tr('Table to import to (leave blank to use layer name)'), optional=True))
self.addParameter(ParameterTableField(self.PRIMARY_KEY, self.tr('Primary key field'), self.INPUT, optional=True))
self.addParameter(ParameterString(self.GEOMETRY_COLUMN, self.tr('Geometry column'), 'geom'))
self.addParameter(ParameterString(self.ENCODING, self.tr('Encoding'), 'UTF-8', optional=True))
self.addParameter(ParameterBoolean(self.OVERWRITE, self.tr('Overwrite'), True))
self.addParameter(ParameterBoolean(self.CREATEINDEX, self.tr('Create spatial index'), True))
self.addParameter(ParameterBoolean(self.LOWERCASE_NAMES, self.tr('Convert field names to lowercase'), True))
self.addParameter(ParameterBoolean(self.DROP_STRING_LENGTH, self.tr('Drop length constraints on character fields'), False))
self.addParameter(ParameterBoolean(self.FORCE_SINGLEPART, self.tr('Create single-part geometries instead of multi-part'), False))

def processAlgorithm(self, progress):
database = self.getParameterValue(self.DATABASE)
uri = QgsDataSourceUri(database)
if uri.database() is '':
if '|layerid' in database:
database = database[:database.find('|layerid')]
uri = QgsDataSourceUri('dbname=\'%s\'' % (database))
db = spatialite.GeoDB(uri)

overwrite = self.getParameterValue(self.OVERWRITE)
createIndex = self.getParameterValue(self.CREATEINDEX)
convertLowerCase = self.getParameterValue(self.LOWERCASE_NAMES)
dropStringLength = self.getParameterValue(self.DROP_STRING_LENGTH)
forceSinglePart = self.getParameterValue(self.FORCE_SINGLEPART)
primaryKeyField = self.getParameterValue(self.PRIMARY_KEY) or 'id'
encoding = self.getParameterValue(self.ENCODING)

layerUri = self.getParameterValue(self.INPUT)
layer = dataobjects.getObjectFromUri(layerUri)

table = self.getParameterValue(self.TABLENAME)
if table:
table.strip()
if not table or table == '':
table = layer.name()
table = table.replace(' ', '').lower()
providerName = 'spatialite'

geomColumn = self.getParameterValue(self.GEOMETRY_COLUMN)
if not geomColumn:
geomColumn = 'the_geom'

options = {}
if overwrite:
options['overwrite'] = True
if convertLowerCase:
options['lowercaseFieldNames'] = True
geomColumn = geomColumn.lower()
if dropStringLength:
options['dropStringConstraints'] = True
if forceSinglePart:
options['forceSinglePartGeometryType'] = True

# Clear geometry column for non-geometry tables
if not layer.hasGeometryType():
geomColumn = None

uri = db.uri
uri.setDataSource('', table, geomColumn, '', primaryKeyField)

if encoding:
layer.setProviderEncoding(encoding)

(ret, errMsg) = QgsVectorLayerImport.importLayer(
layer,
uri.uri(),
providerName,
self.crs,
False,
False,
options,
)
if ret != 0:
raise GeoAlgorithmExecutionException(
self.tr('Error importing to Spatialite\n%s' % errMsg))

if geomColumn and createIndex:
db.create_spatial_index(table, geomColumn)
3 changes: 2 additions & 1 deletion python/plugins/processing/algs/qgis/QGISAlgorithmProvider.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@
from .PointsToPaths import PointsToPaths
from .SpatialiteExecuteSQL import SpatialiteExecuteSQL
from .PostGISExecuteSQL import PostGISExecuteSQL
from .ImportIntoSpatialite import ImportIntoSpatialite
from .ImportIntoPostGIS import ImportIntoPostGIS
from .SetVectorStyle import SetVectorStyle
from .SetRasterStyle import SetRasterStyle
Expand Down Expand Up @@ -217,7 +218,7 @@ def __init__(self):
RandomPointsLayer(), RandomPointsPolygonsFixed(),
RandomPointsPolygonsVariable(),
RandomPointsAlongLines(), PointsToPaths(),
SpatialiteExecuteSQL(),
SpatialiteExecuteSQL(), ImportIntoSpatialite(),
PostGISExecuteSQL(), ImportIntoPostGIS(),
SetVectorStyle(), SetRasterStyle(),
SelectByExpression(), HypsometricCurves(),
Expand Down
11 changes: 10 additions & 1 deletion python/plugins/processing/tools/spatialite.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
__revision__ = '$Format:%H$'

from qgis.utils import spatialite_connect

import sqlite3 as sqlite


Expand Down Expand Up @@ -124,3 +123,13 @@ def _exec_sql_and_commit(self, sql):
except DbError:
self.con.rollback()
raise

def create_spatial_index(self, table, geom_column='the_geom'):
sql = u"SELECT CreateSpatialIndex(%s, %s)" % (self._quote(table), self._quote(geom_column))
self._exec_sql_and_commit(sql)

def _quote(self, identifier):
"""Quote identifier."""

# quote identifier, and double the double-quotes
return u"'%s'" % identifier.replace("'", "''")

0 comments on commit a117df2

Please sign in to comment.