2010-03-08 23:15:11 +00:00
# -*- coding: utf-8 -*-
2011-03-07 23:29:15 +00:00
#-----------------------------------------------------------
#
# fTools
# Copyright (C) 2008-2011 Carson Farmer
# EMAIL: carson.farmer (at) gmail.com
# WEB : http://www.ftools.ca/fTools.html
#
# A collection of data management and analysis tools for vector data
#
#-----------------------------------------------------------
#
# licensed under the terms of GNU GPL 2
#
# 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.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
#---------------------------------------------------------------------
2009-02-01 15:44:02 +00:00
from PyQt4 . QtCore import *
from PyQt4 . QtGui import *
import ftools_utils
from qgis . core import *
from math import *
2009-08-16 22:40:48 +00:00
from ui_frmMeanCoords import Ui_Dialog
2009-02-01 15:44:02 +00:00
class Dialog ( QDialog , Ui_Dialog ) :
2010-03-08 23:15:11 +00:00
def __init__ ( self , iface , function ) :
2012-01-26 00:54:56 +01:00
QDialog . __init__ ( self , iface . mainWindow ( ) )
2010-03-08 23:15:11 +00:00
self . iface = iface
self . function = function
self . setupUi ( self )
self . updateUi ( )
QObject . connect ( self . toolOut , SIGNAL ( " clicked() " ) , self . outFile )
QObject . connect ( self . inShape , SIGNAL ( " currentIndexChanged(QString) " ) , self . update )
2010-05-13 22:55:59 +00:00
self . buttonOk = self . buttonBox_2 . button ( QDialogButtonBox . Ok )
2010-03-08 23:15:11 +00:00
self . progressBar . setValue ( 0 )
2011-11-12 13:05:27 +02:00
self . populateLayers ( )
def populateLayers ( self ) :
2010-03-10 01:11:11 +00:00
layers = ftools_utils . getLayerNames ( [ QGis . Point , QGis . Line , QGis . Polygon ] )
2012-05-28 19:17:21 +03:00
self . inShape . blockSignals ( True )
2011-11-12 13:05:27 +02:00
self . inShape . clear ( )
2012-05-28 19:17:21 +03:00
self . inShape . blockSignals ( False )
2010-03-10 01:11:11 +00:00
self . inShape . addItems ( layers )
2009-01-20 22:54:27 +00:00
2010-03-08 23:15:11 +00:00
def updateUi ( self ) :
if self . function == 1 :
self . setWindowTitle ( self . tr ( " Mean coordinates " ) )
self . sizeValue . setVisible ( False )
self . label_size . setVisible ( False )
elif self . function == 2 :
self . setWindowTitle ( self . tr ( " Standard distance " ) )
self . resize ( 381 , 100 )
2009-02-01 15:44:02 +00:00
2010-03-08 23:15:11 +00:00
def update ( self , inputLayer ) :
self . weightField . clear ( )
self . uniqueField . clear ( )
self . weightField . addItem ( self . tr ( " (Optional) Weight field " ) )
self . uniqueField . addItem ( self . tr ( " (Optional) Unique ID field " ) )
self . changedLayer = ftools_utils . getVectorLayerByName ( inputLayer )
changedField = ftools_utils . getFieldList ( self . changedLayer )
for i in changedField :
if changedField [ i ] . type ( ) == QVariant . Int or changedField [ i ] . type ( ) == QVariant . Double :
self . weightField . addItem ( unicode ( changedField [ i ] . name ( ) ) )
self . uniqueField . addItem ( unicode ( changedField [ i ] . name ( ) ) )
2009-02-01 15:44:02 +00:00
2010-03-08 23:15:11 +00:00
def accept ( self ) :
2010-05-13 22:55:59 +00:00
self . buttonOk . setEnabled ( False )
2010-03-08 23:15:11 +00:00
if self . inShape . currentText ( ) == " " :
QMessageBox . information ( self , self . tr ( " Coordinate statistics " ) , self . tr ( " No input vector layer specified " ) )
elif self . outShape . text ( ) == " " :
QMessageBox . information ( self , self . tr ( " Coordinate statistics " ) , self . tr ( " Please specify output shapefile " ) )
else :
inName = self . inShape . currentText ( )
outPath = self . outShape . text ( )
2009-02-01 15:44:02 +00:00
2010-03-08 23:15:11 +00:00
if outPath . contains ( " \\ " ) :
outName = outPath . right ( ( outPath . length ( ) - outPath . lastIndexOf ( " \\ " ) ) - 1 )
else :
outName = outPath . right ( ( outPath . length ( ) - outPath . lastIndexOf ( " / " ) ) - 1 )
if outName . endsWith ( " .shp " ) :
outName = outName . left ( outName . length ( ) - 4 )
self . compute ( inName , outPath , self . weightField . currentText ( ) , self . sizeValue . value ( ) , self . uniqueField . currentText ( ) )
self . progressBar . setValue ( 100 )
self . outShape . clear ( )
addToTOC = QMessageBox . question ( self , self . tr ( " Coordinate statistics " ) , self . tr ( " Created output point shapefile: \n % 1 \n \n Would you like to add the new layer to the TOC? " ) . arg ( outPath ) , QMessageBox . Yes , QMessageBox . No , QMessageBox . NoButton )
if addToTOC == QMessageBox . Yes :
2011-02-28 22:40:23 +00:00
vlayer = QgsVectorLayer ( outPath , unicode ( outName ) , " ogr " )
2012-12-24 11:48:08 +02:00
QgsMapLayerRegistry . instance ( ) . addMapLayers ( [ vlayer ] )
2011-11-12 13:05:27 +02:00
self . populateLayers ( )
2010-05-13 22:55:59 +00:00
self . progressBar . setValue ( 0 )
self . buttonOk . setEnabled ( True )
2009-02-01 15:44:02 +00:00
2010-03-08 23:15:11 +00:00
def outFile ( self ) :
self . outShape . clear ( )
( self . shapefileName , self . encoding ) = ftools_utils . saveDialog ( self )
if self . shapefileName is None or self . encoding is None :
return
self . outShape . setText ( QString ( self . shapefileName ) )
2009-02-01 15:44:02 +00:00
2010-03-08 23:15:11 +00:00
def compute ( self , inName , outName , weightField = " " , times = 1 , uniqueField = " " ) :
vlayer = ftools_utils . getVectorLayerByName ( inName )
provider = vlayer . dataProvider ( )
weightIndex = provider . fieldNameIndex ( weightField )
uniqueIndex = provider . fieldNameIndex ( uniqueField )
feat = QgsFeature ( )
allAttrs = provider . attributeIndexes ( )
provider . select ( allAttrs )
sRs = provider . crs ( )
check = QFile ( self . shapefileName )
if check . exists ( ) :
if not QgsVectorFileWriter . deleteShapeFile ( self . shapefileName ) :
return
if uniqueIndex < > - 1 :
uniqueValues = ftools_utils . getUniqueValues ( provider , int ( uniqueIndex ) )
single = False
else :
uniqueValues = [ QVariant ( 1 ) ]
single = True
if self . function == 2 :
fieldList = { 0 : QgsField ( " STD_DIST " , QVariant . Double ) , 1 : QgsField ( " UID " , QVariant . String ) }
writer = QgsVectorFileWriter ( self . shapefileName , self . encoding , fieldList , QGis . WKBPolygon , sRs )
else :
fieldList = { 0 : QgsField ( " MEAN_X " , QVariant . Double ) , 1 : QgsField ( " MEAN_Y " , QVariant . Double ) , 2 : QgsField ( " UID " , QVariant . String ) }
writer = QgsVectorFileWriter ( self . shapefileName , self . encoding , fieldList , QGis . WKBPoint , sRs )
outfeat = QgsFeature ( )
points = [ ]
weights = [ ]
nFeat = provider . featureCount ( ) * len ( uniqueValues )
nElement = 0
self . progressBar . setValue ( 0 )
self . progressBar . setRange ( 0 , nFeat )
for j in uniqueValues :
provider . rewind ( )
provider . select ( allAttrs )
cx = 0.00
cy = 0.00
points = [ ]
weights = [ ]
while provider . nextFeature ( feat ) :
nElement + = 1
self . progressBar . setValue ( nElement )
if single :
check = j . toString ( ) . trimmed ( )
else :
check = feat . attributeMap ( ) [ uniqueIndex ] . toString ( ) . trimmed ( )
if check == j . toString ( ) . trimmed ( ) :
cx = 0.00
cy = 0.00
if weightIndex == - 1 :
weight = 1.00
else :
weight = float ( feat . attributeMap ( ) [ weightIndex ] . toDouble ( ) [ 0 ] )
geom = QgsGeometry ( feat . geometry ( ) )
2010-05-13 22:55:59 +00:00
geom = ftools_utils . extractPoints ( geom )
2010-03-08 23:15:11 +00:00
for i in geom :
cx + = i . x ( )
cy + = i . y ( )
points . append ( QgsPoint ( ( cx / len ( geom ) ) , ( cy / len ( geom ) ) ) )
weights . append ( weight )
sumWeight = sum ( weights )
cx = 0.00
cy = 0.00
item = 0
for item , i in enumerate ( points ) :
cx + = i . x ( ) * weights [ item ]
cy + = i . y ( ) * weights [ item ]
cx = cx / sumWeight
cy = cy / sumWeight
meanPoint = QgsPoint ( cx , cy )
if self . function == 2 :
values = [ ]
md = 0.00
sd = 0.00
dist = QgsDistanceArea ( )
item = 0
for i in points :
tempDist = dist . measureLine ( i , meanPoint )
values . append ( tempDist )
item + = 1
md + = tempDist
md = md / item
for i in values :
sd + = ( i - md ) * ( i - md )
sd = sqrt ( sd / item )
outfeat . setGeometry ( QgsGeometry . fromPoint ( meanPoint ) . buffer ( sd * times , 10 ) )
outfeat . addAttribute ( 0 , QVariant ( sd ) )
outfeat . addAttribute ( 1 , QVariant ( j ) )
else :
outfeat . setGeometry ( QgsGeometry . fromPoint ( meanPoint ) )
outfeat . addAttribute ( 0 , QVariant ( cx ) )
outfeat . addAttribute ( 1 , QVariant ( cy ) )
outfeat . addAttribute ( 2 , QVariant ( j ) )
writer . addFeature ( outfeat )
if single :
break
del writer