Example #1
0
    def write(self, writer):
        mapTo3d = writer.settings.mapTo3d()

        writer.write("bl = lyr.addBlock({0}, {1});\n".format(
            pyobj2js(self.properties), pyobj2js(bool(self.clip_geometry))))
        writer.write("bl.data = [{0}];\n".format(",".join(
            map(gdal2threejs.formatValue, self.dem_values))))

        # clipped with polygon layer
        if self.clip_geometry:
            z_func = lambda x, y: 0
            transform_func = lambda x, y, z: mapTo3d.transform(x, y, z)

            geom = PolygonGeometry.fromQgsGeometry(self.clip_geometry, z_func,
                                                   transform_func)
            geom.splitPolygon(
                writer.triangleMesh(self.dem_width, self.dem_height))

            polygons = []
            for polygon in geom.polygons:
                bnds = []
                for boundary in polygon:
                    bnds.append(map(lambda pt: [pt.x, pt.y], boundary))
                polygons.append(bnds)

            writer.write("bl.clip = {};\n")
            writer.write("bl.clip.polygons = {0};\n".format(
                pyobj2js(polygons)))

            triangles = Triangles()
            polygons = []
            for polygon in geom.split_polygons:
                boundary = polygon[0]
                if len(polygon) == 1 and len(boundary) == 4:
                    # vertex order should be counter-clockwise
                    triangles.addTriangle(boundary[0], boundary[2],
                                          boundary[1])
                else:
                    bnds = [
                        map(lambda pt: [pt.x, pt.y], bnd) for bnd in polygon
                    ]
                    polygons.append(bnds)

            vf = {
                "v": map(lambda pt: [pt.x, pt.y], triangles.vertices),
                "f": triangles.faces
            }
            writer.write("bl.clip.triangles = {0};\n".format(pyobj2js(vf)))
            writer.write("bl.clip.split_polygons = {0};\n".format(
                pyobj2js(polygons)))
Example #2
0
  def writeBlock(quad_rect, extent, dem_width, dem_height, dem_values, image_width, image_height):
    # extent = baseExtent.subrectangle(rect)
    npt = baseExtent.normalizePoint(extent.center().x(), extent.center().y())
    block = {"width": dem_width, "height": dem_height}
    block["plane"] = {"width": quad_rect.width() * mapTo3d.planeWidth,
                      "height": quad_rect.height() * mapTo3d.planeHeight,
                      "offsetX": (npt.x() - 0.5) * mapTo3d.planeWidth,
                      "offsetY": (npt.y() - 0.5) * mapTo3d.planeHeight}

    # display type
    if properties.get("radioButton_MapCanvas", False):
      block["m"] = layer.materialManager.getMapImageIndex(image_width, image_height, extent, transparency, transp_background)

    elif properties.get("radioButton_LayerImage", False):
      block["m"] = layer.materialManager.getLayerImageIndex(layerImageIds, image_width, image_height, extent, transparency, transp_background)

    elif properties.get("radioButton_SolidColor", False):
      block["m"] = layer.materialManager.getMeshLambertIndex(properties["lineEdit_Color"], transparency, True)

    # shading (whether compute normals)
    if properties.get("checkBox_Shading", True):
      block["shading"] = True

    # write block
    writer.nextFile(True)
    writer.write("bl = lyr.addBlock({0});\n".format(pyobj2js(block)))
    writer.write("bl.data = [{0}];\n".format(",".join(map(gdal2threejs.formatValue, dem_values))))
Example #3
0
    def write(self, f, imageManager):
        if not len(self._list):
            return

        toMaterialType = {
            self.WIREFRAME: self.MESH_LAMBERT,
            self.MESH_LAMBERT_FLAT: self.MESH_LAMBERT,
            self.CANVAS_IMAGE: self.MESH_PHONG,
            self.MAP_IMAGE: self.MESH_PHONG,
            self.LAYER_IMAGE: self.MESH_PHONG,
            self.IMAGE_FILE: self.MESH_PHONG
        }

        for index, mat in enumerate(self._list):
            m = {"type": toMaterialType.get(mat[0], mat[0])}

            transp_background = False

            if mat[0] == self.CANVAS_IMAGE:
                transp_background = mat[1]
                m["i"] = imageManager.canvasImageIndex(transp_background)
            elif mat[0] == self.MAP_IMAGE:
                width, height, extent, transp_background = mat[1]
                m["i"] = imageManager.mapImageIndex(width, height, extent,
                                                    transp_background)
            elif mat[0] == self.LAYER_IMAGE:
                layerids, width, height, extent, transp_background = mat[1]
                m["i"] = imageManager.layerImageIndex(layerids, width, height,
                                                      extent,
                                                      transp_background)
            elif mat[0] in [self.IMAGE_FILE, self.SPRITE]:
                filepath, transp_background = mat[1]
                m["i"] = imageManager.imageIndex(filepath)
            else:
                m["c"] = mat[1]

            if transp_background:
                m["t"] = 1

            if mat[0] == self.WIREFRAME:
                m["w"] = 1

            if mat[0] == self.MESH_LAMBERT_FLAT:
                m["flat"] = 1

            transparency = mat[2]
            if transparency > 0:
                opacity = 1.0 - float(transparency) / 100
                m["o"] = opacity

            # double sides
            if mat[3]:
                m["ds"] = 1

            f.write(u"lyr.m[{0}] = {1};\n".format(
                index, tools.pyobj2js(m, quoteHex=False)))
