def _initGui(self): "Set up the user interface" self.ui = Ui_batchGeocodeDlg() self.ui.setupUi(self) #settings self.s = QtCore.QSettings() self.loadSettings() #set vars self.csv = None self.delimiter = ';' self.headers = None self.graphicsLayer = [] self.reverseAdresTool = None self.batcGeoHelper = batcGeoHelper(self.iface, self, startFolder=self.startDir ) self.gh = geometryhelper.geometryHelper(self.iface) self.ui.delimEdit.setEnabled(False) self.ui.addToMapKnop.setEnabled(False) self.ui.tlFrame.setEnabled(False) self.ui.buttonBox.addButton( QtGui.QPushButton("Sluiten"), QtGui.QDialogButtonBox.RejectRole ) for btn in self.ui.buttonBox.buttons(): btn.setAutoDefault(0) #actions self.ui.outPutTbl.addAction( self.ui.actionValidateSelection) self.ui.actionValidateSelection.triggered.connect(self.validateSelection) self.ui.outPutTbl.addAction( self.ui.actionZoomToSelection ) self.ui.actionZoomToSelection.triggered.connect(self.zoomtoSelection) self.ui.outPutTbl.addAction(self.ui.adresFromMapAction) self.ui.adresFromMapAction.triggered.connect(self.adresFromMap) #event handlers self.ui.inputBtn.clicked.connect(self.openInputCsv) self.ui.inputTxt.returnPressed.connect(self.loadTable) self.ui.delimSelect.activated.connect(self.setDelim) self.ui.validateBtn.clicked.connect(self.validateAll) self.ui.validateSelBtn.clicked.connect(self.validateSelection) self.ui.addToMapKnop.clicked.connect(self.addToMap) self.ui.adresFromMapBtn.clicked.connect(self.adresFromMap) self.ui.singleLineChk.toggled.connect(self.on_singleLineToggled) self.ui.buttonBox.helpRequested.connect(self.openHelp) self.finished.connect(self.clean)
class geopunt4QgisBatcGeoCodeDialog(QtGui.QDialog): def __init__(self, iface): QtGui.QDialog.__init__(self, None) self.setWindowFlags( self.windowFlags() & ~QtCore.Qt.WindowContextHelpButtonHint ) #self.setWindowFlags( self.windowFlags() | QtCore.Qt.WindowStaysOnTopHint) self.iface = iface # initialize locale locale = QtCore.QSettings().value("locale/userLocale", "nl") if not locale: locale == 'nl' else: locale = locale[0:2] localePath = os.path.join(os.path.dirname(__file__), 'i18n', 'geopunt4qgis_{}.qm'.format(locale)) if os.path.exists(localePath): self.translator = QtCore.QTranslator() self.translator.load(localePath) if QtCore.qVersion() > '4.3.3': QtCore.QCoreApplication.installTranslator(self.translator) #load gui self._initGui() def _initGui(self): "Set up the user interface" self.ui = Ui_batchGeocodeDlg() self.ui.setupUi(self) #settings self.s = QtCore.QSettings() self.loadSettings() #set vars self.csv = None self.delimiter = ';' self.headers = None self.graphicsLayer = [] self.reverseAdresTool = None self.batcGeoHelper = batcGeoHelper(self.iface, self, startFolder=self.startDir ) self.gh = geometryhelper.geometryHelper(self.iface) self.ui.delimEdit.setEnabled(False) self.ui.addToMapKnop.setEnabled(False) self.ui.tlFrame.setEnabled(False) self.ui.buttonBox.addButton( QtGui.QPushButton("Sluiten"), QtGui.QDialogButtonBox.RejectRole ) for btn in self.ui.buttonBox.buttons(): btn.setAutoDefault(0) #actions self.ui.outPutTbl.addAction( self.ui.actionValidateSelection) self.ui.actionValidateSelection.triggered.connect(self.validateSelection) self.ui.outPutTbl.addAction( self.ui.actionZoomToSelection ) self.ui.actionZoomToSelection.triggered.connect(self.zoomtoSelection) self.ui.outPutTbl.addAction(self.ui.adresFromMapAction) self.ui.adresFromMapAction.triggered.connect(self.adresFromMap) #event handlers self.ui.inputBtn.clicked.connect(self.openInputCsv) self.ui.inputTxt.returnPressed.connect(self.loadTable) self.ui.delimSelect.activated.connect(self.setDelim) self.ui.validateBtn.clicked.connect(self.validateAll) self.ui.validateSelBtn.clicked.connect(self.validateSelection) self.ui.addToMapKnop.clicked.connect(self.addToMap) self.ui.adresFromMapBtn.clicked.connect(self.adresFromMap) self.ui.singleLineChk.toggled.connect(self.on_singleLineToggled) self.ui.buttonBox.helpRequested.connect(self.openHelp) self.finished.connect(self.clean) def loadSettings(self): self.maxRows = int( self.s.value("geopunt4qgis/batchMaxRows", 2000 )) self.saveToFile = int( self.s.value("geopunt4qgis/batchGeoCodeSavetoFile" , 1)) layerName = self.s.value("geopunt4qgis/batchLayerText", "") if layerName : self.layerName= layerName self.timeout = int(self.s.value("geopunt4qgis/timeout" ,15)) if int( self.s.value("geopunt4qgis/useProxy" , 0)): self.proxy = self.s.value("geopunt4qgis/proxyHost" ,"") self.port = self.s.value("geopunt4qgis/proxyPort" ,"") else: self.proxy = "" self.port = "" self.retrys = 3 self.startDir = self.s.value("geopunt4qgis/startDir", os.path.dirname(__file__)) self.gp = geopunt.Adres(self.timeout, self.proxy, self.port) #eventHandlers def openHelp(self): webbrowser.open_new_tab("http://www.geopunt.be/voor-experts/geopunt-plug-ins/functionaliteiten/csv-bestanden-geocoderen") def addToMap(self): if not self.layernameValid(): return adresCol = self.ui.outPutTbl.columnCount() -1 rowCount = self.ui.outPutTbl.rowCount() self.ui.statusProgress.setValue(0) self.ui.statusProgress.setMaximum(rowCount) retry = self.retrys row= 0 while row < rowCount: attributes = {} self.ui.statusProgress.setValue(row) if self.ui.outPutTbl.cellWidget(row,adresCol): adres = self.ui.outPutTbl.cellWidget(row,adresCol).currentText() if not adres: continue else: row += 1 continue for name, colIdx in self.headers.items(): val= self.ui.outPutTbl.item(row, colIdx).text() attributes[name] = val if adres.split(",")[0].replace('.','').isdigit() and len(adres.split(","))==2: x,y = [float(n) for n in adres.split(",")] fakecrab = {"Location":{"X_Lambert72":x ,"Y_Lambert72":y }} fakecrab["LocationType"] = "manuele aanduiding" loc = [fakecrab] else: loc = self.gp.fetchLocation(adres,1) if loc and type( loc ) is list: xylb = ( loc[0]["Location"]["X_Lambert72"], loc[0]["Location"]["Y_Lambert72"] ) xyType = loc[0]["LocationType"] xymap = self.gh.prjPtToMapCrs(xylb, 31370) self.batcGeoHelper.save_adres_point(xymap, adres, xyType, attritableDict=attributes, layername=self.layerName ) elif type( loc ) is str: if (loc == 'time out') & (retry > 0): retry -= 1 #minus 1 retry continue else: self.ui.statusMsg.setText("<div style='color:red'>timeout after %s seconds</div>" % (self.timeout)) return self.ui.statusMsg.setText("<div style='color:red'>%s</div>" % loc) return retry = self.retrys row += 1 if self.saveToFile: self.batcGeoHelper.saveMem2file(self.layerName) self.accept() def layernameValid(self): if not hasattr(self, 'layerName'): layerName, accept = QtGui.QInputDialog.getText(None, QtCore.QCoreApplication.translate("geopunt4Qgis", 'Laag toevoegen'), QtCore.QCoreApplication.translate("geopunt4Qgis", 'Geef een naam voor de laag op:') ) if accept == False: return False else: self.layerName = layerName return True def adresFromMap(self): if self.getSelectedRows() == []: return self.reverseAdresTool = reverseAdresMapTool(self.iface, self._reverseAdresCallback) self.iface.mapCanvas().setMapTool(self.reverseAdresTool) self.showMinimized() def on_singleLineToggled(self, toggled): if toggled: self.ui.adresColLbl.setText(QtCore.QCoreApplication.translate("batcGeoCodedialog", "Adres kolom:")) else: self.ui.adresColLbl.setText(QtCore.QCoreApplication.translate("batcGeoCodedialog", "Straatnaam kolom:")) def _reverseAdresCallback(self, point): 'private callback for reverseAdresMapTool' self.iface.mapCanvas().unsetMapTool(self.reverseAdresTool) self.showNormal() self.activateWindow() x,y = self.gh.prjPtFromMapCrs(point, 31370) adres = str(x) +","+ str(y) validAdresCol = self.ui.outPutTbl.columnCount() -1 rowIds= self.getSelectedRows() for rowIdx in rowIds: validCombo = QtGui.QComboBox(self.ui.adresColSelect) validCombo.addItems([adres]) validCombo.setEnabled(False) self.ui.outPutTbl.setCellWidget(rowIdx, validAdresCol, validCombo) for col in range(validAdresCol): self.ui.outPutTbl.item(rowIdx,col).setBackgroundColor(QtGui.QColor("#DDFFDD")) self.ui.outPutTbl.clearSelection() def loadTable(self): self.ui.outPutTbl.clearContents() #clear existing stuff self.ui.outPutTbl.setColumnCount(0) self.ui.outPutTbl.setRowCount(0) self.ui.adresColSelect.clear() self.ui.huisnrSelect.clear() self.ui.gemeenteColSelect.clear() self.ui.statusMsg.clear() self.clearGraphicsLayer() self.headers = {} self.csv = self.ui.inputTxt.text() if not self.csv : #none or empty string self.ui.adresWgt.setDisabled(True) return elif not os.path.exists(self.csv): self.ui.statusMsg.setText(QtCore.QCoreApplication.translate("batcGeoCodedialog", "<div style='color:red'>%s bestaat niet</div>") % self.csv) self.ui.adresWgt.setDisabled(True) return if self.ui.codecBox.currentText() == 'utf-8' : try: csvReader = unicodecsv.reader(open( self.csv, 'rb'), delimiter=self.delimiter) except: QtGui.QMessageBox.warning(self, "Error", QtCore.QCoreApplication.translate("batcGeoCodedialog", "Deze file kon niet correct worden ingelezen, probeer "+ "eens in te laden als <strong>ANSI-file</strong>")) else: try: csvReader = csv.reader(open( self.csv, 'r'), delimiter=self.delimiter) except: QtGui.QMessageBox.warning(self, "Error", QtCore.QCoreApplication.translate("batcGeoCodedialog", "Deze file kon niet correct worden ingelezen, probeer " + " eens in te laden als <strong>UTF-8-file</strong>")) header = csvReader.next() colCount = len(header) for i in range(colCount): self.headers[header[i]]= i self.ui.outPutTbl.setColumnCount(colCount + 1) self.ui.outPutTbl.setColumnWidth(colCount, 250) self.ui.outPutTbl.setHorizontalHeaderLabels(header + [QtCore.QCoreApplication.translate( "batcGeoCodedialog", "gevalideerd adres")]) self.ui.adresColSelect.insertItems(0, header) self.ui.gemeenteColSelect.insertItems(0, header + [QtCore.QCoreApplication.translate( "batcGeoCodedialog", "<geen>")]) self.ui.gemeenteColSelect.setCurrentIndex(colCount) self.ui.huisnrSelect.insertItems(0, header + [QtCore.QCoreApplication.translate( "batcGeoCodedialog", "<geen>")]) self.ui.huisnrSelect.setCurrentIndex(colCount) rowCount = 0 for line in csvReader: self.ui.outPutTbl.insertRow(rowCount) for col in range(colCount): self.ui.outPutTbl.setItem(rowCount, col, QtGui.QTableWidgetItem(line[col])) rowCount += 1 if rowCount > self.maxRows: warnTitle = QtCore.QCoreApplication.translate("batcGeoCodedialog", "%s heeft meer dan %s rijen") % (os.path.basename(self.csv), self.maxRows) warnMsg = "<div>" warnMsg += QtCore.QCoreApplication.translate("batcGeoCodedialog", "Je bestand heeft meer dan %s rijen.<br/>" ) % self.maxRows warnMsg += QtCore.QCoreApplication.translate("batcGeoCodedialog", "Om de servers van agiv niet te zwaar te belasten is de toepassing beperkt tot %s rijen.<br/>" ) % self.maxRows warnMsg += QtCore.QCoreApplication.translate("batcGeoCodedialog", "Deelnemers van GDI-vlaanderen kunnen gebruik maken van Crab Match om grote bestanden te valideren en geocoderen: <br/>" ) warnMsg += QtCore.QCoreApplication.translate("batcGeoCodedialog", "<a href='https://help.agiv.be/Categories/Details/213-Crab_Match_valideer_en_verrijk_je_adressenbestand'>Meer info</a>") warnMsg += "</div>" self.ui.statusMsg.setText("<div style='color:red'>"+ warnTitle +"</div>") QtGui.QMessageBox.warning(self, warnTitle, warnMsg ) break self.ui.adresWgt.setDisabled(False) self.ui.tlFrame.setDisabled(False) def setDelim(self, idx): txt = self.ui.delimSelect.itemText(idx) accept = True if txt == 'Puntcomma': self.delimiter = ';' self.loadTable() elif txt == 'Comma': self.delimiter = ',' self.loadTable() elif txt == 'Tab': self.delimiter = '\t' self.loadTable() else: delimiter, accept = QtGui.QInputDialog.getText(self, QtCore.QCoreApplication.translate("batcGeoCodedialog","Andere separator") , QtCore.QCoreApplication.translate("batcGeoCodedialog","Stel zelf een separator in: (Maximaal 1 karakter)")) if accept: self.delimiter = str( delimiter.strip()[0]) self.ui.delimEdit.setText(self.delimiter) self.loadTable() def validateSelection(self): if self.internet_on() != True: return rows = self.getSelectedRows() self.validateRows(rows) self.ui.addToMapKnop.setEnabled(True) def validateAll(self): if self.internet_on() != True: return rowCount = self.ui.outPutTbl.rowCount() rows = range(rowCount) self.validateRows(rows) self.ui.addToMapKnop.setEnabled(True) def validateRows(self , rowIds): if len(rowIds) == 0: return self.clearGraphicsLayer() adresTxt = self.ui.adresColSelect.currentText() huisnrTxt = self.ui.huisnrSelect.currentText() gemeenteTxt = self.ui.gemeenteColSelect.currentText() validAdresCol = self.ui.outPutTbl.columnCount() -1 adresCol = self.headers[adresTxt] if gemeenteTxt != QtCore.QCoreApplication.translate("batcGeoCodedialog", "<geen>"): gemeenteCol = self.headers[gemeenteTxt] if huisnrTxt != QtCore.QCoreApplication.translate("batcGeoCodedialog", "<geen>"): huisnrCol = self.headers[huisnrTxt] self.ui.statusProgress.setValue(0) self.ui.statusProgress.setMaximum(len(rowIds)) self.ui.statusMsg.setText("vooruitgang: ") retry = self.retrys i= 0 while i < len( rowIds): rowIdx = rowIds[i] #status Progress self.ui.statusProgress.setValue(i) adres = self.ui.outPutTbl.item(rowIdx, adresCol).text() if huisnrTxt != QtCore.QCoreApplication.translate("batcGeoCodedialog", "<geen>"): adres += " " + self.ui.outPutTbl.item(rowIdx, huisnrCol).text() if gemeenteTxt != QtCore.QCoreApplication.translate("batcGeoCodedialog", "<geen>"): adres = ",".join([adres, self.ui.outPutTbl.item(rowIdx, gemeenteCol).text()]) adres = " ".join( adres.split()) #remove too many spaces validAdres = self.gp.fetchSuggestion(adres, 5) if validAdres and type( validAdres ) is str: if (validAdres == 'time out') & (retry > 0): retry -= 1 #minus 1 retry continue elif retry == 0: self.ui.statusMsg.setText("<div style='color:red'>timeout na %s seconden and %s pogingen</div>" % (self.timeout , self.retrys)) return self.ui.statusMsg.setText("<div style='color:red'>%s</div>" % validAdres) return elif validAdres and type( validAdres ) is list: if len(validAdres) > 1 and len( validAdres[0].split(',')) == 2 and len(adres.strip()): resustNR = validAdres[0].split(',')[0].split()[-1] adresNR = adres.split(',')[0].split()[-1] if adresNR == resustNR: validAdres = [validAdres[0]] validCombo = QtGui.QComboBox(self.ui.adresColSelect) validCombo.addItems(validAdres) self.ui.outPutTbl.setCellWidget(rowIdx, validAdresCol, validCombo) if len(validAdres) == 1: self.ui.outPutTbl.cellWidget(rowIdx, validAdresCol).setEnabled(0) for col in range(len(self.headers)): self.ui.outPutTbl.item(rowIdx, col).setBackgroundColor(QtGui.QColor("#CCFFCC")) elif len(validAdres) > 1: self.ui.outPutTbl.cellWidget(rowIdx, validAdresCol).addItem("") for col in range(len(self.headers)): self.ui.outPutTbl.item(rowIdx, col).setBackgroundColor(QtGui.QColor("#FFFFC8")) elif len(validAdres) == 0: self.ui.outPutTbl.setCellWidget(rowIdx, validAdresCol, None) for col in range(len(self.headers)): self.ui.outPutTbl.item(rowIdx, col).setBackgroundColor(QtGui.QColor("#FFBEBE")) i += 1 retry = self.retrys #reset statusbar self.ui.statusMsg.setText("") self.ui.statusProgress.setValue(0) self.ui.outPutTbl.clearSelection() def zoomtoSelection(self): self.clearGraphicsLayer() rows = self.getSelectedRows() adresCol = self.ui.outPutTbl.columnCount() -1 i = 0 pts = [] while i < len(rows): row = rows[i] adres = None if self.ui.outPutTbl.cellWidget(row,adresCol): adres = self.ui.outPutTbl.cellWidget(row,adresCol).currentText() if adres: loc = self.gp.fetchLocation(adres,1) if loc and type( loc ) is list: xylb = ( loc[0]["Location"]["X_Lambert72"], loc[0]["Location"]["Y_Lambert72"]) xyMap = self.gh.prjPtToMapCrs(xylb, 31370) pts.append(xyMap) graphic = self.gh.addPointGraphic(xyMap) self.graphicsLayer.append(graphic) elif type(loc ) is str: self.ui.statusMsg.setText("<div style='color:red'>%s</div>" % loc) self.clearGraphicsLayer() i += 1 bounds = None if len(pts) == 1: x,y = pts[0] bounds = self.gh.getBoundsOfPoint(x, y) elif len(pts) > 1: bounds = self.gh.getBoundsOfPointArray(pts) self.gh.zoomtoRec2(bounds) def openInputCsv(self): fd = QtGui.QFileDialog() filter = "Comma separated value File (.csv) (*.csv);;Text Files (.txt) (*.txt);;Any File (*.*)" fd.setFileMode(QtGui.QFileDialog.AnyFile) #testdata: /home/kay/projects/geopunt4Qgis/testData/vergunning2.csv fName = fd.getOpenFileName( self, "open file" , self.startDir, filter) if fName: self.ui.inputTxt.setText(fName) self.loadTable() def internet_on(self): inet_on = geopunt.internet_on( timeout= self.timeout , proxyUrl= self.proxy , port= self.port ) if True != inet_on: self.ui.statusMsg.setText( QtCore.QCoreApplication.translate("batcGeoCodedialog", "<div style='color:red'>Kon geen connectie maken met geopunt</div>")) return inet_on def getSelectedRows(self): selected = set( [sel.row() for sel in self.ui.outPutTbl.selectedIndexes()] ) return list( selected ) def clearGraphicsLayer(self): for graphic in self.graphicsLayer: self.iface.mapCanvas().scene().removeItem(graphic) self.graphicsLayer = [] def clean(self): self.batcGeoHelper.clear() #ui self.ui.inputTxt.setText("") self.ui.delimSelect.setCurrentIndex(0) self.ui.outPutTbl.clearContents() self.ui.outPutTbl.setRowCount(0) self.ui.outPutTbl.setColumnCount(0) self.ui.adresColSelect.clear() self.ui.huisnrSelect.clear() self.ui.gemeenteColSelect.clear() self.ui.adresWgt.setEnabled(False) self.ui.addToMapKnop.setEnabled(False) self.ui.statusProgress.setValue(0) self.ui.statusMsg.setText("") #vars self.csv = None self.delimiter = ';' self.headers = None self.headers = {} self.clearGraphicsLayer() #unsetMapTool self.iface.mapCanvas().unsetMapTool(self.reverseAdresTool)