def write(writer, layer, feat): mapTo3d = writer.settings.mapTo3d() vals = feat.propValues() mat = layer.materialManager.getMeshLambertIndex(vals[0], vals[1]) pts = feat.geom.asList() if feat.prop.type_index == 0: # Sphere r = float(vals[2]) * mapTo3d.multiplier if r: writer.writeFeature({"m": mat, "pts": pts, "r": r}) else: logMessage(u"Sphere with zero radius not exported") elif feat.prop.type_index in [1, 2]: # Cylinder, Cone rb = float(vals[2]) * mapTo3d.multiplier rt = 0 if feat.prop.type_index == 2 else rb h = float(vals[3]) * mapTo3d.multiplierZ writer.writeFeature({"m": mat, "pts": pts, "rt": rt, "rb": rb, "h": h, "rotateX": 90}) elif feat.prop.type_index == 3: # Box w = float(vals[2]) * mapTo3d.multiplier d = float(vals[3]) * mapTo3d.multiplier h = float(vals[4]) * mapTo3d.multiplierZ writer.writeFeature({"m": mat, "pts": pts, "w": w, "d": d, "h": h, "rotateX": 90}) elif feat.prop.type_index == 4: # Disk r = float(vals[2]) * mapTo3d.multiplier d = float(vals[3]) dd = float(vals[4]) # take map rotation into account rotation = writer.settings.baseExtent.rotation() if rotation: dd = (dd + rotation) % 360 writer.writeFeature({"m": mat, "pts": pts, "r": r, "d": d, "dd": dd})
def getDataset(self, xmin, ymin, xmax, ymax, mapUnitsPerPixel): # calculate zoom level mpp1 = TSIZE1 / TILE_SIZE zoom = int(math.ceil(math.log(mpp1 / mapUnitsPerPixel, 2) + 1)) zoom = max(0, min(zoom, ZMAX)) # calculate tile range (yOrigin is top) size = TSIZE1 / 2**(zoom - 1) matrixSize = 2**zoom ulx = max(0, int((xmin + TSIZE1) / size)) uly = max(0, int((TSIZE1 - ymax) / size)) lrx = min(int((xmax + TSIZE1) / size), matrixSize - 1) lry = min(int((TSIZE1 - ymin) / size), matrixSize - 1) cols = lrx - ulx + 1 rows = lry - uly + 1 # download count limit if cols * rows > 128: logMessage("Number of tiles to fetch is too large!") width = height = 1 return self.driver.Create("", width, height, 1, gdal.GDT_Float32, []) if self.last_dataset and self.last_dataset[0] == [ zoom, ulx, uly, lrx, lry ]: # if same as last tile set, return cached dataset return self.last_dataset[1] urltmpl = "http://cyberjapandata.gsi.go.jp/xyz/dem/{z}/{x}/{y}.txt" #urltmpl = "http://localhost/xyz/dem/{z}/{x}/{y}.txt" tiles = self.fetchFiles(urltmpl, zoom, ulx, uly, lrx, lry) # create a memory dataset width = cols * TILE_SIZE height = rows * TILE_SIZE res = size / TILE_SIZE geotransform = [ ulx * size - TSIZE1, res, 0, TSIZE1 - uly * size, 0, -res ] #mem_driver = gdal.GetDriverByName("GTiff") #ds = mem_driver.Create("D:/fetched_tile.tif", width, height, 1, gdal.GDT_Float32, []) ds = self.driver.Create("", width, height, 1, gdal.GDT_Float32, []) ds.SetProjection(str(self.crs3857.toWkt())) ds.SetGeoTransform(geotransform) band = ds.GetRasterBand(1) for i, tile in enumerate(tiles): if tile: col = i % cols row = i // cols band.WriteRaster(col * TILE_SIZE, row * TILE_SIZE, TILE_SIZE, TILE_SIZE, tile) ds.FlushCache() self.last_dataset = [[zoom, ulx, uly, lrx, lry], ds] # cache dataset return ds
def getDataset(self, xmin, ymin, xmax, ymax, mapUnitsPerPixel): # calculate zoom level mpp1 = TSIZE1 / TILE_SIZE zoom = int(math.ceil(math.log(mpp1 / mapUnitsPerPixel, 2) + 1)) zoom = max(0, min(zoom, ZMAX)) # calculate tile range (yOrigin is top) size = TSIZE1 / 2 ** (zoom - 1) matrixSize = 2 ** zoom ulx = max(0, int((xmin + TSIZE1) / size)) uly = max(0, int((TSIZE1 - ymax) / size)) lrx = min(int((xmax + TSIZE1) / size), matrixSize - 1) lry = min(int((TSIZE1 - ymin) / size), matrixSize - 1) cols = lrx - ulx + 1 rows = lry - uly + 1 # download count limit if cols * rows > 128: logMessage("Number of tiles to fetch is too large!") width = height = 1 return self.driver.Create("", width, height, 1, gdal.GDT_Float32, []) if self.last_dataset and self.last_dataset[0] == [zoom, ulx, uly, lrx, lry]: # if same as last tile set, return cached dataset return self.last_dataset[1] urltmpl = "http://cyberjapandata.gsi.go.jp/xyz/dem/{z}/{x}/{y}.txt" #urltmpl = "http://localhost/xyz/dem/{z}/{x}/{y}.txt" tiles = self.fetchFiles(urltmpl, zoom, ulx, uly, lrx, lry) # create a memory dataset width = cols * TILE_SIZE height = rows * TILE_SIZE res = size / TILE_SIZE geotransform = [ulx * size - TSIZE1, res, 0, TSIZE1 - uly * size, 0, -res] #mem_driver = gdal.GetDriverByName("GTiff") #ds = mem_driver.Create("D:/fetched_tile.tif", width, height, 1, gdal.GDT_Float32, []) ds = self.driver.Create("", width, height, 1, gdal.GDT_Float32, []) ds.SetProjection(str(self.crs3857.toWkt())) ds.SetGeoTransform(geotransform) band = ds.GetRasterBand(1) for i, tile in enumerate(tiles): if tile: col = i % cols row = i / cols band.WriteRaster(col * TILE_SIZE, row * TILE_SIZE, TILE_SIZE, TILE_SIZE, tile) ds.FlushCache() self.last_dataset = [[zoom, ulx, uly, lrx, lry], ds] # cache dataset return ds
def write(writer, layer, feat): mapTo3d = writer.settings.mapTo3d() vals = feat.propValues() mat = layer.materialManager.getMeshLambertIndex(vals[0], vals[1]) pts = feat.geom.asList() if feat.prop.type_index == 0: # Sphere r = float(vals[2]) * mapTo3d.multiplier if r: writer.writeFeature({"m": mat, "pts": pts, "r": r}) else: logMessage(u"Sphere with zero radius not exported") elif feat.prop.type_index in [1, 2]: # Cylinder, Cone rb = float(vals[2]) * mapTo3d.multiplier rt = 0 if feat.prop.type_index == 2 else rb h = float(vals[3]) * mapTo3d.multiplierZ writer.writeFeature({ "m": mat, "pts": pts, "rt": rt, "rb": rb, "h": h, "rotateX": 90 }) elif feat.prop.type_index == 3: # Box w = float(vals[2]) * mapTo3d.multiplier d = float(vals[3]) * mapTo3d.multiplier h = float(vals[4]) * mapTo3d.multiplierZ writer.writeFeature({ "m": mat, "pts": pts, "w": w, "d": d, "h": h, "rotateX": 90 }) elif feat.prop.type_index == 4: # Disk r = float(vals[2]) * mapTo3d.multiplier d = float(vals[3]) dd = float(vals[4]) # take map rotation into account rotation = writer.settings.baseExtent.rotation() if rotation: dd = (dd + rotation) % 360 writer.writeFeature({"m": mat, "pts": pts, "r": r, "d": d, "dd": dd})
def __init__(self, dest_wkt): self.dest_wkt = dest_wkt # crs transformer, which aims to calculate bbox in EPSG:3857 self.crs3857 = QgsCoordinateReferenceSystem(3857) self.dest_crs = QgsCoordinateReferenceSystem() if not self.dest_crs.createFromWkt(dest_wkt): logMessage("Failed to create CRS from WKT: {0}".format(dest_wkt)) self.transform = QgsCoordinateTransform(self.dest_crs, self.crs3857, QgsProject.instance()) # approximate bbox of this data self.boundingbox = QgsRectangle(13667807, 2320477, 17230031, 5713298) self.downloader = Downloader() self.downloader.userAgent = "QGIS/{0} Qgis2threejs GSIElevTileProvider".format(Qgis.QGIS_VERSION_INT) # will be overwritten in QgsNetworkAccessManager::createRequest() since 2.2 self.downloader.DEFAULT_CACHE_EXPIRATION = QSettings().value("/qgis/defaultTileExpiry", 24, type=int) self.driver = gdal.GetDriverByName("MEM") self.last_dataset = None
def __init__(self, dest_wkt): self.dest_wkt = dest_wkt # crs transformer, which aims to calculate bbox in EPSG:3857 self.crs3857 = QgsCoordinateReferenceSystem(3857) self.dest_crs = QgsCoordinateReferenceSystem() if not self.dest_crs.createFromWkt(dest_wkt): logMessage("Failed to create CRS from WKT: {0}".format(dest_wkt)) self.transform = QgsCoordinateTransform(self.dest_crs, self.crs3857) # approximate bbox of this data self.boundingbox = QgsRectangle(13667807, 2320477, 17230031, 5713298) self.downloader = Downloader() self.downloader.userAgent = "QGIS/{0} Qgis2threejs GSIElevTileProvider".format(QGis.QGIS_VERSION) # not written since QGIS 2.2 self.downloader.DEFAULT_CACHE_EXPIRATION = QSettings().value("/qgis/defaultTileExpiry", 24, type=int) self.driver = gdal.GetDriverByName("MEM") self.last_dataset = None
def __init__(self, qgis_iface, pluginManager, settings=None): self.qgis_iface = qgis_iface self.pluginManager = pluginManager if settings is None: defaultSettings = {} settings = ExportSettings(pluginManager, True) settings.loadSettings(defaultSettings) settings.setMapCanvas(qgis_iface.mapCanvas()) err_msg = settings.checkValidity() if err_msg: logMessage(err_msg or "Invalid settings") self.settings = settings self.exporter = ThreeJSExporter(settings) self.iface = None self.enabled = True self.extentUpdated = False
def canvasExtentChanged(self): # update extent of export settings self.exportSettings.setMapCanvas(self.qgis_iface.mapCanvas()) self.iface.notify({"code": q3dconst.N_CANVAS_EXTENT_CHANGED}) logMessage("N_CANVAS_EXTENT_CHANGED notification sent")
def canvasUpdated(self, painter): self.iface.notify({"code": q3dconst.N_CANVAS_IMAGE_UPDATED}) logMessage("N_CANVAS_IMAGE_UPDATED notification sent")