Esempio n. 1
0
  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)
Esempio n. 2
0
  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)
Esempio n. 3
0
  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)
Esempio n. 4
0
  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)
Esempio n. 5
0
  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
Esempio n. 6
0
    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
Esempio n. 7
0
    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)
Esempio n. 8
0
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
Esempio n. 11
0
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
Esempio n. 13
0
    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)