Example #4
0
    def writeLayer(self, obj, fieldNames=None):
        self.currentLayerIndex = self.layerCount
        type2classprefix = {
            "dem": "DEM",
            "point": "Point",
            "line": "Line",
            "polygon": "Polygon"
        }
        self.write(u"\n// Layer {0}\n".format(self.currentLayerIndex))
        self.write(u"lyr = project.addLayer(new Q3D.{0}Layer({1}));\n".format(
            type2classprefix[obj["type"]], pyobj2js(obj)))
        # del obj["type"]

        if fieldNames is not None:
            self.write(u"lyr.a = {0};\n".format(pyobj2js(fieldNames)))
        self.layerCount += 1
        self.currentFeatureIndex = -1
        self.attrs = []
        return self.currentLayerIndex
  def writeLayer(self, obj, fieldNames=None):
    self.currentLayerIndex = self.layerCount
    type2classprefix = {"dem": "DEM", "point": "Point", "line": "Line", "polygon": "Polygon"}
    self.write(u"\n// Layer {0}\n".format(self.currentLayerIndex))
    self.write(u"lyr = project.addLayer(new Q3D.{0}Layer({1}));\n".format(type2classprefix[obj["type"]], pyobj2js(obj)))
    # del obj["type"]

    if fieldNames is not None:
      self.write(u"lyr.a = {0};\n".format(pyobj2js(fieldNames)))
    self.layerCount += 1
    self.currentFeatureIndex = -1
    self.attrs = []
    return self.currentLayerIndex
Example #6
0
  def write(self, f, imageManager):
    if not len(self._list):
      return

    toMaterialType = {self.WIREFRAME: self.MESH_LAMBERT,
                      self.MESH_LAMBERT_FLAT: self.MESH_LAMBERT,
                      self.CANVAS_IMAGE: self.MESH_PHONG,
                      self.MAP_IMAGE: self.MESH_PHONG,
                      self.LAYER_IMAGE: self.MESH_PHONG,
                      self.IMAGE_FILE: self.MESH_PHONG}

    for index, mat in enumerate(self._list):
      m = {"type": toMaterialType.get(mat[0], mat[0])}

      transp_background = False

      if mat[0] == self.CANVAS_IMAGE:
        transp_background = mat[1]
        m["i"] = imageManager.canvasImageIndex(transp_background)
      elif mat[0] == self.MAP_IMAGE:
        width, height, extent, transp_background = mat[1]
        m["i"] = imageManager.mapImageIndex(width, height, extent, transp_background)
      elif mat[0] == self.LAYER_IMAGE:
        layerids, width, height, extent, transp_background = mat[1]
        m["i"] = imageManager.layerImageIndex(layerids, width, height, extent, transp_background)
      elif mat[0] in [self.IMAGE_FILE, self.SPRITE]:
        filepath, transp_background = mat[1]
        m["i"] = imageManager.imageIndex(filepath)
      else:
        m["c"] = mat[1]

      if transp_background:
        m["t"] = 1

      if mat[0] == self.WIREFRAME:
        m["w"] = 1

      if mat[0] == self.MESH_LAMBERT_FLAT:
        m["flat"] = 1

      transparency = mat[2]
      if transparency > 0:
        opacity = 1.0 - float(transparency) / 100
        m["o"] = opacity

      # double sides
      if mat[3]:
        m["ds"] = 1

      f.write(u"lyr.m[{0}] = {1};\n".format(index, tools.pyobj2js(m, quoteHex=False)))
Example #7
0
  def write(self, writer):
    mapTo3d = writer.settings.mapTo3d

    writer.write("bl = lyr.addBlock({0}, {1});\n".format(pyobj2js(self.properties), pyobj2js(bool(self.clip_geometry))))
    writer.write("bl.data = [{0}];\n".format(",".join(map(gdal2threejs.formatValue, self.dem_values))))

    # clipped with polygon layer
    if self.clip_geometry:
      z_func = lambda x, y: 0
      transform_func = lambda x, y, z: mapTo3d.transform(x, y, z)

      geom = PolygonGeometry.fromQgsGeometry(self.clip_geometry, z_func, transform_func)
      geom.splitPolygon(writer.triangleMesh(self.dem_width, self.dem_height))

      polygons = []
      for polygon in geom.polygons:
        bnds = []
        for boundary in polygon:
          bnds.append(map(lambda pt: [pt.x, pt.y], boundary))
        polygons.append(bnds)

      writer.write("bl.clip = {};\n")
      writer.write("bl.clip.polygons = {0};\n".format(pyobj2js(polygons)))

      triangles = Triangles()
      polygons = []
      for polygon in geom.split_polygons:
        boundary = polygon[0]
        if len(polygon) == 1 and len(boundary) == 4:
          triangles.addTriangle(boundary[0], boundary[2], boundary[1])    # vertex order should be counter-clockwise
        else:
          bnds = [map(lambda pt: [pt.x, pt.y], bnd) for bnd in polygon]
          polygons.append(bnds)

      vf = {"v": map(lambda pt: [pt.x, pt.y], triangles.vertices), "f": triangles.faces}
      writer.write("bl.clip.triangles = {0};\n".format(pyobj2js(vf)))
      writer.write("bl.clip.split_polygons = {0};\n".format(pyobj2js(polygons)))
