def calculate_cachesize(self): if self.cachesizethread is None: self.generalCacheSize.setText("calculating...") cachedir = s.get(s.CACHE_DIRECTORY) self.cachesizethread = DirsizeThread(self, cachedir) self.cachesizethread.finished.connect(self.cachesize_finished) self.cachesizethread.start() else: log("not starting second cachesize thread")
def zoom(self, widthpx, extll): if self.specifiedzoom is None: maxzoom = tm.maxzoom(self.tiletype) if self.maxzoom is None else self.maxzoom autozoom = osm.autozoom(widthpx/(extll.xMaximum()-extll.xMinimum())) return min(max((tm.minzoom(self.tiletype), autozoom)), maxzoom) else: numtiles = len(osm.tiles(extll.xMinimum(), extll.xMaximum(), extll.yMinimum(), extll.yMaximum(), self.specifiedzoom)) if numtiles > qosmsettings.get(qosmsettings.MAX_TILES): log("too many tiles for fixed zoom layer!: %s" % numtiles) self.rendererrors += 1 return None else: return self.specifiedzoom
def on_generalClearCache_released(self): QMessageBox.information(self, "fish", "fish") if self.generalCacheLocation.text() == s.get(s.CACHE_DIRECTORY): if QMessageBox.Ok == QMessageBox.question(self, "Question", "Clear entire cache directory? This cannot be undone.", QMessageBox.Ok | QMessageBox.Cancel): try: shutil.rmtree(s.get(s.CACHE_DIRECTORY)) os.mkdir(s.get(s.CACHE_DIRECTORY)) self.calculate_cachesize() except Exception as e: log("Error clearing cache directory: %s" % e) QMessageBox.information(self, "Error", "Error cleaning directory: %s" % e) else: QMessageBox.information(self, "Error", "Apply changes to cache directory before clearing.")
def on_logWhichLog_currentIndexChanged(self, text): if text == "Current session": fname = FILE elif text == "Previous session": fname = PREVIOUS_FILE else: self.logText.setPlainText("") return try: f = open(fname, "r") self.logText.setPlainText(f.read()) f.close() except IOError as e: log("could not load log into settings dialog: %s" % e) self.logText.setPlainText("")
def download_finished(self): log("Thread finished") self.thread.finished.disconnect(self.download_finished) self.thread.progress.disconnect(self.set_progress) self.thread.error.disconnect(self.add_error) self.rejected.disconnect(self.thread.cancel) self.gridLayout.setEnabled(True) self.button_box.button(QDialogButtonBox.Ok).setEnabled(True) haderrors = len(self.errors) != 0 self.errors = [] self.thread = None if not haderrors: self.statusText.setText("Download complete.")
def do_download(self): if not self.thread is None: #don't start another thread if is already downloading return self.gridLayout.setEnabled(False) self.button_box.button(QDialogButtonBox.Ok).setEnabled(False) minzoom = self.minZoom.value() maxzoom = self.maxZoom.value() tilelist = tiles(self.extent, minzoom, maxzoom) self.thread = DownloaderThread(self, self.tiletype, tilelist, self.doOverwrite.isChecked()) self.thread.finished.connect(self.download_finished) self.thread.progress.connect(self.set_progress) self.thread.error.connect(self.add_error) self.rejected.connect(self.thread.cancel) log("Starting thread") self.thread.start()
def createimage(self, extent, crs, outputsize): render = QgsMapRenderer() render.setLayerSet(self.loadedlayers.values()) render.setProjectionsEnabled(True) render.setDestinationCrs(crs) render.setExtent(extent) img = QImage(outputsize, QImage.Format_ARGB32_Premultiplied) img.fill(Qt.transparent) #needed, apparently the QImage() is not empty painter = QPainter() painter.begin(img) painter.setRenderHint(QPainter.Antialiasing) render.setOutputSize(img.size(), img.logicalDpiX()) log("about to render") render.render(painter) log("just rendered") painter.end() return img
def run(self): log("ensuring %s tiles are downloaded" % len(self.tilelist)) cachedir = qosmsettings.get(qosmsettings.CACHE_DIRECTORY) tilefiles = [tm.filename(cachedir, self.tiletype, tile[0:2], tile[2]) for tile in self.tilelist] tileurls = [tm.tileurl(self.tiletype, tile[0:2], tile[2]) for tile in self.tilelist] if not self.overwrite: #remove existing files indicies = [] for i in range(len(tilefiles)): if os.path.exists(tilefiles[i]): indicies.append(i) log("removing %s tiles that already exist" % len(indicies)) for i in reversed(indicies): tilefiles.pop(i) tileurls.pop(i) downloader.download(tileurls, tilefiles, self.overwrite, errorhandler=self.emiterror, progresshandler=self.emitprogress, cancelledcallback=self.isCancelled)
def refreshtiles_apply(self, tilestoclean, tilestoload, tilefiles, extent): #clean layerstoclean = [self.loadedlayers[tile] for tile in tilestoclean] for tile in tilestoclean: del self.loadedlayers[tile] QgsMapLayerRegistry.instance().removeMapLayers(layerstoclean) log("defining self.actualzoom") if len(tilestoload) > 0: self.actualzoom = tilestoload[0][2] else: self.actualzoom = None #load log("loading tiles") for i in range(len(tilestoload)): #check file exists if os.path.exists(tilefiles[i]): auxfile = tm.auxfilename(tilefiles[i]) if not os.path.exists(auxfile): osm.writeauxfile(*tilestoload[i], filename=auxfile, imagesize=tm.tilesize(self.tiletype)) #create layer, add to self.loadedlayers layername = "qosm_%s_x%s_y%s_z%s" % ((self.tiletype,) + tilestoload[i]) layer = QgsRasterLayer(tilefiles[i], layername) if layer.isValid(): layer = QgsMapLayerRegistry.instance().addMapLayer(layer, False) layer.resampleFilter().setZoomedOutResampler(QgsBilinearRasterResampler()) layer.resampleFilter().setZoomedInResampler(QgsBilinearRasterResampler()) self.loadedlayers[tilestoload[i]] = layer.id() else: log("ERROR invalid layer produced:" + layername) else: #report error? log("tile filename does not exist: " + tilefiles[i]) log("setting extent: " + extent.toString()) self.setExtent(extent)
def draw(self, rendererContext): log("drawing start") try: extent = rendererContext.extent() crs = rendererContext.coordinateTransform().destCRS() outputsize = QSize(rendererContext.painter().device().width(), rendererContext.painter().device().height()) refreshonce = self.refreshonce forcedownload = self.forcedownload self.refreshonce = False self.forcedownload = False if self.autorefresh or refreshonce: log("starting refresh") tilestoclean, tilestoload, tilefiles = self.refreshtiles_get(extent, crs, outputsize.width(), forcedownload=forcedownload, cancelledcallback=rendererContext.renderingStopped) log("refreshtiles_get returned") #check if rendering stopped before applying changes to object if rendererContext.renderingStopped(): log("rendering cancelled, returning True") return True log("applying tile changes") self.refreshtiles_apply(tilestoclean, tilestoload, tilefiles, extent) if len(self.loadedlayers) > 0: log("drawing loaded layers") img = self.createimage(extent, crs, outputsize) rendererContext.painter().drawImage(0, 0, img) log("drawing complete") else: log("no loaded layers, not drawing") log("drawing end") return True except Exception as e: log("error drawing: " + str(e)) log(traceback.format_exc()) self.rendererrors += 1 return False
def download(urllist, outfiles, overwrite=False, progresshandler=None, errorhandler=None, cancelledcallback=_default_cancelled_callback): if isinstance(outfiles, list): if not isinstance(urllist, list): raise ValueError("Cannot pass list to outfiles if urllist is not also a list") if len(outfiles) != len(urllist): raise ValueError("url and outfile must be of same length \ if list is passed to download") else: outfiles = [outfiles, ] * len(urllist) log("download() starting with %s urls and %s outfiles" % (len(urllist), len(outfiles))) downloadedfiles = [] if progresshandler: progresshandler(0, len(urllist)) for i in range(len(urllist)): if cancelledcallback(): return downloadedfiles url = urllist[i] outfile = outfiles[i] if os.path.isdir(outfile): filename = os.path.join(outfile, url.split("/")[-1]) else: filename = outfile try: if progresshandler: progresshandler(i, len(urllist)) if not os.path.isfile(filename) or overwrite: log("Downloading " + url) #ensure directory is already created directory = os.path.dirname(filename) if not os.path.exists(directory): os.makedirs(directory) fo = open(filename, "wb") urlhandle = urlopen(url) blocksize = 64*1024 while not cancelledcallback(): block = urlhandle.read(blocksize) if len(block) == 0: break fo.write(block) fo.close() urlhandle.close() downloadedfiles.append(filename) log("Downloaded to " + filename) else: log("Skipping existing file: " + filename) if cancelledcallback(): #remove cancelled download file os.unlink(filename) return downloadedfiles except IOError as e: log("Error downloading: %s" % e) if errorhandler: errorhandler(str(e)) fo.close() os.unlink(filename) finally: try: fo.close() urlhandle.close() except Exception: pass if progresshandler: progresshandler(len(urllist), len(urllist)) return downloadedfiles