Skip to content

Commit

Permalink
[processing] restore import into spatialite & spatialite execute sql
Browse files Browse the repository at this point in the history
  • Loading branch information
nirvn authored Jun 26, 2017
1 parent bfb41a1 commit fa8b216
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 65 deletions.
110 changes: 63 additions & 47 deletions python/plugins/processing/algs/qgis/ImportIntoSpatialite.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,16 @@
QgsFeatureSink,
QgsVectorLayerExporter,
QgsApplication,
QgsProcessingUtils)
QgsProcessingUtils,
QgsProcessingParameterFeatureSource,
QgsProcessingParameterVectorLayer,
QgsProcessingParameterField,
QgsProcessingParameterString,
QgsProcessingParameterBoolean,
QgsWkbTypes)

from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
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 ParameterTableField
from processing.tools import spatialite


Expand All @@ -59,17 +61,17 @@ def group(self):

def __init__(self):
super().__init__()
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))
self.addParameter(QgsProcessingParameterFeatureSource(self.INPUT, self.tr('Layer to import')))
self.addParameter(QgsProcessingParameterVectorLayer(self.DATABASE, self.tr('File database'), False, False))
self.addParameter(QgsProcessingParameterString(self.TABLENAME, self.tr('Table to import to (leave blank to use layer name)'), optional=True))
self.addParameter(QgsProcessingParameterField(self.PRIMARY_KEY, self.tr('Primary key field'), self.INPUT, optional=True))
self.addParameter(QgsProcessingParameterString(self.GEOMETRY_COLUMN, self.tr('Geometry column'), 'geom'))
self.addParameter(QgsProcessingParameterString(self.ENCODING, self.tr('Encoding'), 'UTF-8', optional=True))
self.addParameter(QgsProcessingParameterBoolean(self.OVERWRITE, self.tr('Overwrite'), True))
self.addParameter(QgsProcessingParameterBoolean(self.CREATEINDEX, self.tr('Create spatial index'), True))
self.addParameter(QgsProcessingParameterBoolean(self.LOWERCASE_NAMES, self.tr('Convert field names to lowercase'), True))
self.addParameter(QgsProcessingParameterBoolean(self.DROP_STRING_LENGTH, self.tr('Drop length constraints on character fields'), False))
self.addParameter(QgsProcessingParameterBoolean(self.FORCE_SINGLEPART, self.tr('Create single-part geometries instead of multi-part'), False))

def name(self):
return 'importintospatialite'
Expand All @@ -78,36 +80,37 @@ def displayName(self):
return self.tr('Import into Spatialite')

def processAlgorithm(self, parameters, context, feedback):
database = self.getParameterValue(self.DATABASE)
uri = QgsDataSourceUri(database)
database = self.parameterAsVectorLayer(parameters, self.DATABASE, context)
databaseuri = database.dataProvider().dataSourceUri()
uri = QgsDataSourceUri(databaseuri)
if uri.database() is '':
if '|layerid' in database:
database = database[:database.find('|layerid')]
uri = QgsDataSourceUri('dbname=\'%s\'' % (database))
if '|layerid' in databaseuri:
databaseuri = databaseuri[:databaseuri.find('|layerid')]
uri = QgsDataSourceUri('dbname=\'%s\'' % (databaseuri))
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)
overwrite = self.parameterAsBool(parameters, self.OVERWRITE, context)
createIndex = self.parameterAsBool(parameters, self.CREATEINDEX, context)
convertLowerCase = self.parameterAsBool(parameters, self.LOWERCASE_NAMES, context)
dropStringLength = self.parameterAsBool(parameters, self.DROP_STRING_LENGTH, context)
forceSinglePart = self.parameterAsBool(parameters, self.FORCE_SINGLEPART, context)
primaryKeyField = self.parameterAsString(parameters, self.PRIMARY_KEY, context) or 'id'
encoding = self.parameterAsString(parameters, self.ENCODING, context)

layerUri = self.getParameterValue(self.INPUT)
layer = QgsProcessingUtils.mapLayerFromString(layerUri, context)
source = self.parameterAsSource(parameters, self.INPUT, context)

table = self.getParameterValue(self.TABLENAME)
table = self.parameterAsString(parameters, self.TABLENAME, context)
if table:
table.strip()
if not table or table == '':
table = layer.name()
table = source.sourceName()
table = table.replace('.', '_')
table = table.replace(' ', '').lower()
providerName = 'spatialite'

geomColumn = self.getParameterValue(self.GEOMETRY_COLUMN)
geomColumn = self.parameterAsString(parameters, self.GEOMETRY_COLUMN, context)
if not geomColumn:
geomColumn = 'the_geom'
geomColumn = 'geom'

options = {}
if overwrite:
Expand All @@ -121,26 +124,39 @@ def processAlgorithm(self, parameters, context, feedback):
options['forceSinglePartGeometryType'] = True

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

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

if encoding:
layer.setProviderEncoding(encoding)

(ret, errMsg) = QgsVectorLayerExporter.exportLayer(
layer,
uri.uri(),
providerName,
self.crs,
False,
options,
)
if ret != 0:
options['fileEncoding'] = encoding

exporter = QgsVectorLayerExporter(uri.uri(), providerName, source.fields(),
source.wkbType(), source.sourceCrs(), overwrite, options)

if exporter.errorCode() != QgsVectorLayerExporter.NoError:
raise GeoAlgorithmExecutionException(
self.tr('Error importing to Spatialite\n{0}').format(exporter.errorMessage()))

features = source.getFeatures()
total = 100.0 / source.featureCount() if source.featureCount() else 0
for current, f in enumerate(features):
if feedback.isCanceled():
break