Example #8
0
  def writeProject(self):
    # write project information
    self.write(u"// Qgis2threejs Project\n")
    settings = self.settings
    extent = self.settings.baseExtent
    rect = extent.unrotatedRect()
    mapTo3d = self.settings.mapTo3d()
    wgs84Center = self.settings.wgs84Center()

    args = {"title": settings.title,
            "crs": unicode(settings.crs.authid()),
            "proj": settings.crs.toProj4(),
            "baseExtent": [rect.xMinimum(), rect.yMinimum(), rect.xMaximum(), rect.yMaximum()],
            "rotation": extent.rotation(),
            "width": mapTo3d.planeWidth,
            "zExaggeration": mapTo3d.verticalExaggeration,
            "zShift": mapTo3d.verticalShift,
            "wgs84Center": {"lat": wgs84Center.y(), "lon": wgs84Center.x()}}

    self.write(u"project = new Q3D.Project({0});\n".format(pyobj2js(args)))
  def writeProject(self):
    # write project information
    self.write(u"// Qgis2threejs Project\n")
    settings = self.settings
    extent = self.settings.baseExtent
    rect = extent.unrotatedRect()
    mapTo3d = self.settings.mapTo3d
    wgs84Center = self.settings.wgs84Center

    args = {"title": settings.title,
            "crs": unicode(settings.crs.authid()),
            "proj": settings.crs.toProj4(),
            "baseExtent": [rect.xMinimum(), rect.yMinimum(), rect.xMaximum(), rect.yMaximum()],
            "rotation": extent.rotation(),
            "width": mapTo3d.planeWidth,
            "zExaggeration": mapTo3d.verticalExaggeration,
            "zShift": mapTo3d.verticalShift,
            "wgs84Center": {"lat": wgs84Center.y(), "lon": wgs84Center.x()}}

    self.write(u"project = new Q3D.Project({0});\n".format(pyobj2js(args)))
Example #10
0
def writeSimpleDEM(writer, properties, progress=None):
  settings = writer.settings
  mapTo3d = settings.mapTo3d
  progress = progress or dummyProgress

  prop = DEMPropertyReader(properties)
  dem_width = prop.width()
  dem_height = prop.height()

  # warp dem
  demLayer = QgsMapLayerRegistry.instance().mapLayer(prop.layerId) if prop.layerId else None
  if demLayer:
    layerName = demLayer.name()
    warp_dem = MemoryWarpRaster(demLayer.source(), str(demLayer.crs().toWkt()), str(settings.crs.toWkt()))
  else:
    layerName = "Flat plane"
    warp_dem = FlatRaster()

  dem_values = warp_dem.read(dem_width, dem_height, settings.baseExtent.geotransform(dem_width, dem_height))

  # calculate statistics
  stats = {"max": max(dem_values), "min": min(dem_values)}

  # 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)

  surroundings = properties.get("checkBox_Surroundings", False) if demLayer else False
  if surroundings:
    roughenEdges(dem_width, dem_height, dem_values, properties["spinBox_Roughening"])

  # layer
  layer = DEMLayer(writer, demLayer, prop)
  lyr = layer.layerObject()
  lyr.update({"name": layerName, "stats": stats})
  lyrIdx = writer.writeLayer(lyr)

  # dem block
  block = {"width": dem_width, "height": dem_height}
  block["plane"] = {"width": mapTo3d.planeWidth, "height": mapTo3d.planeHeight, "offsetX": 0, "offsetY": 0}

  # material option
  transparency = properties["spinBox_demtransp"]
  transp_background = properties.get("checkBox_TransparentBackground", False)

  # display type
  if properties.get("radioButton_MapCanvas", False):
    block["m"] = layer.materialManager.getCanvasImageIndex(transparency, transp_background)

  elif properties.get("radioButton_LayerImage", False):
    layerids = properties.get("layerImageIds", [])
    size = settings.mapSettings.outputSize()
    block["m"] = layer.materialManager.getLayerImageIndex(layerids, size.width(), size.height(), settings.baseExtent, transparency, transp_background)

  elif properties.get("radioButton_ImageFile", False):
    filepath = properties.get("lineEdit_ImageFile", "")
    block["m"] = layer.materialManager.getImageFileIndex(filepath, transparency, transp_background, True)

  elif properties.get("radioButton_SolidColor", False):
    block["m"] = layer.materialManager.getMeshLambertIndex(properties["lineEdit_Color"], transparency, True)

  #elif properties.get("radioButton_Wireframe", False):
  #  block["m"] = layer.materialManager.getWireframeIndex(properties["lineEdit_Color"], transparency)

  # shading (whether compute normals)
  if properties.get("checkBox_Shading", True):
    block["shading"] = True

  if not surroundings and properties.get("checkBox_Sides", False):
    block["s"] = True

  if not surroundings and properties.get("checkBox_Frame", False):
    block["frame"] = True

  # write central block
  writer.write("bl = lyr.addBlock({0});\n".format(pyobj2js(block)))
  writer.write("bl.data = [{0}];\n".format(",".join(map(gdal2threejs.formatValue, dem_values))))

  # write surrounding dems
  if surroundings:
    writeSurroundingDEM(writer, layer, warp_dem, stats, properties, progress)
    # overwrite stats
    writer.write("lyr.stats = {0};\n".format(pyobj2js(stats)))

  writer.writeMaterials(layer.materialManager)
