Skip to content
Permalink
Browse files

Merge pull request #3656 from nirvn/processing_import_to_spatialite

[processing] add "Import into Spatialite" algorithm
  • Loading branch information
nyalldawson committed Oct 30, 2016
2 parents 29ce141 + 121f48d commit a117df22050145d9d0a0a015ee5db56abc9aa701
@@ -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.

@@ -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,
@@ -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]
@@ -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)
@@ -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
@@ -217,7 +218,7 @@ def __init__(self):
RandomPointsLayer(), RandomPointsPolygonsFixed(),
RandomPointsPolygonsVariable(),
RandomPointsAlongLines(), PointsToPaths(),
SpatialiteExecuteSQL(),
SpatialiteExecuteSQL(), ImportIntoSpatialite(),
PostGISExecuteSQL(), ImportIntoPostGIS(),
SetVectorStyle(), SetRasterStyle(),
SelectByExpression(), HypsometricCurves(),
@@ -28,7 +28,6 @@
__revision__ = '$Format:%H$'

from qgis.utils import spatialite_connect

import sqlite3 as sqlite


@@ -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.
You can’t perform that action at this time.