Skip to content

Commit

Permalink
[FEATURE] Extract projection tool for GdalTools
Browse files Browse the repository at this point in the history
  • Loading branch information
alexbruy committed Aug 9, 2011
1 parent b35e075 commit 1f1dd7d
Show file tree
Hide file tree
Showing 5 changed files with 321 additions and 1 deletion.
11 changes: 10 additions & 1 deletion python/plugins/GdalTools/GdalTools.py
Expand Up @@ -115,7 +115,11 @@ def initGui( self ):
self.projection.setStatusTip( QCoreApplication.translate( "GdalTools", "Add projection info to the raster" ) )
QObject.connect( self.projection, SIGNAL( "triggered()" ), self.doProjection )

self.projectionsMenu.addActions( [ self.warp, self.projection ] )
self.extractProj = QAction( QIcon( ":icons/extract-projection.png" ), QCoreApplication.translate( "GdalTools", "Extract projection" ), self.iface.mainWindow() )
self.extractProj.setStatusTip( QCoreApplication.translate( "GdalTools", "Extract projection information from raster(s)" ) )
QObject.connect( self.extractProj, SIGNAL( "triggered()" ), self.doExtractProj )

self.projectionsMenu.addActions( [ self.warp, self.projection, self.extractProj ] )

# conversion menu (Rasterize (Vector to raster), Polygonize (Raster to vector), Translate, RGB to PCT, PCT to RGB)
self.conversionMenu = QMenu( QCoreApplication.translate( "GdalTools", "Conversion" ) )
Expand Down Expand Up @@ -341,6 +345,11 @@ def doTileIndex( self ):
d = TileIndex( self.iface )
self.runToolDialog( d )

def doExtractProj( self ):
from tools.doExtractProj import GdalToolsDialog as ExtractProj
d = ExtractProj( self.iface )
d.exec_()

def doDEM( self ):
from tools.doDEM import GdalToolsDialog as DEM
d = DEM( self.iface )
Expand Down
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions python/plugins/GdalTools/resources.qrc
Expand Up @@ -20,5 +20,6 @@
<file>icons/tileindex.png</file>
<file>icons/about.png</file>
<file>icons/dem.png</file>
<file>icons/extract-projection.png</file>
</qresource>
</RCC>
117 changes: 117 additions & 0 deletions python/plugins/GdalTools/tools/dialogExtractProjection.ui
@@ -0,0 +1,117 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>GdalToolsDialog</class>
<widget class="QDialog" name="GdalToolsDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>192</height>
</rect>
</property>
<property name="windowTitle">
<string>Extract projection</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QCheckBox" name="batchCheck">
<property name="text">
<string>Batch mode (for processing whole directory)</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>&amp;Input file</string>
</property>
<property name="buddy">
<cstring>inSelector</cstring>
</property>
</widget>
</item>
<item>
<widget class="GdalToolsInOutSelector" name="inSelector" native="true"/>
</item>
</layout>
</item>
<item>
<widget class="QCheckBox" name="recurseCheck">
<property name="text">
<string>Recurse subdirectories</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="prjCheck">
<property name="text">
<string>Create also prj file</string>
</property>
</widget>
</item>
<item>
<widget class="QProgressBar" name="progressBar">
<property name="value">
<number>0</number>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>GdalToolsInOutSelector</class>
<extends>QWidget</extends>
<header>inOutSelector</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>GdalToolsDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>GdalToolsDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>
193 changes: 193 additions & 0 deletions python/plugins/GdalTools/tools/doExtractProj.py
@@ -0,0 +1,193 @@
# -*- coding: utf-8 -*-
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from qgis.core import *
from qgis.gui import *

from ui_dialogExtractProjection import Ui_GdalToolsDialog as Ui_Dialog
import GdalTools_utils as Utils

import os.path

try:
from osgeo import gdal
from osgeo import osr
except ImportError, e:
error_str = e.args[ 0 ]
error_mod = error_str.replace( "No module named ", "" )
if req_mods.has_key( error_mod ):
error_str = error_str.replace( error_mod, req_mods[error_mod] )
raise ImportError( error_str )

class GdalToolsDialog( QDialog, Ui_Dialog ):
def __init__( self, iface ):
QDialog.__init__( self )
self.setupUi( self )
self.iface = iface

self.inSelector.setType( self.inSelector.FILE )

self.recurseCheck.hide()

self.okButton = self.buttonBox.button( QDialogButtonBox.Ok )
self.cancelButton = self.buttonBox.button( QDialogButtonBox.Cancel )

self.connect( self.inSelector, SIGNAL( "selectClicked()" ), self.fillInputFileEdit )
self.connect( self.batchCheck, SIGNAL( "stateChanged( int )" ), self.switchToolMode )

def switchToolMode( self ):
self.recurseCheck.setVisible( self.batchCheck.isChecked() )

self.inSelector.clear()

if self.batchCheck.isChecked():
self.inFileLabel = self.label.text()
self.label.setText( QCoreApplication.translate( "GdalTools", "&Input directory" ) )