def writeMultiResDEM(writer, properties, progress=None):
  settings = writer.settings
  mapSettings = settings.mapSettings
  mapTo3d = settings.mapTo3d
  baseExtent = settings.baseExtent
  progress = progress or dummyProgress

  prop = DEMPropertyReader(properties)
  demLayer = QgsMapLayerRegistry.instance().mapLayer(prop.layerId)
  if demLayer is None:
    return

  # layer
  layer = DEMLayer(writer, demLayer, prop)
  lyrIdx = writer.writeLayer(layer.layerObject())

  warp_dem = MemoryWarpRaster(demLayer.source(), str(demLayer.crs().toWkt()), str(settings.crs.toWkt()))

  # quad tree
  quadtree = settings.quadtree
  if quadtree is None:
    return
  quads = quadtree.quads()

  # (currently) dem size is 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

  # material options
  transparency = properties["spinBox_demtransp"]
  transp_background = properties.get("checkBox_TransparentBackground", False)
  layerImageIds = properties.get("layerImageIds", [])

  # writeBlock function
  def writeBlock(quad_rect, extent, dem_width, dem_height, dem_values, image_width, image_height):
    # extent = baseExtent.subrectangle(rect)
    npt = baseExtent.normalizePoint(extent.center().x(), extent.center().y())
    block = {"width": dem_width, "height": dem_height}
    block["plane"] = {"width": quad_rect.width() * mapTo3d.planeWidth,
                      "height": quad_rect.height() * mapTo3d.planeHeight,
                      "offsetX": (npt.x() - 0.5) * mapTo3d.planeWidth,
                      "offsetY": (npt.y() - 0.5) * mapTo3d.planeHeight}

    # display type
    if properties.get("radioButton_MapCanvas", False):
      block["m"] = layer.materialManager.getMapImageIndex(image_width, image_height, extent, transparency, transp_background)

    elif properties.get("radioButton_LayerImage", False):
      block["m"] = layer.materialManager.getLayerImageIndex(layerImageIds, image_width, image_height, extent, transparency, transp_background)

    elif properties.get("radioButton_SolidColor", False):
      block["m"] = layer.materialManager.getMeshLambertIndex(properties["lineEdit_Color"], transparency, True)

    # write block
    writer.nextFile(True)
    writer.write("bl = lyr.addBlock({0});\n".format(pyobj2js(block)))
    writer.write("bl.data = [{0}];\n".format(",".join(map(gdal2threejs.formatValue, dem_values))))

  # image size
  canvas_size = mapSettings.outputSize()
  hpw = float(canvas_size.height()) / canvas_size.width()
  if hpw < 1:
    image_width = settings.image_basesize
    image_height = round(image_width * hpw)
  else:
    image_height = settings.image_basesize
    image_width = round(image_height / hpw)

  unites_center = True
  centerQuads = DEMQuadList(dem_width, dem_height)
  stats = None
  for i, quad in enumerate(quads):
    progress(30 * i / len(quads) + 5)

    # block extent
    rect = quad.rect
    extent = baseExtent.subrectangle(rect)

    # warp dem
    dem_values = warp_dem.read(dem_width, dem_height, extent.geotransform(dem_width, dem_height))
    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)

    # calculate DEM values on edges to combine with next DEM block with different resolution
    neighbors = quadtree.neighbors(quad)
    for direction, neighbor in enumerate(neighbors):
      if neighbor is None:
        continue
      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 unites_center and quad.height == quadtree.height:
      centerQuads.addQuad(quad, dem_values)
    else:
      writeBlock(rect, extent, dem_width, dem_height, dem_values, image_width, image_height)

  if unites_center:
    dem_width = (dem_width - 1) * centerQuads.width() + 1
    dem_height = (dem_height - 1) * centerQuads.height() + 1
    dem_values = centerQuads.unitedDEM()

    if hpw < 1:
      image_width = settings.image_basesize * centerQuads.width()
      image_height = round(image_width * hpw)
    else:
      image_height = settings.image_basesize * centerQuads.height()
      image_width = round(image_height / hpw)

    # block extent
    rect = centerQuads.rect()
    extent = baseExtent.subrectangle(rect)
    writeBlock(rect, extent, dem_width, dem_height, dem_values, image_width, image_height)

  writer.write("lyr.stats = {0};\n".format(pyobj2js(stats)))
  writer.writeMaterials(layer.materialManager)
def writeSurroundingDEM(writer, layer, warp_dem, stats, properties, progress=None):
  settings = writer.settings
  mapSettings = settings.mapSettings
  mapTo3d = settings.mapTo3d
  baseExtent = settings.baseExtent
  progress = progress or dummyProgress

  # options
  size = properties["spinBox_Size"]
  roughening = properties["spinBox_Roughening"]
  transparency = properties["spinBox_demtransp"]
  transp_background = properties.get("checkBox_TransparentBackground", False)

  prop = DEMPropertyReader(properties)
  dem_width = (prop.width() - 1) / roughening + 1
  dem_height = (prop.height() - 1) / roughening + 1

  # texture image size
  canvas_size = mapSettings.outputSize()
  hpw = float(canvas_size.height()) / canvas_size.width()
  if hpw < 1:
    image_width = settings.image_basesize
    image_height = round(image_width * hpw)
    #image_height = settings.image_basesize * max(1, int(round(1 / hpw)))    # not rendered expectedly
  else:
    image_height = settings.image_basesize
    image_width = round(image_height / hpw)

  center = baseExtent.center()
  rotation = baseExtent.rotation()

  size2 = size * size
  for i in range(size2):
    progress(20 * i / size2 + 10)
    if i == (size2 - 1) / 2:    # center (map canvas)
      continue

    # block extent
    sx = i % size - (size - 1) / 2
    sy = i / size - (size - 1) / 2
    block_center = QgsPoint(center.x() + sx * baseExtent.width(), center.y() + sy * baseExtent.height())
    extent = RotatedRect(block_center, baseExtent.width(), baseExtent.height()).rotate(rotation, center)

    # warp dem
    dem_values = warp_dem.read(dem_width, dem_height, extent.geotransform(dem_width, dem_height))

    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)

    # generate javascript data file
    # dem block
    block = {"width": dem_width, "height": dem_height}
    block["plane"] = {"width": mapTo3d.planeWidth, "height": mapTo3d.planeHeight,
                      "offsetX": mapTo3d.planeWidth * sx, "offsetY": mapTo3d.planeHeight * sy}

    # display type
    if properties.get("radioButton_MapCanvas", False):
      block["m"] = layer.materialManager.getMapImageIndex(image_width, image_height, extent, transparency, transp_background)

    elif properties.get("radioButton_LayerImage", False):
      layerids = properties.get("layerImageIds", [])
      block["m"] = layer.materialManager.getLayerImageIndex(layerids, image_width, image_height, extent, transparency, transp_background)

    elif properties.get("radioButton_SolidColor", False):
      block["m"] = layer.materialManager.getMeshLambertIndex(properties["lineEdit_Color"], transparency, True)

    # write block
    writer.write("bl = lyr.addBlock({0});\n".format(pyobj2js(block)))
    writer.write("bl.data = [{0}];\n".format(",".join(map(gdal2threejs.formatValue, dem_values))))
