mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-08 00:05:32 -04:00
1) All fTools functions should now add all layers to dropdowns (including non-visible layers), 2) All fTools functions should now be non-modal 3) Several fTools functions have been spead up slightly 4) Where possible, internal (cpp) functions have be used to replace older Python functions 5) Defining projections now also considers .qpj files Fixes bugs #2502 and #2506, and possibly others? git-svn-id: http://svn.osgeo.org/qgis/trunk@13037 c8812cc2-4d05-0410-92ff-de0c093fc19c
297 lines
11 KiB
Python
Executable File
297 lines
11 KiB
Python
Executable File
# -*- coding: utf-8 -*-
|
|
# Utility functions
|
|
# -------------------------------------------------
|
|
#
|
|
# combineVectorAttributes( QgsAttributeMap, QgsAttributeMap )
|
|
# convertFieldNameType( QgsField.name() )
|
|
# combineVectorFields( QgsVectorLayer, QgsVectorLayer )
|
|
# checkCRSCompatibility( QgsCoordinateReferenceSystem, QgsCoordinateReferenceSystem )
|
|
# writeVectorLayerToShape(QgsVectorLayer, QString *file path, QString *encoding style )
|
|
# getVectorTypeAsString( QgsVectorLayer )
|
|
# measurePerimeter( QgsGeometry )
|
|
# extractPoints( QgsGeometry )
|
|
# testForUniqueness( QList *QgsField, QList *QgsField )
|
|
# createUniqueFieldName( QgsField.name() )
|
|
# getLayerNames( QGis.vectorType() )
|
|
# getFieldNames( QgsVectorLayer )
|
|
# getVectorLayerByName( QgsVectorLayer.name() )
|
|
# getFieldList( QgsVectorLayer )
|
|
# createIndex( QgsVectorDataProvider )
|
|
# addShapeToCanvas( QString *file path )
|
|
# getUniqueValues( QgsVectorDataProvider, int *field id )
|
|
# saveDialog( QWidget *parent )
|
|
# getFieldType( QgsVectorLayer, QgsField.name() )
|
|
# getUniqueValuesCount( QgsVectorLayer, int fieldIndex, bool useSelection ):
|
|
#
|
|
# -------------------------------------------------
|
|
|
|
from PyQt4.QtCore import *
|
|
from PyQt4.QtGui import *
|
|
from qgis.core import *
|
|
from qgis.gui import *
|
|
|
|
# From two input attribute maps, create single attribute map
|
|
def combineVectorAttributes( atMapA, atMapB ):
|
|
attribA = atMapA.values()
|
|
lengthA = len(attribA)
|
|
attribB = atMapB.values()
|
|
lengthB = len(attribB)
|
|
attribA.extend( attribB )
|
|
return dict( zip( range( 0, lengthB + lengthA ), attribA ) )
|
|
|
|
# For use with memory provider/layer, converts full field type to simple string
|
|
def convertFieldNameType( inName ):
|
|
if inName == "Integer":
|
|
return "int"
|
|
elif inName == "Real":
|
|
return "double"
|
|
else:
|
|
return "string"
|
|
|
|
# From two input field maps, create single field map
|
|
def combineVectorFields( layerA, layerB ):
|
|
fieldsA = layerA.dataProvider().fields().values()
|
|
fieldsB = layerB.dataProvider().fields().values()
|
|
fieldsB = testForUniqueness( fieldsA, fieldsB )
|
|
seq = range( 0, len( fieldsA ) + len( fieldsB ) )
|
|
fieldsA.extend( fieldsB )
|
|
fieldsA = dict( zip ( seq, fieldsA ) )
|
|
return fieldsA
|
|
|
|
# Check if two input CRSs are identical
|
|
def checkCRSCompatibility( crsA, crsB ):
|
|
if crsA == crsB:
|
|
return True
|
|
else:
|
|
return False
|
|
|
|
# Convenience function to write vector layer to shapefile
|
|
def writeVectorLayerToShape( vlayer, outputPath, encoding ):
|
|
mCodec = QTextCodec.codecForName( QString(encoding).toLocal8Bit().data() )
|
|
if not mCodec:
|
|
return False
|
|
#Here we should check that the output path is valid
|
|
QgsVectorFileWriter.writeAsShapefile( vlayer, outputPath, encoding, vlayer.dataProvider().crs(), False )
|
|
return True
|
|
|
|
# For use with memory provider/layer, converts QGis vector type definition to simple string
|
|
def getVectorTypeAsString( vlayer ):
|
|
if vlayer.geometryType() == QGis.Polygon:
|
|
return "Polygon"
|
|
elif vlayer.geometryType() == QGis.Line:
|
|
return "LineString"
|
|
elif vlayer.geometryType() == QGis.Point:
|
|
return "Point"
|
|
else:
|
|
return False
|
|
|
|
# Compute area and perimeter of input polygon geometry
|
|
def getAreaAndPerimeter( geom ):
|
|
measure = QgsDistanceArea()
|
|
area = measure.measure( geom )
|
|
perim = measurePerimeter( geom, measure )
|
|
return ( area, perim )
|
|
|
|
# Compute perimeter of input polygon geometry
|
|
def measurePerimeter( geom ):
|
|
measure = QgsDistanceArea()
|
|
value = 0.00
|
|
polygon = geom.asPolygon()
|
|
for line in polygon:
|
|
value += measure.measureLine( line )
|
|
return value
|
|
|
|
# Generate list of QgsPoints from input geometry ( can be point, line, or polygon )
|
|
def extractPoints( geom ):
|
|
multi_geom = QgsGeometry()
|
|
temp_geom = []
|
|
if geom.type() == 0: # it's a point
|
|
if geom.isMultipart():
|
|
temp_geom = geom.asMultiPoint()
|
|
else:
|
|
temp_geom.append(geom.asPoint())
|
|
if geom.type() == 1: # it's a line
|
|
if geom.isMultipart():
|
|
multi_geom = geom.asMultiPolyline() #multi_geog is a multiline
|
|
for i in multi_geom: #i is a line
|
|
temp_geom.extend( i )
|
|
else:
|
|
temp_geom = geom.asPolyline()
|
|
elif geom.type() == 2: # it's a polygon
|
|
if geom.isMultipart():
|
|
multi_geom = geom.asMultiPolygon() #multi_geom is a multipolygon
|
|
for i in multi_geom: #i is a polygon
|
|
for j in i: #j is a line
|
|
temp_geom.extend( j )
|
|
else:
|
|
multi_geom = geom.asPolygon() #multi_geom is a polygon
|
|
for i in multi_geom: #i is a line
|
|
temp_geom.extend( i )
|
|
return temp_geom
|
|
|
|
# Check if two input field maps are unique, and resolve name issues if they aren't
|
|
def testForUniqueness( fieldList1, fieldList2 ):
|
|
changed = True
|
|
while changed:
|
|
changed = False
|
|
for i in fieldList1:
|
|
for j in fieldList2:
|
|
if j.name() == i.name():
|
|
j = createUniqueFieldName( j )
|
|
changed = True
|
|
return fieldList2
|
|
|
|
# Create a unique field name based on input field name
|
|
def createUniqueFieldName( field ):
|
|
check = field.name().right( 2 )
|
|
if check.startsWith("_"):
|
|
( val, test ) = check.right( 1 ).toInt()
|
|
if test:
|
|
if val < 2:
|
|
val = 2
|
|
else:
|
|
val = val + 1
|
|
field.setName( field.name().left( len( field.name() )-1 ) + unicode( val ) )
|
|
else:
|
|
field.setName( field.name() + "_2" )
|
|
else:
|
|
field.setName( field.name() + "_2" )
|
|
return field
|
|
|
|
# Return list of names of all layers in QgsMapLayerRegistry
|
|
def getLayerNames( vTypes ):
|
|
layermap = QgsMapLayerRegistry.instance().mapLayers()
|
|
layerlist = []
|
|
if vTypes == "all":
|
|
for name, layer in layermap.iteritems():
|
|
layerlist.append( unicode( layer.name() ) )
|
|
else:
|
|
for name, layer in layermap.iteritems():
|
|
if layer.type() == QgsMapLayer.VectorLayer:
|
|
if layer.geometryType() in vTypes:
|
|
layerlist.append( unicode( layer.name() ) )
|
|
elif layer.type() == QgsMapLayer.RasterLayer:
|
|
if "Raster" in vTypes:
|
|
layerlist.append( unicode( layer.name() ) )
|
|
return layerlist
|
|
|
|
# Return list of names of all fields from input QgsVectorLayer
|
|
def getFieldNames( vlayer ):
|
|
fieldmap = getFieldList( vlayer )
|
|
fieldlist = []
|
|
for name, field in fieldmap.iteritems():
|
|
if not field.name() in fieldlist:
|
|
fieldlist.append( unicode( field.name() ) )
|
|
return fieldlist
|
|
|
|
# Return QgsVectorLayer from a layer name ( as string )
|
|
def getVectorLayerByName( myName ):
|
|
layermap = QgsMapLayerRegistry.instance().mapLayers()
|
|
for name, layer in layermap.iteritems():
|
|
if layer.type() == QgsMapLayer.VectorLayer and layer.name() == myName:
|
|
if layer.isValid():
|
|
return layer
|
|
else:
|
|
return None
|
|
|
|
# Return QgsMapLayer from a layer name ( as string )
|
|
def getMapLayerByName( myName ):
|
|
layermap = QgsMapLayerRegistry.instance().mapLayers()
|
|
for name, layer in layermap.iteritems():
|
|
if layer.name() == myName:
|
|
if layer.isValid():
|
|
return layer
|
|
else:
|
|
return None
|
|
|
|
# Return the field list of a vector layer
|
|
def getFieldList( vlayer ):
|
|
vprovider = vlayer.dataProvider()
|
|
feat = QgsFeature()
|
|
allAttrs = vprovider.attributeIndexes()
|
|
vprovider.select( allAttrs )
|
|
myFields = vprovider.fields()
|
|
return myFields
|
|
|
|
# Convinience function to create a spatial index for input QgsVectorDataProvider
|
|
def createIndex( provider ):
|
|
feat = QgsFeature()
|
|
index = QgsSpatialIndex()
|
|
provider.rewind()
|
|
while provider.nextFeature( feat ):
|
|
index.insertFeature( feat )
|
|
return index
|
|
|
|
# Convinience function to add a vector layer to canvas based on input shapefile path ( as string )
|
|
def addShapeToCanvas( shapefile_path ):
|
|
file_info = QFileInfo( shapefile_path )
|
|
if file_info.exists():
|
|
layer_name = file_info.completeBaseName()
|
|
else:
|
|
return False
|
|
vlayer_new = QgsVectorLayer( shapefile_path, layer_name, "ogr" )
|
|
print layer_name
|
|
if vlayer_new.isValid():
|
|
QgsMapLayerRegistry.instance().addMapLayer( vlayer_new )
|
|
return True
|
|
else:
|
|
return False
|
|
|
|
# Return all unique values in field based on field index
|
|
def getUniqueValues( provider, index ):
|
|
allAttrs = provider.attributeIndexes()
|
|
provider.select( allAttrs )
|
|
f = QgsFeature()
|
|
values = []
|
|
check = []
|
|
while provider.nextFeature( f ):
|
|
if not f.attributeMap()[ index ].toString() in check:
|
|
values.append( f.attributeMap()[ index ] )
|
|
check.append( f.attributeMap()[ index ].toString() )
|
|
return values
|
|
|
|
# Generate a save file dialog with a dropdown box for choosing encoding style
|
|
def saveDialog( parent ):
|
|
settings = QSettings()
|
|
dirName = settings.value( "/UI/lastShapefileDir" ).toString()
|
|
filtering = QString( "Shapefiles (*.shp)" )
|
|
encode = settings.value( "/UI/encoding" ).toString()
|
|
fileDialog = QgsEncodingFileDialog( parent, "Save output shapefile", dirName, filtering, encode )
|
|
fileDialog.setDefaultSuffix( QString( "shp" ) )
|
|
fileDialog.setFileMode( QFileDialog.AnyFile )
|
|
fileDialog.setAcceptMode( QFileDialog.AcceptSave )
|
|
fileDialog.setConfirmOverwrite( True )
|
|
if not fileDialog.exec_() == QDialog.Accepted:
|
|
return None, None
|
|
files = fileDialog.selectedFiles()
|
|
settings.setValue("/UI/lastShapefileDir", QVariant( QFileInfo( unicode( files.first() ) ).absolutePath() ) )
|
|
return ( unicode( files.first() ), unicode( fileDialog.encoding() ) )
|
|
|
|
# Return field type from it's name
|
|
def getFieldType(vlayer, fieldName):
|
|
fields = vlayer.dataProvider().fields()
|
|
for name, field in fields.iteritems():
|
|
if field.name() == fieldName:
|
|
return field.typeName()
|
|
|
|
# return the number of unique values in field
|
|
def getUniqueValuesCount( vlayer, fieldIndex, useSelection ):
|
|
vprovider = vlayer.dataProvider()
|
|
allAttrs = vprovider.attributeIndexes()
|
|
vprovider.select( allAttrs )
|
|
count = 0
|
|
values = []
|
|
if useSelection:
|
|
selection = vlayer.selectedFeatures()
|
|
for f in selection:
|
|
if f.attributeMap()[ fieldIndex ].toString() not in values:
|
|
values.append( f.attributeMap()[ fieldIndex ].toString() )
|
|
count += 1
|
|
else:
|
|
feat = QgsFeature()
|
|
while vprovider.nextFeature( feat ):
|
|
if feat.attributeMap()[ fieldIndex ].toString() not in values:
|
|
values.append( feat.attributeMap()[ fieldIndex ].toString() )
|
|
count += 1
|
|
return count
|