class QosmDialog(QDialog, Ui_qosmDialogBase): def __init__(self, iface): """Constructor.""" super(QosmDialog, self).__init__(None) self.setupUi(self) self.refresh_types() self.newlayer = False self.iface = iface self.cachedialog = DialogCachetiles(self, iface) def on_downloadTileCache_released(self): current = self.maptypeSpinner.itemData(self.maptypeSpinner.currentIndex()) self.cachedialog.set_tiletype(current) self.cachedialog.set_extent() self.cachedialog.autoset_minmax() self.cachedialog.show() def on_addCustomType_released(self): #validate url urlpattern = unicode(self.customUrl.text()) if tm.valid_urlpattern(urlpattern): urlpattern = urlpattern.strip() currenttype = self.get_type(urlpattern) if not currenttype is None: self.set_selected_type(currenttype) self.customUrl.setText("") self.customUrl.clearFocus() else: #ask for name name, ok = QInputDialog.getText(self, "Enter name", "Enter name for custom tile type:") if ok: name = name.strip() if len(name) > 0: self.add_custom_type(urlpattern, name) self.refresh_types() self.set_selected_type(urlpattern) else: QMessageBox.information(self, "QOSM Error", "Invalid URL pattern (must contain ${x}, ${y} and ${z} or ${quadkey}") def add_custom_type(self, urlpattern, label): customtypes = qosmsettings.get(qosmsettings.CUSTOM_TILE_TYPES) customtypes[urlpattern] = label qosmsettings.put(qosmsettings.CUSTOM_TILE_TYPES, customtypes) self.customUrl.setText("") self.customUrl.clearFocus() def refresh_types(self): self.maptypeSpinner.clear() i = 0 for tiletype, label in tm.BUILT_IN_LABELS.items(): self.maptypeSpinner.insertItem(i, label) self.maptypeSpinner.setItemData(i, tiletype) i += 1 self.maptypeSpinner.insertSeparator(i) i += 1 customtypes = qosmsettings.get(qosmsettings.CUSTOM_TILE_TYPES) for tiletype, label in customtypes.items(): self.maptypeSpinner.insertItem(i, label) self.maptypeSpinner.setItemData(i, tiletype) i += 1 def get_type(self, urlpattern): customtypes = qosmsettings.get(qosmsettings.CUSTOM_TILE_TYPES) if urlpattern in customtypes: return urlpattern else: for tiletype, urllist in tm.BUILT_IN_TILETYPES.items(): for url in urllist: if urlpattern == url: return tiletype return None def set_selected_type(self, setselection): if not setselection is None: index = self.maptypeSpinner.findData(setselection) if index != -1: self.maptypeSpinner.setCurrentIndex(index) def reset_defaults(self): self.set_selected_type("osm") #change to qosmsettings saved value self.customUrl.setText("") self.autorefresh.setChecked(True) def set_layer(self, layer, applyvalues=True): self.layer = layer if applyvalues: #check to make sure tiletype is in spinner. add if this is not true index = self.maptypeSpinner.findData(layer.tiletype) if index == -1: self.add_custom_type(layer.tiletype, "imported from project") self.autorefresh.setChecked(layer.autorefresh is True) self.set_selected_type(layer.tiletype) self.customUrl.setText("") if not self.layer.specifiedzoom is None: self.fixedZoom.setValue(self.layer.specifiedzoom) self.hasFixedZoom.setChecked(True) else: if self.layer.actualzoom is None: self.fixedZoom.setValue(tm.maxzoom(self.layer.tiletype)) else: self.fixedZoom.setValue(self.layer.actualzoom) if not self.layer.maxzoom is None: self.maxZoom.setValue(self.layer.maxzoom) self.hasMaxZoom.setChecked(True) else: self.maxZoom.setValue(tm.maxzoom(self.layer.tiletype)) self.set_summarystats() else: self.statusText.setText("") def set_summarystats(self): numtiles = len(self.layer.loadedlayers) zoom = self.layer.actualzoom if self.layer.specifiedzoom is None else \ self.layer.specifiedzoom extent = self.iface.mapCanvas().extent() crs = self.iface.mapCanvas().mapRenderer().destinationCrs() widthpx = self.iface.mapCanvas().width() extll = osm.unproject(extent, crs) calczoom = osm.autozoom(widthpx/(extll.xMaximum()-extll.xMinimum())) layerzoom = calczoom if zoom is None else zoom numtilestot = len(osm.tiles(extll.xMinimum(), extll.xMaximum(), extll.yMinimum(), extll.yMaximum(), layerzoom)) self.statusText.setText("Loaded %s of %s tiles at zoom level %s (automatic zoom would be %s). \ %s rendering errors (see QOSM Settings/Logs for more details)." % (numtiles, numtilestot, zoom, calczoom, self.layer.rendererrors)) def get_label(self, tiletype): if tiletype in tm.BUILT_IN_LABELS: return tm.BUILT_IN_LABELS[tiletype] else: customtypes = qosmsettings.get(qosmsettings.CUSTOM_TILE_TYPES) if tiletype in customtypes: return customtypes[tiletype] else: return str(tiletype) # in case None is passed def accept(self): #check environment to make sure this will work self.iface.mapCanvas().mapRenderer().setProjectionsEnabled(True) if not self.iface.mapCanvas().mapRenderer().destinationCrs().isValid(): if len(QgsMapLayerRegistry.instance().mapLayers()) > 1: self.iface.messageBar().pushMessage("Error", "You need to set a project CRS for QOSM to work!", level=QgsMessageBar.CRITICAL) self.reject() else: #this is the only layer. self.iface.mapCanvas().mapRenderer().setDestinationCrs(QgsCoordinateReferenceSystem(3857)) #best for osm #zoom to USA usa = QgsRectangle(-124.39, 25.82, -66.94, 49.38) xform = QgsCoordinateTransform(QgsCoordinateReferenceSystem(4326), QgsCoordinateReferenceSystem(3857)) usa = xform.transform(usa) self.iface.mapCanvas().setExtent(usa) #apply values to layer object if self.layer.autorefresh != self.autorefresh.isChecked(): self.layer.set_autorefresh(self.autorefresh.isChecked()) tiletypevalue = self.maptypeSpinner.itemData(self.maptypeSpinner.currentIndex()) if self.newlayer: self.layer.setLayerName("QOSM layer - " + self.get_label(tiletypevalue)) if tiletypevalue != self.layer.tiletype: #rename any part of the layer that was named according to the tiletype layername = unicode(self.layer.name()) layername = layername.replace(self.get_label(self.layer.tiletype), self.get_label(tiletypevalue)) self.layer.setLayerName(layername) #set new tiletype and clean old tiles self.layer.set_tiletype(tiletypevalue) self.layer.cleantiles() if self.hasFixedZoom.isChecked(): self.layer.set_fixedzoom(self.fixedZoom.value()) else: self.layer.set_fixedzoom(None) if self.hasMaxZoom.isChecked(): self.layer.set_maxzoom(self.maxZoom.value()) else: self.layer.set_maxzoom(None) self.layer.triggerRepaint() self.newlayer = False QDialog.accept(self) def reject(self): if self.newlayer: layerid = self.layer.id() QgsMapLayerRegistry.instance().removeMapLayer(layerid) self.newlayer = False QDialog.reject(self)