def writeSimpleDEM(writer, properties, progress=None):
  settings = writer.settings
  mapTo3d = settings.mapTo3d
  progress = progress or dummyProgress

  prop = DEMPropertyReader(properties)
  dem_width = prop.width()
  dem_height = prop.height()

  # warp dem
  demLayer = QgsMapLayerRegistry.instance().mapLayer(prop.layerId) if prop.layerId else None
  if demLayer:
    layerName = demLayer.name()
    warp_dem = MemoryWarpRaster(demLayer.source(), str(demLayer.crs().toWkt()), str(settings.crs.toWkt()))
  else:
    layerName = "Flat plane"
    warp_dem = FlatRaster()

  dem_values = warp_dem.read(dem_width, dem_height, settings.baseExtent.geotransform(dem_width, dem_height))

  # calculate statistics
  stats = {"max": max(dem_values), "min": min(dem_values)}

  # 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)

  surroundings = properties.get("checkBox_Surroundings", False) if demLayer else False
  if surroundings:
    roughenEdges(dem_width, dem_height, dem_values, properties["spinBox_Roughening"])

  # layer
  layer = DEMLayer(writer, demLayer, prop)
  lyr = layer.layerObject()
  lyr.update({"name": layerName, "stats": stats})
  lyrIdx = writer.writeLayer(lyr)

  # dem block
  block = {"width": dem_width, "height": dem_height}
  block["plane"] = {"width": mapTo3d.planeWidth, "height": mapTo3d.planeHeight, "offsetX": 0, "offsetY": 0}

  # material option
  transparency = properties["spinBox_demtransp"]
  transp_background = properties.get("checkBox_TransparentBackground", False)

  # display type
  if properties.get("radioButton_MapCanvas", False):
    block["m"] = layer.materialManager.getCanvasImageIndex(transparency, transp_background)

  elif properties.get("radioButton_LayerImage", False):
    layerids = properties.get("layerImageIds", [])
    size = settings.mapSettings.outputSize()
    block["m"] = layer.materialManager.getLayerImageIndex(layerids, size.width(), size.height(), settings.baseExtent, transparency, transp_background)

  elif properties.get("radioButton_ImageFile", False):
    filepath = properties.get("lineEdit_ImageFile", "")
    block["m"] = layer.materialManager.getImageFileIndex(filepath, transparency, transp_background, True)

  elif properties.get("radioButton_SolidColor", False):
    block["m"] = layer.materialManager.getMeshLambertIndex(properties["lineEdit_Color"], transparency, True)

  #elif properties.get("radioButton_Wireframe", False):
  #  block["m"] = layer.materialManager.getWireframeIndex(properties["lineEdit_Color"], transparency)

  clip_layer = None
  if not surroundings:
    # clipping option
    clip_option = properties.get("checkBox_Clip", False)
    if clip_option:
      clip_layerId = properties.get("comboBox_ClipLayer")
      clip_layer = QgsMapLayerRegistry.instance().mapLayer(clip_layerId) if clip_layerId else None

    if properties.get("checkBox_Sides", False):
      block["sides"] = True

    if properties.get("checkBox_Frame", False) and not clip_option:
      block["frame"] = True

  # write central block
  writer.write("bl = lyr.addBlock({0}, {1});\n".format(pyobj2js(block), pyobj2js(bool(clip_layer))))
  writer.write("bl.data = [{0}];\n".format(",".join(map(gdal2threejs.formatValue, dem_values))))

  # clipped with polygon layer
  if clip_layer:
    geometry = dissolvePolygonsOnCanvas(writer, clip_layer)
    z_func = lambda x, y: 0
    transform_func = lambda x, y, z: mapTo3d.transform(x, y, z)

    geom = PolygonGeometry.fromQgsGeometry(geometry, z_func, transform_func)
    geom.splitPolygon(writer.triangleMesh(dem_width, dem_height))

    polygons = []
    for polygon in geom.polygons:
      bnds = []
      for boundary in polygon:
        bnds.append(map(lambda pt: [pt.x, pt.y], boundary))
      polygons.append(bnds)

    writer.write("bl.clip = {};\n")
    writer.write("bl.clip.polygons = {0};\n".format(pyobj2js(polygons)))

    triangles = Triangles()
    polygons = []
    for polygon in geom.split_polygons:
      boundary = polygon[0]
      if len(polygon) == 1 and len(boundary) == 4:
        triangles.addTriangle(boundary[0], boundary[2], boundary[1])    # vertex order should be counter-clockwise
      else:
        bnds = [map(lambda pt: [pt.x, pt.y], bnd) for bnd in polygon]
        polygons.append(bnds)

    vf = {"v": map(lambda pt: [pt.x, pt.y], triangles.vertices), "f": triangles.faces}
    writer.write("bl.clip.triangles = {0};\n".format(pyobj2js(vf)))
    writer.write("bl.clip.split_polygons = {0};\n".format(pyobj2js(polygons)))

  # write surrounding dems
  if surroundings:
    writeSurroundingDEM(writer, layer, warp_dem, stats, properties, progress)
    # overwrite stats
    writer.write("lyr.stats = {0};\n".format(pyobj2js(stats)))

  writer.writeMaterials(layer.materialManager)
 def writeAttributes(self):
   for index, attrs in enumerate(self.attrs):
     self.write(u"lyr.f[{0}].a = {1};\n".format(index, pyobj2js(attrs, True)))
 def writeFeature(self, f):
   self.currentFeatureIndex += 1
   self.write(u"lyr.f[{0}] = {1};\n".format(self.currentFeatureIndex, pyobj2js(f)))