QObject.disconnect( self.inSelector, SIGNAL( "selectClicked()" ), self.fillInputFileEdit )
QObject.connect( self.inSelector, SIGNAL( "selectClicked()" ), self.fillInputDir )
else:
self.label.setText( self.inFileLabel )

QObject.connect( self.inSelector, SIGNAL( "selectClicked()" ), self.fillInputFileEdit )
QObject.disconnect( self.inSelector, SIGNAL( "selectClicked()" ), self.fillInputDir )

def fillInputFileEdit( self ):
lastUsedFilter = Utils.FileFilter.lastUsedRasterFilter()
inputFile = Utils.FileDialog.getOpenFileName( self, self.tr( "Select the file to analyse" ), Utils.FileFilter.allRastersFilter(), lastUsedFilter )
if inputFile.isEmpty():
return
Utils.FileFilter.setLastUsedRasterFilter( lastUsedFilter )
self.inSelector.setFilename( inputFile )

def fillInputDir( self ):
inputDir = Utils.FileDialog.getExistingDirectory( self, self.tr( "Select the input directory with files to Assign projection" ))
if inputDir.isEmpty():
return
self.inSelector.setFilename( inputDir )

def reject( self ):
QDialog.reject( self )

def accept( self ):
self.inFiles = None
if self.batchCheck.isChecked():
self.inFiles = Utils.getRasterFiles( self.inSelector.filename(), self.recurseCheck.isChecked() )
else:
self.inFiles = [ self.inSelector.filename() ]

self.progressBar.setRange( 0, len( self.inFiles ) )

QApplication.setOverrideCursor( QCursor( Qt.WaitCursor ) )
self.okButton.setEnabled( False )

self.extractor = ExtractThread( self.inFiles, self.prjCheck.isChecked() )
QObject.connect( self.extractor, SIGNAL( "fileProcessed()" ), self.updateProgress )
QObject.connect( self.extractor, SIGNAL( "processFinished()" ), self.processingFinished )
QObject.connect( self.extractor, SIGNAL( "processInterrupted()" ), self.processingInterrupted )

QObject.disconnect( self.buttonBox, SIGNAL( "rejected()" ), self.reject )
QObject.connect( self.buttonBox, SIGNAL( "rejected()" ), self.stopProcessing )

self.extractor.start()

def updateProgress( self ):
self.progressBar.setValue( self.progressBar.value() + 1 )

def processingFinished( self ):
self.stopProcessing()

def processingInterrupted( self ):
self.restoreGui()

def stopProcessing( self ):
if self.extractor != None:
self.extractor.stop()
self.extractor = None

self.restoreGui()

def restoreGui( self ):
self.progressBar.setRange( 0, 100 )
self.progressBar.setValue( 0 )

QApplication.restoreOverrideCursor()

QObject.disconnect( self.buttonBox, SIGNAL( "rejected()" ), self.stopProcessing )
QObject.connect( self.buttonBox, SIGNAL( "rejected()" ), self.reject )

self.okButton.setEnabled( True )

# ----------------------------------------------------------------------

def extractProjection( filename, createPrj ):
raster = gdal.Open( unicode( filename ) )

crs = raster.GetProjection()
geotransform = raster.GetGeoTransform()

raster = None

outFileName = os.path.splitext( unicode( filename ) )[0]

# create prj file requested and if projection available
if crs != "" and createPrj:
# convert CRS into ESRI format
tmp = osr.SpatialReference()
tmp.ImportFromWkt( crs )
tmp.MorphToESRI()
crs = tmp.ExportToWkt()
tmp = None

prj = open( outFileName + '.prj', 'wt' )
prj.write( crs )
prj.close()

# create wld file
wld = open( outFileName + '.wld', 'wt')
wld.write( "%0.8f\n" % geotransform[1] )
wld.write( "%0.8f\n" % geotransform[2] )
wld.write( "%0.8f\n" % geotransform[4] )
wld.write( "%0.8f\n" % geotransform[5] )
wld.write( "%0.8f\n" % geotransform[0] )
wld.write( "%0.8f\n" % geotransform[3] )
wld.close()

class ExtractThread( QThread ):
def __init__( self, files, needPrj ):
QThread.__init__( self, QThread.currentThread() )
self.inFiles = files
self.needPrj = needPrj

self.mutex = QMutex()
self.stopMe = 0

def run( self ):
self.mutex.lock()
self.stopMe = 0
self.mutex.unlock()

interrupted = False

for f in self.inFiles:
extractProjection( f, self.needPrj )
self.emit( SIGNAL( "fileProcessed()" ) )

self.mutex.lock()
s = self.stopMe
self.mutex.unlock()
if s == 1:
interrupted = True
break

if not interrupted:
self.emit( SIGNAL( "processFinished()" ) )
else:
self.emit( SIGNAL( "processIterrupted()" ) )

def stop( self ):
self.mutex.lock()
self.stopMe = 1
self.mutex.unlock()

QThread.wait( self )

0 comments on commit 1f1dd7d

Please sign in to comment.