if not exporter.addFeature(f, QgsFeatureSink.FastInsert):
feedback.reportError(exporter.errorMessage())

feedback.setProgress(int(current * total))

exporter.flushBuffer()
if exporter.errorCode() != QgsVectorLayerExporter.NoError:
raise GeoAlgorithmExecutionException(
self.tr('Error importing to Spatialite\n{0}').format(errMsg))
self.tr('Error importing to Spatialite\n{0}').format(exporter.errorMessage()))

if geomColumn and createIndex:
db.create_spatial_index(table, geomColumn)

return {}
7 changes: 4 additions & 3 deletions python/plugins/processing/algs/qgis/QGISAlgorithmProvider.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,15 @@
from .FixGeometry import FixGeometry
from .GridPolygon import GridPolygon
from .ImportIntoPostGIS import ImportIntoPostGIS
from .ImportIntoSpatialite import ImportIntoSpatialite
from .Merge import Merge
from .PostGISExecuteSQL import PostGISExecuteSQL
from .RandomExtract import RandomExtract
from .RandomExtractWithinSubsets import RandomExtractWithinSubsets
from .RegularPoints import RegularPoints
from .SimplifyGeometries import SimplifyGeometries
from .Smooth import Smooth
from .SpatialiteExecuteSQL import SpatialiteExecuteSQL
from .SymmetricalDifference import SymmetricalDifference
from .VectorSplit import VectorSplit

Expand Down Expand Up @@ -124,8 +126,6 @@
# from .RandomPointsPolygonsVariable import RandomPointsPolygonsVariable
# from .RandomPointsAlongLines import RandomPointsAlongLines
# from .PointsToPaths import PointsToPaths
# from .SpatialiteExecuteSQL import SpatialiteExecuteSQL
# from .ImportIntoSpatialite import ImportIntoSpatialite
# from .SetVectorStyle import SetVectorStyle
# from .SetRasterStyle import SetRasterStyle
# from .SelectByExpression import SelectByExpression
Expand Down Expand Up @@ -216,7 +216,6 @@ def getAlgs(self):
# RandomPointsLayer(), RandomPointsPolygonsFixed(),
# RandomPointsPolygonsVariable(),
# RandomPointsAlongLines(), PointsToPaths(),
# SpatialiteExecuteSQL(), ImportIntoSpatialite(),
# SetVectorStyle(), SetRasterStyle(),
# SelectByExpression(), HypsometricCurves(),
# SplitWithLines(), CreateConstantRaster(),
Expand Down Expand Up @@ -260,13 +259,15 @@ def getAlgs(self):
FixGeometry(),
GridPolygon(),
ImportIntoPostGIS(),
ImportIntoSpatialite(),
Merge(),
PostGISExecuteSQL(),
RandomExtract(),
RandomExtractWithinSubsets(),
RegularPoints(),
SimplifyGeometries(),
Smooth(),
SpatialiteExecuteSQL(),
SymmetricalDifference(),
VectorSplit()
]
Expand Down
33 changes: 18 additions & 15 deletions python/plugins/processing/algs/qgis/SpatialiteExecuteSQL.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,15 @@

__revision__ = '$Format:%H$'

from qgis.core import (QgsDataSourceUri,
QgsApplication,
QgsProcessingParameterVectorLayer,
QgsProcessingParameterString)

from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
from processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
from processing.core.parameters import ParameterVector
from processing.core.parameters import ParameterString
from processing.tools import spatialite

from qgis.core import (QgsApplication,
QgsDataSourceUri)


class SpatialiteExecuteSQL(QgisAlgorithm):

Expand All @@ -46,8 +46,8 @@ def group(self):

def __init__(self):
super().__init__()
self.addParameter(ParameterVector(self.DATABASE, self.tr('File Database'), False, False))
self.addParameter(ParameterString(self.SQL, self.tr('SQL query'), '', True))
self.addParameter(QgsProcessingParameterVectorLayer(self.DATABASE, self.tr('File Database'), False, False))
self.addParameter(QgsProcessingParameterString(self.SQL, self.tr('SQL query'), '', True))

def name(self):
return 'spatialiteexecutesql'
Expand All @@ -56,16 +56,19 @@ def displayName(self):
return self.tr('Spatialite execute SQL')

def processAlgorithm(self, parameters, context, feedback):
database = self.getParameterValue(self.DATABASE)
uri = QgsDataSourceUri(database)
database = self.parameterAsVectorLayer(parameters, self.DATABASE, context)
databaseuri = database.dataProvider().dataSourceUri()
uri = QgsDataSourceUri(databaseuri)
if uri.database() is '':
if '|layerid' in database:
database = database[:database.find('|layerid')]
uri = QgsDataSourceUri('dbname=\'%s\'' % (database))
self.db = spatialite.GeoDB(uri)
sql = self.getParameterValue(self.SQL).replace('\n', ' ')
if '|layerid' in databaseuri:
databaseuri = databaseuri[:databaseuri.find('|layerid')]
uri = QgsDataSourceUri('dbname=\'%s\'' % (databaseuri))
db = spatialite.GeoDB(uri)
sql = self.parameterAsString(parameters, self.SQL, context).replace('\n', ' ')
try:
self.db._exec_sql_and_commit(str(sql))
db._exec_sql_and_commit(str(sql))
except spatialite.DbError as e:
raise GeoAlgorithmExecutionException(
self.tr('Error executing SQL:\n{0}').format(str(e)))

return {}

0 comments on commit fa8b216

Please sign in to comment.