Example #16
0
 def writeFeature(self, f):
     self.currentFeatureIndex += 1
     self.write(u"lyr.f[{0}] = {1};\n".format(self.currentFeatureIndex,
                                              pyobj2js(f)))
Example #17
0
 def writeAttributes(self):
     for index, attrs in enumerate(self.attrs):
         self.write(u"lyr.f[{0}].a = {1};\n".format(index,
                                                    pyobj2js(attrs, True)))
Example #18
0
def writeMultiResDEM(writer, properties, progress=None):
  settings = writer.settings
  mapSettings = settings.mapSettings
  mapTo3d = settings.mapTo3d
  baseExtent = settings.baseExtent
  progress = progress or dummyProgress

  prop = DEMPropertyReader(properties)

  # DEM provider
  provider = settings.demProviderByLayerId(prop.layerId)
  if isinstance(provider, GDALDEMProvider):
    demLayer = QgsMapLayerRegistry.instance().mapLayer(prop.layerId)
    layerName = demLayer.name()
  else:
    demLayer = None
    layerName = provider.name()

  # layer
  layer = DEMLayer(writer, demLayer, prop)
  lyr = layer.layerObject()
  lyr.update({"name": layerName})
  lyrIdx = writer.writeLayer(lyr)

  # quad tree
  quadtree = settings.quadtree
  if quadtree is None:
    return

  # (currently) dem size is 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

  # material options
  texture_scale = properties["comboBox_TextureSize"] / 100
  transparency = properties["spinBox_demtransp"]
  transp_background = properties.get("checkBox_TransparentBackground", False)
  layerImageIds = properties.get("layerImageIds", [])

  def materialIndex(extent, image_width, image_height):
    # display type
    if properties.get("radioButton_MapCanvas", False):
      return layer.materialManager.getMapImageIndex(image_width, image_height, extent, transparency, transp_background)

    elif properties.get("radioButton_LayerImage", False):
      return layer.materialManager.getLayerImageIndex(layerImageIds, image_width, image_height, extent, transparency, transp_background)

    else:   #.get("radioButton_SolidColor", False)
      return layer.materialManager.getMeshLambertIndex(properties["lineEdit_Color"], transparency, True)

  blocks = DEMBlocks()
  def addDEMBlock(quad_rect, dem_width, dem_height, dem_values, image_width, image_height):
    planeWidth = quad_rect.width() * mapTo3d.planeWidth
    planeHeight = quad_rect.height() * mapTo3d.planeHeight
    extent = baseExtent.subrectangle(quad_rect)
    npt = baseExtent.normalizePoint(extent.center().x(), extent.center().y())
    offsetX = (npt.x() - 0.5) * mapTo3d.planeWidth
    offsetY = (npt.y() - 0.5) * mapTo3d.planeHeight

    block = DEMBlock(dem_width, dem_height, dem_values, planeWidth, planeHeight, offsetX, offsetY)
    #block.zShift(mapTo3d.verticalShift)
    #block.zScale(mapTo3d.multiplierZ)
    block.set("m", materialIndex(extent, image_width, image_height))

    blocks.appendBlock(block)

  # image size
  canvas_size = mapSettings.outputSize()
  image_width = canvas_size.width() * texture_scale
  image_height = canvas_size.height() * texture_scale

  quads = quadtree.quads()
  unites_center = True
  centerQuads = DEMQuadList(dem_width, dem_height)
  stats = None
  for i, quad in enumerate(quads):
    progress(15 * i / len(quads) + 5)

    # block extent
    extent = baseExtent.subrectangle(quad.rect)

    # warp dem
    dem_values = provider.read(dem_width, dem_height, extent)

    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)

    quad.setData(dem_width, dem_height, dem_values)

  # process edges to eliminate opening between blocks
  quadtree.processEdges()

  for i, quad in enumerate(quads):
    progress(15 * i / len(quads) + 20)

    if unites_center and quad.height == quadtree.height:
      centerQuads.addQuad(quad)
    else:
      addDEMBlock(quad.rect, quad.dem_width, quad.dem_height, quad.dem_values, image_width, image_height)

  if unites_center:
    dem_width = (dem_width - 1) * centerQuads.width() + 1
    dem_height = (dem_height - 1) * centerQuads.height() + 1
    dem_values = centerQuads.unitedDEM()

    image_width *= centerQuads.width()
    image_height *= centerQuads.height()

    addDEMBlock(centerQuads.rect(), dem_width, dem_height, dem_values, image_width, image_height)

  blocks.write(writer, separated=True)

  writer.write("lyr.stats = {0};\n".format(pyobj2js(stats)))
  writer.writeMaterials(layer.materialManager)
