def _renderedImage2(self, width, height, extent, transp_background=False, layerids=None): antialias = True if self._renderer is None: self._initRenderer() canvas = self.context.canvas if layerids is None: layerids = [mapLayer.id() for mapLayer in canvas.layers()] renderer = self._renderer renderer.setLayerSet(layerids) image = QImage(width, height, QImage.Format_ARGB32_Premultiplied) if transp_background: image.fill(QColor(Qt.transparent).rgba()) # else: image.fill(canvas.canvasColor().rgba()) # renderer.setOutputSize(image.size(), image.logicalDpiX()) renderer.setExtent(extent.unrotatedRect()) painter = QPainter() painter.begin(image) if antialias: painter.setRenderHint(QPainter.Antialiasing) renderer.render(painter) painter.end() return tools.base64image(image)
def renderedImage(self, width, height, extent, transp_background=False, layerids=None): if QGis.QGIS_VERSION_INT < 20700: return self._renderedImage2(width, height, extent, transp_background, layerids) from qgis.core import QgsMapRendererCustomPainterJob antialias = True # render map image with QgsMapRendererCustomPainterJob settings = self.context.canvas.mapSettings() settings.setOutputSize(QSize(width, height)) settings.setExtent(extent.unrotatedRect()) settings.setRotation(extent.rotation()) if layerids: settings.setLayers(layerids) if transp_background: settings.setBackgroundColor(QColor(Qt.transparent)) #else: #TODO: remove #settings.setBackgroundColor(self.context.canvas.canvasColor()) image = QImage(width, height, QImage.Format_ARGB32_Premultiplied) painter = QPainter() painter.begin(image) if antialias: painter.setRenderHint(QPainter.Antialiasing) job = QgsMapRendererCustomPainterJob(settings, painter) job.start() job.waitForFinished() painter.end() return tools.base64image(image)
def _renderedImage2(self, width, height, extent, transp_background=False, layerids=None): """rendering function for GIS < 2.7""" antialias = True if self._renderer is None: self._initRenderer() canvas = self.exportSettings.canvas if canvas is None: logMessage("With this QGIS version (<= 2.6), map canvas needs to be set to the export settings") return if layerids is None: layerids = [mapLayer.id() for mapLayer in canvas.layers()] renderer = self._renderer # QgsMapRenderer renderer.setLayerSet(layerids) image = QImage(width, height, QImage.Format_ARGB32_Premultiplied) if transp_background: image.fill(QColor(Qt.transparent).rgba()) # else: image.fill(canvas.canvasColor().rgba()) # renderer.setOutputSize(image.size(), image.logicalDpiX()) renderer.setExtent(extent.unrotatedRect()) painter = QPainter() painter.begin(image) if antialias: painter.setRenderHint(QPainter.Antialiasing) renderer.render(painter) painter.end() return tools.base64image(image)
def renderedImage(self, width, height, extent, transp_background=False, layerids=None): if QGis.QGIS_VERSION_INT < 20700: return self._renderedImage2(width, height, extent, transp_background, layerids) # render layers with QgsMapRendererCustomPainterJob from qgis.core import QgsMapRendererCustomPainterJob antialias = True settings = self.exportSettings.mapSettings # store old map settings old_outputSize = settings.outputSize() old_extent = settings.extent() old_rotation = settings.rotation() old_layerids = settings.layers() old_backgroundColor = settings.backgroundColor() # map settings settings.setOutputSize(QSize(width, height)) settings.setExtent(extent.unrotatedRect()) settings.setRotation(extent.rotation()) if layerids is not None: settings.setLayers(layerids) if transp_background: settings.setBackgroundColor(QColor(Qt.transparent)) #else: #TODO: remove #settings.setBackgroundColor(self.exportSettings.canvas.canvasColor()) has_pluginlayer = False for layerId in settings.layers(): layer = QgsMapLayerRegistry.instance().mapLayer(layerId) if layer and layer.type() == QgsMapLayer.PluginLayer: has_pluginlayer = True break # create an image image = QImage(width, height, QImage.Format_ARGB32_Premultiplied) painter = QPainter() painter.begin(image) if antialias: painter.setRenderHint(QPainter.Antialiasing) # rendering job = QgsMapRendererCustomPainterJob(settings, painter) if has_pluginlayer: job.renderSynchronously() # use this method so that TileLayerPlugin layer is rendered correctly else: job.start() job.waitForFinished() painter.end() # restore map settings settings.setOutputSize(old_outputSize) settings.setExtent(old_extent) settings.setRotation(old_rotation) settings.setLayers(old_layerids) settings.setBackgroundColor(old_backgroundColor) return tools.base64image(image)
def mapCanvasImage(self, transp_background=False): """ returns base64 encoded map canvas image """ if transp_background: size = self.context.mapSettings.outputSize() return self.renderedImage(size.width(), size.height(), self.context.baseExtent, transp_background) canvas = self.context.canvas if QGis.QGIS_VERSION_INT >= 20400: return tools.base64image(canvas.map().contentImage()) temp_dir = QDir.tempPath() texfilename = os.path.join(temp_dir, "tex%s.png" % (self.context.timestamp)) canvas.saveAsImage(texfilename) texData = gdal2threejs.base64image(texfilename) tools.removeTemporaryFiles([texfilename, texfilename + "w"]) return texData
def mapCanvasImage(self, transp_background=False): """ returns base64 encoded map canvas image """ canvas = self.exportSettings.canvas if canvas is None or transp_background: size = self.exportSettings.mapSettings.outputSize() return self.renderedImage(size.width(), size.height(), self.exportSettings.baseExtent, transp_background) if QGis.QGIS_VERSION_INT >= 20400: return tools.base64image(canvas.map().contentImage()) temp_dir = QDir.tempPath() texfilename = os.path.join( temp_dir, "tex%s.png" % (self.exportSettings.timestamp)) canvas.saveAsImage(texfilename) texData = gdal2threejs.base64image(texfilename) tools.removeTemporaryFiles([texfilename, texfilename + "w"]) return texData
def _renderedImage2(self, width, height, extent, transp_background=False, layerids=None): """rendering function for GIS < 2.7""" antialias = True if self._renderer is None: self._initRenderer() canvas = self.exportSettings.canvas if canvas is None: logMessage( "With this QGIS version (<= 2.6), map canvas needs to be set to the export settings" ) return if layerids is None: layerids = [mapLayer.id() for mapLayer in canvas.layers()] renderer = self._renderer # QgsMapRenderer renderer.setLayerSet(layerids) image = QImage(width, height, QImage.Format_ARGB32_Premultiplied) if transp_background: image.fill(QColor(Qt.transparent).rgba()) # else: image.fill(canvas.canvasColor().rgba()) # renderer.setOutputSize(image.size(), image.logicalDpiX()) renderer.setExtent(extent.unrotatedRect()) painter = QPainter() painter.begin(image) if antialias: painter.setRenderHint(QPainter.Antialiasing) renderer.render(painter) painter.end() return tools.base64image(image)
def writeSphereTexture(writer): #context = writer.context canvas = writer.context.canvas antialias = True image_height = 1024 image_width = 2 * image_height image = QImage(image_width, image_height, QImage.Format_ARGB32_Premultiplied) # fill image with canvas color fillColor = canvas.canvasColor() if float(".".join(QT_VERSION_STR.split(".")[0:2])) < 4.8: fillColor = qRgb(fillColor.red(), fillColor.green(), fillColor.blue()) image.fill(fillColor) # set up a renderer renderer = QgsMapRenderer() renderer.setOutputSize(image.size(), image.logicalDpiX()) crs = QgsCoordinateReferenceSystem(4326) renderer.setDestinationCrs(crs) renderer.setProjectionsEnabled(True) layerids = [] for layer in canvas.layers(): layerids.append(unicode(layer.id())) renderer.setLayerSet(layerids) extent = QgsRectangle(-180, -90, 180, 90) renderer.setExtent(extent) # render map image painter = QPainter() painter.begin(image) if antialias: painter.setRenderHint(QPainter.Antialiasing) renderer.render(painter) painter.end() #if context.localBrowsingMode: texData = tools.base64image(image) writer.write('tex = "{0}";\n'.format(texData))
def writeMultiResDEM(writer, properties, progress=None): context = writer.context mapTo3d = context.mapTo3d canvas = context.canvas if progress is None: progress = dummyProgress demlayer = QgsMapLayerRegistry().instance().mapLayer(properties["comboBox_DEMLayer"]) temp_dir = QDir.tempPath() timestamp = writer.timestamp htmlfilename = writer.htmlfilename out_dir, filename = os.path.split(htmlfilename) filetitle = os.path.splitext(filename)[0] # material options demTransparency = properties["spinBox_demtransp"] # layer dict lyr = {"type": "dem", "name": demlayer.name(), "dem": []} lyr["q"] = 1 #queryable lyrIdx = writer.writeLayer(lyr) # create quad tree quadtree = createQuadTree(canvas.extent(), properties) if quadtree is None: QMessageBox.warning(None, "Qgis2threejs", "Focus point/area is not selected.") return quads = quadtree.quads() # create quads and a point on map canvas with rubber bands context.dialog.createRubberBands(quads, quadtree.focusRect.center()) # create an image for texture image_basesize = 128 hpw = canvas.extent().height() / canvas.extent().width() if hpw < 1: image_width = image_basesize image_height = round(image_width * hpw) else: image_height = image_basesize image_width = round(image_height / hpw) image = QImage(image_width, image_height, QImage.Format_ARGB32_Premultiplied) #qDebug("Created image size: %d, %d" % (image_width, image_height)) layerids = [] for layer in canvas.layers(): layerids.append(unicode(layer.id())) # set up a renderer labeling = QgsPalLabeling() renderer = QgsMapRenderer() renderer.setOutputSize(image.size(), image.logicalDpiX()) renderer.setDestinationCrs(context.crs) renderer.setProjectionsEnabled(True) renderer.setLabelingEngine(labeling) renderer.setLayerSet(layerids) painter = QPainter() antialias = True fillColor = canvas.canvasColor() if float(".".join(QT_VERSION_STR.split(".")[0:2])) < 4.8: fillColor = qRgb(fillColor.red(), fillColor.green(), fillColor.blue()) # (currently) dem size should be 2 ^ quadtree.height * a + 1, where a is larger integer than 0 # with smooth resolution change, this is not necessary dem_width = dem_height = max(64, 2 ** quadtree.height) + 1 warp_dem = tools.MemoryWarpRaster(demlayer.source().encode("UTF-8")) wkt = str(context.crs.toWkt()) unites_center = True centerQuads = DEMQuadList(dem_width, dem_height) scripts = [] stats = None plane_index = 0 for i, quad in enumerate(quads): progress(45 * i / len(quads) + 5) extent = quad.extent # calculate extent. output dem should be handled as points. xres = extent.width() / (dem_width - 1) yres = extent.height() / (dem_height - 1) geotransform = [extent.xMinimum() - xres / 2, xres, 0, extent.yMaximum() + yres / 2, 0, -yres] # warp dem dem_values = warp_dem.read(dem_width, dem_height, wkt, geotransform) if stats is None: stats = {"max": max(dem_values), "min": min(dem_values)} else: stats["max"] = max(max(dem_values), stats["max"]) stats["min"] = min(min(dem_values), stats["min"]) # shift and scale if mapTo3d.verticalShift != 0: dem_values = map(lambda x: x + mapTo3d.verticalShift, dem_values) if mapTo3d.multiplierZ != 1: dem_values = map(lambda x: x * mapTo3d.multiplierZ, dem_values) if debug_mode: qDebug("Warped DEM: %d x %d, extent %s" % (dem_width, dem_height, str(geotransform))) # generate javascript data file planeWidth = mapTo3d.planeWidth * extent.width() / canvas.extent().width() planeHeight = mapTo3d.planeHeight * extent.height() / canvas.extent().height() offsetX = mapTo3d.planeWidth * (extent.xMinimum() - canvas.extent().xMinimum()) / canvas.extent().width() + planeWidth / 2 - mapTo3d.planeWidth / 2 offsetY = mapTo3d.planeHeight * (extent.yMinimum() - canvas.extent().yMinimum()) / canvas.extent().height() + planeHeight / 2 - mapTo3d.planeHeight / 2 # value resampling on edges for combination with different resolution DEM neighbors = quadtree.neighbors(quad) #qDebug("Output quad (%d %s): height=%d" % (i, str(quad), quad.height)) for direction, neighbor in enumerate(neighbors): if neighbor is None: continue #qDebug(" neighbor %d %s: height=%d" % (direction, str(neighbor), neighbor.height)) interval = 2 ** (quad.height - neighbor.height) if interval > 1: if direction == QuadTree.UP or direction == QuadTree.DOWN: y = 0 if direction == QuadTree.UP else dem_height - 1 for x1 in range(interval, dem_width, interval): x0 = x1 - interval z0 = dem_values[x0 + dem_width * y] z1 = dem_values[x1 + dem_width * y] for xx in range(1, interval): z = (z0 * (interval - xx) + z1 * xx) / interval dem_values[x0 + xx + dem_width * y] = z else: # LEFT or RIGHT x = 0 if direction == QuadTree.LEFT else dem_width - 1 for y1 in range(interval, dem_height, interval): y0 = y1 - interval z0 = dem_values[x + dem_width * y0] z1 = dem_values[x + dem_width * y1] for yy in range(1, interval): z = (z0 * (interval - yy) + z1 * yy) / interval dem_values[x + dem_width * (y0 + yy)] = z if quad.height < quadtree.height or unites_center == False: dem = {"width": dem_width, "height": dem_height} dem["plane"] = {"width": planeWidth, "height": planeHeight, "offsetX": offsetX, "offsetY": offsetY} # display type texData = None if properties.get("radioButton_MapCanvas", False): renderer.setExtent(extent) # render map image image.fill(fillColor) painter.begin(image) if antialias: painter.setRenderHint(QPainter.Antialiasing) renderer.render(painter) painter.end() tex = {} if context.localBrowsingMode: texData = tools.base64image(image) else: texfilename = os.path.splitext(htmlfilename)[0] + "_%d.png" % plane_index image.save(texfilename) texSrc = os.path.split(texfilename)[1] tex["src"] = texSrc if demTransparency > 0: demOpacity = 1.0 - float(demTransparency) / 100 tex["o"] = demOpacity tex["t"] = demOpacity < 1 # dem["t"] = tex elif properties.get("radioButton_SolidColor", False): dem["m"] = writer.materialManager.getMeshLambertIndex(properties["lineEdit_Color"], demTransparency) elif properties.get("radioButton_Wireframe", False): dem["m"] = writer.materialManager.getWireframeIndex(properties["lineEdit_Color"], demTransparency) # write dem object writer.openFile(True) writer.write("lyr[{0}].dem[{1}] = {2};\n".format(lyrIdx, plane_index, writer.obj2js(dem))) writer.write("lyr[{0}].dem[{1}].data = [{2}];\n".format(lyrIdx, plane_index, ",".join(map(gdal2threejs.formatValue, dem_values)))) if texData is not None: writer.write('lyr[{0}].dem[{1}].t.data = "{2}";\n'.format(lyrIdx, plane_index, texData)) plane_index += 1 else: centerQuads.addQuad(quad, dem_values) if unites_center: extent = centerQuads.extent() dem_width = (dem_width - 1) * centerQuads.width() + 1 dem_height = (dem_height - 1) * centerQuads.height() + 1 dem_values = centerQuads.unitedDEM() planeWidth = mapTo3d.planeWidth * extent.width() / canvas.extent().width() planeHeight = mapTo3d.planeHeight * extent.height() / canvas.extent().height() offsetX = mapTo3d.planeWidth * (extent.xMinimum() - canvas.extent().xMinimum()) / canvas.extent().width() + planeWidth / 2 - mapTo3d.planeWidth / 2 offsetY = mapTo3d.planeHeight * (extent.yMinimum() - canvas.extent().yMinimum()) / canvas.extent().height() + planeHeight / 2 - mapTo3d.planeHeight / 2 dem = {"width": dem_width, "height": dem_height} dem["plane"] = {"width": planeWidth, "height": planeHeight, "offsetX": offsetX, "offsetY": offsetY} # display type texData = None if properties.get("radioButton_MapCanvas", False): if hpw < 1: image_width = image_basesize * centerQuads.width() image_height = round(image_width * hpw) else: image_height = image_basesize * centerQuads.height() image_width = round(image_height / hpw) image = QImage(image_width, image_height, QImage.Format_ARGB32_Premultiplied) #qDebug("Created image size: %d, %d" % (image_width, image_height)) renderer.setOutputSize(image.size(), image.logicalDpiX()) renderer.setExtent(extent) # render map image image.fill(fillColor) painter.begin(image) if antialias: painter.setRenderHint(QPainter.Antialiasing) renderer.render(painter) painter.end() tex = {} if context.localBrowsingMode: texData = tools.base64image(image) else: texfilename = os.path.splitext(htmlfilename)[0] + "_%d.png" % plane_index image.save(texfilename) texSrc = os.path.split(texfilename)[1] tex["src"] = texSrc if demTransparency > 0: demOpacity = str(1.0 - float(demTransparency) / 100) tex["o"] = demOpacity tex["t"] = demOpacity < 1 # dem["t"] = tex elif properties.get("radioButton_SolidColor", False): dem["m"] = writer.materialManager.getMeshLambertIndex(properties["lineEdit_Color"], demTransparency) elif properties.get("radioButton_Wireframe", False): dem["m"] = writer.materialManager.getWireframeIndex(properties["lineEdit_Color"], demTransparency) # write dem object writer.openFile(True) writer.write("lyr[{0}].dem[{1}] = {2};\n".format(lyrIdx, plane_index, writer.obj2js(dem))) writer.write("lyr[{0}].dem[{1}].data = [{2}];\n".format(lyrIdx, plane_index, ",".join(map(gdal2threejs.formatValue, dem_values)))) if texData is not None: writer.write('lyr[{0}].dem[{1}].t.data = "{2}";\n'.format(lyrIdx, plane_index, texData)) plane_index += 1 writer.write("lyr[{0}].stats = {1};\n".format(lyrIdx, writer.obj2js(stats)))
def writeSurroundingDEM(writer, lyrIdx, stats, properties, progress=None): context = writer.context mapTo3d = context.mapTo3d canvas = context.canvas if progress is None: progress = dummyProgress demlayer = QgsMapLayerRegistry().instance().mapLayer(properties["comboBox_DEMLayer"]) htmlfilename = writer.htmlfilename # options size = properties["spinBox_Size"] roughening = properties["spinBox_Roughening"] demTransparency = properties["spinBox_demtransp"] prop = DEMPropertyReader(properties) dem_width = (prop.width() - 1) / roughening + 1 dem_height = (prop.height() - 1) / roughening + 1 # create an image for texture image_basesize = 128 hpw = canvas.extent().height() / canvas.extent().width() if hpw < 1: image_width = image_basesize image_height = round(image_width * hpw) #image_height = image_basesize * max(1, int(round(1 / hpw))) # not rendered expectedly else: image_height = image_basesize image_width = round(image_height / hpw) image = QImage(image_width, image_height, QImage.Format_ARGB32_Premultiplied) layerids = [] for layer in canvas.layers(): layerids.append(unicode(layer.id())) # set up a renderer labeling = QgsPalLabeling() renderer = QgsMapRenderer() renderer.setOutputSize(image.size(), image.logicalDpiX()) renderer.setDestinationCrs(context.crs) renderer.setProjectionsEnabled(True) renderer.setLabelingEngine(labeling) renderer.setLayerSet(layerids) painter = QPainter() antialias = True fillColor = canvas.canvasColor() if float(".".join(QT_VERSION_STR.split(".")[0:2])) < 4.8: fillColor = qRgb(fillColor.red(), fillColor.green(), fillColor.blue()) warp_dem = tools.MemoryWarpRaster(demlayer.source().encode("UTF-8")) wkt = str(context.crs.toWkt()) scripts = [] plane_index = 1 size2 = size * size for i in range(size2): progress(40 * i / size2 + 10) if i == (size2 - 1) / 2: # center (map canvas) continue sx = i % size - (size - 1) / 2 sy = i / size - (size - 1) / 2 # calculate extent e = canvas.extent() extent = QgsRectangle(e.xMinimum() + sx * e.width(), e.yMinimum() + sy * e.height(), e.xMaximum() + sx * e.width(), e.yMaximum() + sy * e.height()) # calculate extent. output dem should be handled as points. xres = extent.width() / (dem_width - 1) yres = extent.height() / (dem_height - 1) geotransform = [extent.xMinimum() - xres / 2, xres, 0, extent.yMaximum() + yres / 2, 0, -yres] # warp dem dem_values = warp_dem.read(dem_width, dem_height, wkt, geotransform) if stats is None: stats = {"max": max(dem_values), "min": min(dem_values)} else: stats["max"] = max(max(dem_values), stats["max"]) stats["min"] = min(min(dem_values), stats["min"]) # shift and scale if mapTo3d.verticalShift != 0: dem_values = map(lambda x: x + mapTo3d.verticalShift, dem_values) if mapTo3d.multiplierZ != 1: dem_values = map(lambda x: x * mapTo3d.multiplierZ, dem_values) if debug_mode: qDebug("Warped DEM: %d x %d, extent %s" % (dem_width, dem_height, str(geotransform))) # generate javascript data file planeWidth = mapTo3d.planeWidth * extent.width() / canvas.extent().width() planeHeight = mapTo3d.planeHeight * extent.height() / canvas.extent().height() offsetX = mapTo3d.planeWidth * (extent.xMinimum() - canvas.extent().xMinimum()) / canvas.extent().width() + planeWidth / 2 - mapTo3d.planeWidth / 2 offsetY = mapTo3d.planeHeight * (extent.yMinimum() - canvas.extent().yMinimum()) / canvas.extent().height() + planeHeight / 2 - mapTo3d.planeHeight / 2 dem = {"width": dem_width, "height": dem_height} dem["plane"] = {"width": planeWidth, "height": planeHeight, "offsetX": offsetX, "offsetY": offsetY} # display type texData = None if properties.get("radioButton_MapCanvas", False): renderer.setExtent(extent) # render map image image.fill(fillColor) painter.begin(image) if antialias: painter.setRenderHint(QPainter.Antialiasing) renderer.render(painter) painter.end() tex = {} if context.localBrowsingMode: texData = tools.base64image(image) else: texfilename = os.path.splitext(htmlfilename)[0] + "_%d.png" % plane_index image.save(texfilename) texSrc = os.path.split(texfilename)[1] tex["src"] = texSrc if demTransparency > 0: demOpacity = 1.0 - float(demTransparency) / 100 tex["o"] = demOpacity tex["t"] = demOpacity < 1 # dem["t"] = tex elif properties.get("radioButton_SolidColor", False): dem["m"] = writer.materialManager.getMeshLambertIndex(properties["lineEdit_Color"], demTransparency) elif properties.get("radioButton_Wireframe", False): dem["m"] = writer.materialManager.getWireframeIndex(properties["lineEdit_Color"], demTransparency) # write dem object writer.write("lyr[{0}].dem[{1}] = {2};\n".format(lyrIdx, plane_index, writer.obj2js(dem))) writer.write("lyr[{0}].dem[{1}].data = [{2}];\n".format(lyrIdx, plane_index, ",".join(map(gdal2threejs.formatValue, dem_values)))) if texData is not None: writer.write('lyr[{0}].dem[{1}].t.data = "{2}";\n'.format(lyrIdx, plane_index, texData)) plane_index += 1
def runAdvanced(htmlfilename, context, dialog, progress=None): mapTo3d = context.mapTo3d canvas = context.canvas if progress is None: progress = dummyProgress demlayer = QgsMapLayerRegistry().instance().mapLayer(context.demlayerid) temp_dir = QDir.tempPath() timestamp = datetime.datetime.today().strftime("%Y%m%d%H%M%S") if htmlfilename == "": htmlfilename = tools.temporaryOutputDir() + "/%s.html" % timestamp out_dir, filename = os.path.split(htmlfilename) if not QDir(out_dir).exists(): QDir().mkpath(out_dir) filetitle = os.path.splitext(filename)[0] # create quad tree quadtree = dialog.createQuadTree() if quadtree is None: QMessageBox.warning(None, "Qgis2threejs", "Focus point/area is not selected.") return quads = quadtree.quads() # create quads and a point on map canvas with rubber bands dialog.createRubberBands(quads, quadtree.focusRect.center()) # create an image for texture image_basesize = 128 hpw = canvas.extent().height() / canvas.extent().width() if hpw < 1: image_width = image_basesize image_height = round(image_width * hpw) else: image_height = image_basesize image_width = round(image_height * hpw) image = QImage(image_width, image_height, QImage.Format_ARGB32_Premultiplied) #qDebug("Created image size: %d, %d" % (image_width, image_height)) layerids = [] for layer in canvas.layers(): layerids.append(unicode(layer.id())) # set up a renderer labeling = QgsPalLabeling() renderer = QgsMapRenderer() renderer.setOutputSize(image.size(), image.logicalDpiX()) renderer.setDestinationCrs(context.crs) renderer.setProjectionsEnabled(True) renderer.setLabelingEngine(labeling) renderer.setLayerSet(layerids) painter = QPainter() antialias = True fillColor = canvas.canvasColor() if float(".".join(QT_VERSION_STR.split(".")[0:2])) < 4.8: fillColor = qRgb(fillColor.red(), fillColor.green(), fillColor.blue()) # (currently) dem size should be 2 ^ quadtree.height * a + 1, where a is larger integer than 0 # with smooth resolution change, this is not necessary dem_width = dem_height = max(64, 2 ** quadtree.height) + 1 warp_dem = tools.MemoryWarpRaster(demlayer.source().encode("UTF-8")) wkt = str(context.crs.toWkt()) # create JavaScript writer object context.setWarpDem(warp_dem) writer = JSWriter(htmlfilename, context) unites_center = True centerQuads = DEMQuadList(dem_width, dem_height) scripts = [] plane_index = 0 for i, quad in enumerate(quads): progress(50 * i / len(quads)) extent = quad.extent if quad.height < quadtree.height or unites_center == False: renderer.setExtent(extent) # render map image image.fill(fillColor) painter.begin(image) if antialias: painter.setRenderHint(QPainter.Antialiasing) renderer.render(painter) painter.end() if context.localBrowsingMode: tex = tools.base64image(image) else: texfilename = os.path.splitext(htmlfilename)[0] + "_%d.png" % plane_index image.save(texfilename) tex = os.path.split(texfilename)[1] # calculate extent. output dem should be handled as points. xres = extent.width() / (dem_width - 1) yres = extent.height() / (dem_height - 1) geotransform = [extent.xMinimum() - xres / 2, xres, 0, extent.yMaximum() + yres / 2, 0, -yres] # warp dem dem_values = warp_dem.read(dem_width, dem_height, wkt, geotransform) if mapTo3d.multiplierZ != 1: dem_values = map(lambda x: x * mapTo3d.multiplierZ, dem_values) if debug_mode: qDebug("Warped DEM: %d x %d, extent %s" % (dem_width, dem_height, str(geotransform))) # generate javascript data file planeWidth = mapTo3d.planeWidth * extent.width() / canvas.extent().width() planeHeight = mapTo3d.planeHeight * extent.height() / canvas.extent().height() offsetX = mapTo3d.planeWidth * (extent.xMinimum() - canvas.extent().xMinimum()) / canvas.extent().width() + planeWidth / 2 - mapTo3d.planeWidth / 2 offsetY = mapTo3d.planeHeight * (extent.yMinimum() - canvas.extent().yMinimum()) / canvas.extent().height() + planeHeight / 2 - mapTo3d.planeHeight / 2 # value resampling on edges for combination with different resolution DEM neighbors = quadtree.neighbors(quad) #qDebug("Output quad (%d %s): height=%d" % (i, str(quad), quad.height)) for direction, neighbor in enumerate(neighbors): if neighbor is None: continue #qDebug(" neighbor %d %s: height=%d" % (direction, str(neighbor), neighbor.height)) interval = 2 ** (quad.height - neighbor.height) if interval > 1: if direction == QuadTree.UP or direction == QuadTree.DOWN: y = 0 if direction == QuadTree.UP else dem_height - 1 for x1 in range(interval, dem_width, interval): x0 = x1 - interval z0 = dem_values[x0 + dem_width * y] z1 = dem_values[x1 + dem_width * y] for xx in range(1, interval): z = (z0 * (interval - xx) + z1 * xx) / interval dem_values[x0 + xx + dem_width * y] = z else: # LEFT or RIGHT x = 0 if direction == QuadTree.LEFT else dem_width - 1 for y1 in range(interval, dem_height, interval): y0 = y1 - interval z0 = dem_values[x + dem_width * y0] z1 = dem_values[x + dem_width * y1] for yy in range(1, interval): z = (z0 * (interval - yy) + z1 * yy) / interval dem_values[x + dem_width * (y0 + yy)] = z if quad.height < quadtree.height or unites_center == False: writer.openFile(True) opt = "{width:%f,height:%f,offsetX:%f,offsetY:%f}" % (planeWidth, planeHeight, offsetX, offsetY) writer.write('dem[%d] = {width:%d,height:%d,plane:%s,data:[%s]};\n' % (plane_index, dem_width, dem_height, opt, ",".join(map(gdal2threejs.formatValue, dem_values)))) writer.write('tex[%d] = "%s";\n' % (plane_index, tex)) plane_index += 1 else: centerQuads.addQuad(quad, dem_values) if unites_center: extent = centerQuads.extent() if hpw < 1: image_width = image_basesize * centerQuads.width() image_height = round(image_width * hpw) else: image_height = image_basesize * centerQuads.height() image_width = round(image_height * hpw) image = QImage(image_width, image_height, QImage.Format_ARGB32_Premultiplied) #qDebug("Created image size: %d, %d" % (image_width, image_height)) renderer.setOutputSize(image.size(), image.logicalDpiX()) renderer.setExtent(extent) # render map image image.fill(fillColor) painter.begin(image) if antialias: painter.setRenderHint(QPainter.Antialiasing) renderer.render(painter) painter.end() if context.localBrowsingMode: tex = tools.base64image(image) else: texfilename = os.path.splitext(htmlfilename)[0] + "_%d.png" % plane_index image.save(texfilename) tex = os.path.split(texfilename)[1] dem_values = centerQuads.unitedDEM() planeWidth = mapTo3d.planeWidth * extent.width() / canvas.extent().width() planeHeight = mapTo3d.planeHeight * extent.height() / canvas.extent().height() offsetX = mapTo3d.planeWidth * (extent.xMinimum() - canvas.extent().xMinimum()) / canvas.extent().width() + planeWidth / 2 - mapTo3d.planeWidth / 2 offsetY = mapTo3d.planeHeight * (extent.yMinimum() - canvas.extent().yMinimum()) / canvas.extent().height() + planeHeight / 2 - mapTo3d.planeHeight / 2 dem_width = (dem_width - 1) * centerQuads.width() + 1 dem_height = (dem_height - 1) * centerQuads.height() + 1 writer.openFile(True) opt = "{width:%f,height:%f,offsetX:%f,offsetY:%f}" % (planeWidth, planeHeight, offsetX, offsetY) writer.write('dem[%d] = {width:%d,height:%d,plane:%s,data:[%s]};\n' % (plane_index, dem_width, dem_height, opt, ",".join(map(gdal2threejs.formatValue, dem_values)))) writer.write('tex[%d] = "%s";\n' % (plane_index, tex)) plane_index += 1 progress(50) # vector data output writer.prepareNext() writeVectors(writer) progress(80) # copy files from template tools.copyThreejsFiles(out_dir) # generate html file with codecs.open(tools.pluginDir() + "/template.html", "r", "UTF-8") as f: html = f.read() with codecs.open(htmlfilename, "w", "UTF-8") as f: f.write(html.replace("${title}", filetitle).replace("${scripts}", writer.scripts())) return htmlfilename
def runAdvanced(htmlfilename, context, dialog, progress=None): mapTo3d = context.mapTo3d canvas = context.canvas if progress is None: progress = dummyProgress demlayer = QgsMapLayerRegistry().instance().mapLayer(context.demlayerid) temp_dir = QDir.tempPath() timestamp = datetime.datetime.today().strftime("%Y%m%d%H%M%S") if htmlfilename == "": htmlfilename = tools.temporaryOutputDir() + "/%s.html" % timestamp out_dir, filename = os.path.split(htmlfilename) if not QDir(out_dir).exists(): QDir().mkpath(out_dir) filetitle = os.path.splitext(filename)[0] # create quad tree quadtree = dialog.createQuadTree() if quadtree is None: QMessageBox.warning(None, "Qgis2threejs", "Focus point/area is not selected.") return quads = quadtree.quads() # create quads and a point on map canvas with rubber bands dialog.createRubberBands(quads, quadtree.focusRect.center()) # create an image for texture image_basesize = 128 hpw = canvas.extent().height() / canvas.extent().width() if hpw < 1: image_width = image_basesize image_height = round(image_width * hpw) else: image_height = image_basesize image_width = round(image_height * hpw) image = QImage(image_width, image_height, QImage.Format_ARGB32_Premultiplied) #qDebug("Created image size: %d, %d" % (image_width, image_height)) layerids = [] for layer in canvas.layers(): layerids.append(unicode(layer.id())) # set up a renderer labeling = QgsPalLabeling() renderer = QgsMapRenderer() renderer.setOutputSize(image.size(), image.logicalDpiX()) renderer.setDestinationCrs(context.crs) renderer.setProjectionsEnabled(True) renderer.setLabelingEngine(labeling) renderer.setLayerSet(layerids) painter = QPainter() antialias = True fillColor = canvas.canvasColor() if float(".".join(QT_VERSION_STR.split(".")[0:2])) < 4.8: fillColor = qRgb(fillColor.red(), fillColor.green(), fillColor.blue()) # (currently) dem size should be 2 ^ quadtree.height * a + 1, where a is larger integer than 0 # with smooth resolution change, this is not necessary dem_width = dem_height = max(64, 2**quadtree.height) + 1 warp_dem = tools.MemoryWarpRaster(demlayer.source().encode("UTF-8")) wkt = str(context.crs.toWkt()) # create JavaScript writer object context.setWarpDem(warp_dem) writer = JSWriter(htmlfilename, context) unites_center = True centerQuads = DEMQuadList(dem_width, dem_height) scripts = [] plane_index = 0 for i, quad in enumerate(quads): progress(50 * i / len(quads)) extent = quad.extent if quad.height < quadtree.height or unites_center == False: renderer.setExtent(extent) # render map image image.fill(fillColor) painter.begin(image) if antialias: painter.setRenderHint(QPainter.Antialiasing) renderer.render(painter) painter.end() if context.localBrowsingMode: tex = tools.base64image(image) else: texfilename = os.path.splitext( htmlfilename)[0] + "_%d.png" % plane_index image.save(texfilename) tex = os.path.split(texfilename)[1] # calculate extent. output dem should be handled as points. xres = extent.width() / (dem_width - 1) yres = extent.height() / (dem_height - 1) geotransform = [ extent.xMinimum() - xres / 2, xres, 0, extent.yMaximum() + yres / 2, 0, -yres ] # warp dem dem_values = warp_dem.read(dem_width, dem_height, wkt, geotransform) if mapTo3d.multiplierZ != 1: dem_values = map(lambda x: x * mapTo3d.multiplierZ, dem_values) if debug_mode: qDebug("Warped DEM: %d x %d, extent %s" % (dem_width, dem_height, str(geotransform))) # generate javascript data file planeWidth = mapTo3d.planeWidth * extent.width() / canvas.extent( ).width() planeHeight = mapTo3d.planeHeight * extent.height() / canvas.extent( ).height() offsetX = mapTo3d.planeWidth * ( extent.xMinimum() - canvas.extent().xMinimum() ) / canvas.extent().width() + planeWidth / 2 - mapTo3d.planeWidth / 2 offsetY = mapTo3d.planeHeight * ( extent.yMinimum() - canvas.extent().yMinimum()) / canvas.extent( ).height() + planeHeight / 2 - mapTo3d.planeHeight / 2 # value resampling on edges for combination with different resolution DEM neighbors = quadtree.neighbors(quad) #qDebug("Output quad (%d %s): height=%d" % (i, str(quad), quad.height)) for direction, neighbor in enumerate(neighbors): if neighbor is None: continue #qDebug(" neighbor %d %s: height=%d" % (direction, str(neighbor), neighbor.height)) interval = 2**(quad.height - neighbor.height) if interval > 1: if direction == QuadTree.UP or direction == QuadTree.DOWN: y = 0 if direction == QuadTree.UP else dem_height - 1 for x1 in range(interval, dem_width, interval): x0 = x1 - interval z0 = dem_values[x0 + dem_width * y] z1 = dem_values[x1 + dem_width * y] for xx in range(1, interval): z = (z0 * (interval - xx) + z1 * xx) / interval dem_values[x0 + xx + dem_width * y] = z else: # LEFT or RIGHT x = 0 if direction == QuadTree.LEFT else dem_width - 1 for y1 in range(interval, dem_height, interval): y0 = y1 - interval z0 = dem_values[x + dem_width * y0] z1 = dem_values[x + dem_width * y1] for yy in range(1, interval): z = (z0 * (interval - yy) + z1 * yy) / interval dem_values[x + dem_width * (y0 + yy)] = z if quad.height < quadtree.height or unites_center == False: writer.openFile(True) opt = "{width:%f,height:%f,offsetX:%f,offsetY:%f}" % ( planeWidth, planeHeight, offsetX, offsetY) writer.write( 'dem[%d] = {width:%d,height:%d,plane:%s,data:[%s]};\n' % (plane_index, dem_width, dem_height, opt, ",".join( map(gdal2threejs.formatValue, dem_values)))) writer.write('tex[%d] = "%s";\n' % (plane_index, tex)) plane_index += 1 else: centerQuads.addQuad(quad, dem_values) if unites_center: extent = centerQuads.extent() if hpw < 1: image_width = image_basesize * centerQuads.width() image_height = round(image_width * hpw) else: image_height = image_basesize * centerQuads.height() image_width = round(image_height * hpw) image = QImage(image_width, image_height, QImage.Format_ARGB32_Premultiplied) #qDebug("Created image size: %d, %d" % (image_width, image_height)) renderer.setOutputSize(image.size(), image.logicalDpiX()) renderer.setExtent(extent) # render map image image.fill(fillColor) painter.begin(image) if antialias: painter.setRenderHint(QPainter.Antialiasing) renderer.render(painter) painter.end() if context.localBrowsingMode: tex = tools.base64image(image) else: texfilename = os.path.splitext( htmlfilename)[0] + "_%d.png" % plane_index image.save(texfilename) tex = os.path.split(texfilename)[1] dem_values = centerQuads.unitedDEM() planeWidth = mapTo3d.planeWidth * extent.width() / canvas.extent( ).width() planeHeight = mapTo3d.planeHeight * extent.height() / canvas.extent( ).height() offsetX = mapTo3d.planeWidth * ( extent.xMinimum() - canvas.extent().xMinimum() ) / canvas.extent().width() + planeWidth / 2 - mapTo3d.planeWidth / 2 offsetY = mapTo3d.planeHeight * ( extent.yMinimum() - canvas.extent().yMinimum()) / canvas.extent( ).height() + planeHeight / 2 - mapTo3d.planeHeight / 2 dem_width = (dem_width - 1) * centerQuads.width() + 1 dem_height = (dem_height - 1) * centerQuads.height() + 1 writer.openFile(True) opt = "{width:%f,height:%f,offsetX:%f,offsetY:%f}" % ( planeWidth, planeHeight, offsetX, offsetY) writer.write('dem[%d] = {width:%d,height:%d,plane:%s,data:[%s]};\n' % (plane_index, dem_width, dem_height, opt, ",".join( map(gdal2threejs.formatValue, dem_values)))) writer.write('tex[%d] = "%s";\n' % (plane_index, tex)) plane_index += 1 progress(50) # vector data output writer.prepareNext() writeVectors(writer) progress(80) # copy files from template tools.copyThreejsFiles(out_dir) # generate html file with codecs.open(tools.pluginDir() + "/template.html", "r", "UTF-8") as f: html = f.read() with codecs.open(htmlfilename, "w", "UTF-8") as f: f.write( html.replace("${title}", filetitle).replace("${scripts}", writer.scripts())) return htmlfilename
def renderedImage(self, width, height, extent, transp_background=False, layerids=None): if QGis.QGIS_VERSION_INT < 20700: return self._renderedImage2(width, height, extent, transp_background, layerids) # render layers with QgsMapRendererCustomPainterJob from qgis.core import QgsMapRendererCustomPainterJob antialias = True settings = self.exportSettings.mapSettings # store old map settings old_outputSize = settings.outputSize() old_extent = settings.extent() old_rotation = settings.rotation() old_layerids = settings.layers() old_backgroundColor = settings.backgroundColor() # map settings settings.setOutputSize(QSize(width, height)) settings.setExtent(extent.unrotatedRect()) settings.setRotation(extent.rotation()) if layerids is not None: settings.setLayers(layerids) if transp_background: settings.setBackgroundColor(QColor(Qt.transparent)) #else: #TODO: remove #settings.setBackgroundColor(self.exportSettings.canvas.canvasColor()) has_pluginlayer = False for layerId in settings.layers(): layer = QgsMapLayerRegistry.instance().mapLayer(layerId) if layer and layer.type() == QgsMapLayer.PluginLayer: has_pluginlayer = True break # create an image image = QImage(width, height, QImage.Format_ARGB32_Premultiplied) painter = QPainter() painter.begin(image) if antialias: painter.setRenderHint(QPainter.Antialiasing) # rendering job = QgsMapRendererCustomPainterJob(settings, painter) if has_pluginlayer: job.renderSynchronously( ) # use this method so that TileLayerPlugin layer is rendered correctly else: job.start() job.waitForFinished() painter.end() # restore map settings settings.setOutputSize(old_outputSize) settings.setExtent(old_extent) settings.setRotation(old_rotation) settings.setLayers(old_layerids) settings.setBackgroundColor(old_backgroundColor) return tools.base64image(image)