def exportToThreeJS(htmlfilename, context, progress=None): mapTo3d = context.mapTo3d canvas = context.canvas extent = canvas.extent() if progress is None: progress = dummyProgress temp_dir = QDir.tempPath() #TODO: do in JSWriter? 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] demProperties = context.properties[ObjectTreeItem.ITEM_DEM] isSimpleMode = demProperties.get("radioButton_Simple", False) # create JavaScript writer object writer = JSWriter(htmlfilename, context) writer.openFile(not isSimpleMode) writer.writeWorldInfo() progress(5) #TODO writer.timestamp = timestamp # write primary DEM if isSimpleMode: writeSimpleDEM(writer, demProperties, progress) else: writeMultiResDEM(writer, demProperties, progress) writer.prepareNext() # write additional DEM(s) primaryDEMLayerId = demProperties["comboBox_DEMLayer"] for layerId, properties in context.properties[ObjectTreeItem.ITEM_OPTDEM].iteritems(): if layerId != primaryDEMLayerId and properties.get("visible", False): writeSimpleDEM(writer, properties) progress(50) # write vector data writeVectors(writer) progress(80) # copy three.js files tools.copyThreejsFiles(out_dir, context.controls) # copy additional library files templatePath = os.path.join(tools.templateDir(), context.templateName) metadata = tools.getTemplateMetadata(templatePath) tools.copyLibraries(out_dir, metadata) # generate html file with codecs.open(templatePath, "r", "UTF-8") as f: html = f.read() with codecs.open(htmlfilename, "w", "UTF-8") as f: f.write(html.replace("${title}", filetitle).replace("${controls}", '<script src="./threejs/%s"></script>' % context.controls).replace("${options}", writer.options()).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 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 runSimple(htmlfilename, context, progress=None): mapTo3d = context.mapTo3d canvas = context.canvas extent = canvas.extent() demlayer = QgsMapLayerRegistry().instance().mapLayer(context.demlayerid) if progress is None: progress = dummyProgress 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] # save map canvas image if context.localBrowsingMode: texfilename = os.path.join(temp_dir, "tex%s.png" % (timestamp)) canvas.saveAsImage(texfilename) tex = gdal2threejs.base64image(texfilename) tools.removeTemporaryFiles([texfilename, texfilename + "w"]) else: texfilename = os.path.splitext(htmlfilename)[0] + ".png" canvas.saveAsImage(texfilename) tex = os.path.split(texfilename)[1] tools.removeTemporaryFiles([texfilename + "w"]) progress(20) # warp dem # calculate extent. output dem should be handled as points. xres = extent.width() / (context.dem_width - 1) yres = extent.height() / (context.dem_height - 1) geotransform = [extent.xMinimum() - xres / 2, xres, 0, extent.yMaximum() + yres / 2, 0, -yres] wkt = str(context.crs.toWkt()) warp_dem = tools.MemoryWarpRaster(demlayer.source().encode("UTF-8")) dem_values = warp_dem.read(context.dem_width, context.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" % (context.dem_width, context.dem_height, str(geotransform))) # create JavaScript writer object context.setWarpDem(warp_dem) writer = JSWriter(htmlfilename, context) writer.openFile() # write dem data offsetX = offsetY = 0 opt = "{width:%f,height:%f,offsetX:%f,offsetY:%f}" % (mapTo3d.planeWidth, mapTo3d.planeHeight, offsetX, offsetY) writer.write('dem[0] = {width:%d,height:%d,plane:%s,data:[%s]};\n' % (context.dem_width, context.dem_height, opt, ",".join(map(gdal2threejs.formatValue, dem_values)))) writer.write('tex[0] = "%s";\n' % tex) progress(50) # write vector data 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 runSimple(htmlfilename, context, progress=None): mapTo3d = context.mapTo3d canvas = context.canvas extent = canvas.extent() demlayer = QgsMapLayerRegistry().instance().mapLayer(context.demlayerid) if progress is None: progress = dummyProgress 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] # save map canvas image if context.localBrowsingMode: texfilename = os.path.join(temp_dir, "tex%s.png" % (timestamp)) canvas.saveAsImage(texfilename) tex = gdal2threejs.base64image(texfilename) tools.removeTemporaryFiles([texfilename, texfilename + "w"]) else: texfilename = os.path.splitext(htmlfilename)[0] + ".png" canvas.saveAsImage(texfilename) tex = os.path.split(texfilename)[1] tools.removeTemporaryFiles([texfilename + "w"]) progress(20) # warp dem # calculate extent. output dem should be handled as points. xres = extent.width() / (context.dem_width - 1) yres = extent.height() / (context.dem_height - 1) geotransform = [ extent.xMinimum() - xres / 2, xres, 0, extent.yMaximum() + yres / 2, 0, -yres ] wkt = str(context.crs.toWkt()) warp_dem = tools.MemoryWarpRaster(demlayer.source().encode("UTF-8")) dem_values = warp_dem.read(context.dem_width, context.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" % (context.dem_width, context.dem_height, str(geotransform))) # create JavaScript writer object context.setWarpDem(warp_dem) writer = JSWriter(htmlfilename, context) writer.openFile() # write dem data offsetX = offsetY = 0 opt = "{width:%f,height:%f,offsetX:%f,offsetY:%f}" % ( mapTo3d.planeWidth, mapTo3d.planeHeight, offsetX, offsetY) writer.write('dem[0] = {width:%d,height:%d,plane:%s,data:[%s]};\n' % (context.dem_width, context.dem_height, opt, ",".join( map(gdal2threejs.formatValue, dem_values)))) writer.write('tex[0] = "%s";\n' % tex) progress(50) # write vector data 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