Example #19
0
def writeSimpleDEM(writer, properties, progress=None):
  settings = writer.settings
  mapTo3d = settings.mapTo3d
  progress = progress or dummyProgress

  prop = DEMPropertyReader(properties)

  # DEM provider
  provider = settings.demProviderByLayerId(prop.layerId)
  if isinstance(provider, GDALDEMProvider):
    demLayer = QgsMapLayerRegistry.instance().mapLayer(prop.layerId)
    layerName = demLayer.name()
  else:
    demLayer = None
    layerName = provider.name()

  # layer
  layer = DEMLayer(writer, demLayer, prop)
  lyr = layer.layerObject()
  lyr.update({"name": layerName})
  lyrIdx = writer.writeLayer(lyr)

  # material option
  texture_scale = properties["comboBox_TextureSize"] / 100
  transparency = properties["spinBox_demtransp"]
  transp_background = properties.get("checkBox_TransparentBackground", False)

  # display type
  canvas_size = settings.mapSettings.outputSize()
  if properties.get("radioButton_MapCanvas", False):
    if texture_scale == 1:
      mat = layer.materialManager.getCanvasImageIndex(transparency, transp_background)
    else:
      mat = layer.materialManager.getMapImageIndex(canvas_size.width() * texture_scale, canvas_size.height() * texture_scale, settings.baseExtent, transparency, transp_background)

  elif properties.get("radioButton_LayerImage", False):
    layerids = properties.get("layerImageIds", [])
    mat = layer.materialManager.getLayerImageIndex(layerids, canvas_size.width() * texture_scale, canvas_size.height() * texture_scale, settings.baseExtent, transparency, transp_background)

  elif properties.get("radioButton_ImageFile", False):
    filepath = properties.get("lineEdit_ImageFile", "")
    mat = layer.materialManager.getImageFileIndex(filepath, transparency, transp_background, True)

  else:   #.get("radioButton_SolidColor", False)
    mat = layer.materialManager.getMeshLambertIndex(properties["lineEdit_Color"], transparency, True)

  #elif properties.get("radioButton_Wireframe", False):
  #  block["m"] = layer.materialManager.getWireframeIndex(properties["lineEdit_Color"], transparency)

  # get DEM values
  dem_width, dem_height = prop.width(), prop.height()
  dem_values = provider.read(dem_width, dem_height, settings.baseExtent)

  # DEM block
  block = DEMBlock(dem_width, dem_height, dem_values, mapTo3d.planeWidth, mapTo3d.planeHeight, 0, 0)
  block.zShift(mapTo3d.verticalShift)
  block.zScale(mapTo3d.multiplierZ)
  block.set("m", mat)

  surroundings = properties.get("checkBox_Surroundings", False) if prop.layerId else False
  if surroundings:
    blocks = DEMBlocks()
    blocks.appendBlock(block)
    blocks.appendBlocks(surroundingDEMBlocks(writer, layer, provider, properties, progress))
    blocks.processEdges()
    blocks.write(writer)

    writer.write("lyr.stats = {0};\n".format(pyobj2js(blocks.stats())))

  else:
    # clipping
    if properties.get("checkBox_Clip", False):
      clip_layerId = properties.get("comboBox_ClipLayer")
      clip_layer = QgsMapLayerRegistry.instance().mapLayer(clip_layerId) if clip_layerId else None
      if clip_layer:
        block.setClipGeometry(dissolvePolygonsOnCanvas(writer, clip_layer))

    # sides and bottom
    if properties.get("checkBox_Sides", False):
      block.set("sides", True)

    # frame
    if properties.get("checkBox_Frame", False) and not clip_option:
      block.set("frame", True)

    block.write(writer)

    writer.write("lyr.stats = {0};\n".format(pyobj2js(block.orig_stats)))

  # materials
  writer.writeMaterials(layer.materialManager)
Example #20
0
def writeMultiResDEM(writer, properties, progress=None):
    settings = writer.settings
    mapSettings = settings.mapSettings
    mapTo3d = settings.mapTo3d()
    baseExtent = settings.baseExtent
    progress = progress or dummyProgress

    prop = DEMPropertyReader(properties)

    # DEM provider
    provider = settings.demProviderByLayerId(prop.layerId)
    if isinstance(provider, GDALDEMProvider):
        demLayer = QgsMapLayerRegistry.instance().mapLayer(prop.layerId)
        layerName = demLayer.name()
    else:
        demLayer = None
        layerName = provider.name()

    # layer
    layer = DEMLayer(writer, demLayer, prop)
    lyr = layer.layerObject()
    lyr.update({"name": layerName})
    writer.writeLayer(lyr)

    # quad tree
    quadtree = settings.quadtree()
    if quadtree is None:
        return

    # (currently) dem size is 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

    # material options
    texture_scale = properties.get("comboBox_TextureSize", 100) / 100
    transparency = properties.get("spinBox_demtransp", 0)
    transp_background = properties.get("checkBox_TransparentBackground", False)
    layerImageIds = properties.get("layerImageIds", [])

    def materialIndex(extent, image_width, image_height):
        # display type
        if properties.get("radioButton_MapCanvas", False):
            return layer.materialManager.getMapImageIndex(
                image_width, image_height, extent, transparency,
                transp_background)

        elif properties.get("radioButton_LayerImage", False):
            return layer.materialManager.getLayerImageIndex(
                layerImageIds, image_width, image_height, extent, transparency,
                transp_background)

        else:  # .get("radioButton_SolidColor", False)
            return layer.materialManager.getMeshLambertIndex(
                properties.get("lineEdit_Color", ""), transparency, True)

    blocks = DEMBlocks()

    def addDEMBlock(quad_rect, dem_width, dem_height, dem_values, image_width,
                    image_height):
        planeWidth = quad_rect.width() * mapTo3d.planeWidth
        planeHeight = quad_rect.height() * mapTo3d.planeHeight
        extent = baseExtent.subrectangle(quad_rect)
        npt = baseExtent.normalizePoint(extent.center().x(),
                                        extent.center().y())
        offsetX = (npt.x() - 0.5) * mapTo3d.planeWidth
        offsetY = (npt.y() - 0.5) * mapTo3d.planeHeight

        block = DEMBlock(dem_width, dem_height, dem_values, planeWidth,
                         planeHeight, offsetX, offsetY)
        # block.zShift(mapTo3d.verticalShift)
        # block.zScale(mapTo3d.multiplierZ)
        block.set("m", materialIndex(extent, image_width, image_height))

        blocks.appendBlock(block)

    # image size
    canvas_size = mapSettings.outputSize()
    image_width = canvas_size.width() * texture_scale
    image_height = canvas_size.height() * texture_scale

    quads = quadtree.quads()
    unites_center = True
    centerQuads = DEMQuadList(dem_width, dem_height)
    stats = None
    for i, quad in enumerate(quads):
        progress(15 * i / len(quads) + 5)

        # block extent
        extent = baseExtent.subrectangle(quad.rect)

        # warp dem
        dem_values = provider.read(dem_width, dem_height, extent)

        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)

        quad.setData(dem_width, dem_height, dem_values)

    # process edges to eliminate opening between blocks
    quadtree.processEdges()

    for i, quad in enumerate(quads):
        progress(15 * i / len(quads) + 20)

        if unites_center and quad.height == quadtree.height:
            centerQuads.addQuad(quad)
        else:
            addDEMBlock(quad.rect, quad.dem_width, quad.dem_height,
                        quad.dem_values, image_width, image_height)

    if unites_center:
        dem_width = (dem_width - 1) * centerQuads.width() + 1
        dem_height = (dem_height - 1) * centerQuads.height() + 1
        dem_values = centerQuads.unitedDEM()

        image_width *= centerQuads.width()
        image_height *= centerQuads.height()

        addDEMBlock(centerQuads.rect(), dem_width, dem_height, dem_values,
                    image_width, image_height)

    blocks.write(writer, separated=True)

    writer.write("lyr.stats = {0};\n".format(pyobj2js(stats)))
    writer.writeMaterials(layer.materialManager)
