[processing] add import into spatialite algorithm

This commit is contained in:
nirvn 2016-10-22 11:28:03 +07:00
parent 7a05a7a8c4
commit 121f48d654
5 changed files with 157 additions and 5 deletions

View File

@ -198,6 +198,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.

View File

@ -65,7 +65,7 @@ class ImportIntoPostGIS(GeoAlgorithm):
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 @@ class ImportIntoPostGIS(GeoAlgorithm):
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]

View File

@ -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)

View File

@ -133,6 +133,7 @@ from .RandomPointsAlongLines import RandomPointsAlongLines
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
@ -214,7 +215,7 @@ class QGISAlgorithmProvider(AlgorithmProvider):
RandomPointsLayer(), RandomPointsPolygonsFixed(),
RandomPointsPolygonsVariable(),
RandomPointsAlongLines(), PointsToPaths(),
SpatialiteExecuteSQL(),
SpatialiteExecuteSQL(), ImportIntoSpatialite(),
PostGISExecuteSQL(), ImportIntoPostGIS(),
SetVectorStyle(), SetRasterStyle(),
SelectByExpression(), HypsometricCurves(),

View File

@ -28,7 +28,6 @@ __copyright__ = '(C) 2015, René-Luc Dhont'
__revision__ = '$Format:%H$'
from qgis.utils import spatialite_connect
import sqlite3 as sqlite
@ -124,3 +123,13 @@ class GeoDB(object):
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("'", "''")