Example #21
0
def writeSimpleDEM(writer, properties, progress=None):
    settings = writer.settings
    mapTo3d = settings.mapTo3d()
    progress = progress or dummyProgress

    prop = DEMPropertyReader(properties)

    # DEM provider
    provider = settings.demProviderByLayerId(prop.layerId)
    if isinstance(provider, GDALDEMProvider):
        demLayer = QgsMapLayerRegistry.instance().mapLayer(prop.layerId)
        layerName = demLayer.name()
    else:
        demLayer = None
        layerName = provider.name()

    # layer
    layer = DEMLayer(writer, demLayer, prop)
    lyr = layer.layerObject()
    lyr.update({"name": layerName})
    writer.writeLayer(lyr)

    # material option
    texture_scale = properties.get("comboBox_TextureSize", 100) / 100
    transparency = properties.get("spinBox_demtransp", 0)
    transp_background = properties.get("checkBox_TransparentBackground", False)

    # display type
    canvas_size = settings.mapSettings.outputSize()
    if properties.get("radioButton_MapCanvas", False):
        if texture_scale == 1:
            mat = layer.materialManager.getCanvasImageIndex(
                transparency, transp_background)
        else:
            mat = layer.materialManager.getMapImageIndex(
                canvas_size.width() * texture_scale,
                canvas_size.height() * texture_scale, settings.baseExtent,
                transparency, transp_background)

    elif properties.get("radioButton_LayerImage", False):
        layerids = properties.get("layerImageIds", [])
        mat = layer.materialManager.getLayerImageIndex(
            layerids,
            canvas_size.width() * texture_scale,
            canvas_size.height() * texture_scale, settings.baseExtent,
            transparency, transp_background)

    elif properties.get("radioButton_ImageFile", False):
        filepath = properties.get("lineEdit_ImageFile", "")
        mat = layer.materialManager.getImageFileIndex(filepath, transparency,
                                                      transp_background, True)

    else:  # .get("radioButton_SolidColor", False)
        mat = layer.materialManager.getMeshLambertIndex(
            properties.get("lineEdit_Color", ""), transparency, True)

    # elif properties.get("radioButton_Wireframe", False):
    #  block["m"] = layer.materialManager.getWireframeIndex(properties["lineEdit_Color"], transparency)

    # get DEM values
    dem_size = prop.demSize(settings.mapSettings.outputSize())
    dem_width, dem_height = dem_size.width(), dem_size.height()
    dem_values = provider.read(dem_width, dem_height, settings.baseExtent)

    # DEM block
    block = DEMBlock(dem_width, dem_height, dem_values, mapTo3d.planeWidth,
                     mapTo3d.planeHeight, 0, 0)
    block.zShift(mapTo3d.verticalShift)
    block.zScale(mapTo3d.multiplierZ)
    block.set("m", mat)

    surroundings = properties.get("checkBox_Surroundings",
                                  False) if prop.layerId else False
    if surroundings:
        blocks = DEMBlocks()
        blocks.appendBlock(block)
        blocks.appendBlocks(
            surroundingDEMBlocks(writer, layer, provider, properties,
                                 progress))
        blocks.processEdges()
        blocks.write(writer)

        writer.write("lyr.stats = {0};\n".format(pyobj2js(blocks.stats())))

    else:
        # clipping
        clip_option = properties.get("checkBox_Clip", False)
        if clip_option:
            clip_layerId = properties.get("comboBox_ClipLayer")
            clip_layer = QgsMapLayerRegistry.instance().mapLayer(
                clip_layerId) if clip_layerId else None
            if clip_layer:
                block.setClipGeometry(
                    dissolvePolygonsOnCanvas(writer, clip_layer))

        # sides and bottom
        if properties.get("checkBox_Sides", False):
            block.set("sides", True)

        # frame
        if properties.get("checkBox_Frame", False) and not clip_option:
            block.set("frame", True)

        block.write(writer)

        writer.write("lyr.stats = {0};\n".format(pyobj2js(block.orig_stats)))

    # materials
    writer.writeMaterials(layer.materialManager)