示例#1
0
def arrays2tileset(positions, normals, bboxes, transform, ids=None):
    print("Creating tileset...")
    maxTileSize = 2000
    featuresPerTile = 20
    indices = [i for i in range(len(positions))]

    # glTF is Y-up, so to get the bounding boxes in the 3D tiles
    # coordinate system, we have to apply a Y-to-Z transform to the
    # glTF bounding boxes
    zUpBboxes = []
    for bbox in bboxes:
        tmp = m = bbox[0]
        M = bbox[1]
        m = [m[0], -m[2], m[1]]
        M = [M[0], -tmp[2], M[1]]
        zUpBboxes.append([m, M])

    # Compute extent
    xMin = yMin = float('inf')
    xMax = yMax = -float('inf')

    for bbox in zUpBboxes:
        xMin = min(xMin, bbox[0][0])
        yMin = min(yMin, bbox[0][1])
        xMax = max(xMax, bbox[1][0])
        yMax = max(yMax, bbox[1][1])
    extent = BoundingBox([xMin, yMin], [xMax, yMax])
    extentX = xMax - xMin
    extentY = yMax - yMin

    # Create quadtree
    tree = Node()
    for i in range(0, int(math.ceil(extentX / maxTileSize))):
        for j in range(0, int(math.ceil(extentY / maxTileSize))):
            tile = tile_extent(extent, maxTileSize, i, j)

            geoms = []
            for idx, box in zip(indices, zUpBboxes):
                bbox = BoundingBox(box[0], box[1])

                if tile.inside(bbox.center()):
                    geoms.append(Feature(idx, bbox))

            if len(geoms) == 0:
                continue

            if len(geoms) > featuresPerTile:
                node = Node(geoms[0:featuresPerTile])
                tree.add(node)
                divide(tile, geoms[featuresPerTile:len(geoms)], i * 2, j * 2,
                       maxTileSize / 2., featuresPerTile, node)
            else:
                node = Node(geoms)
                tree.add(node)

    # Export b3dm & tileset
    tileset = tree.to_tileset(transform)
    f = open("tileset.json", 'w')
    f.write(json.dumps(tileset))
    print("Creating tiles...")
    nodes = tree.all_nodes()
    identity = np.identity(4).flatten('F')
    try:
        os.makedirs("tiles")
    except OSError as e:
        if e.errno != errno.EEXIST:
            raise
    for node in nodes:
        if len(node.features) != 0:
            binarrays = []
            gids = []
            for feature in node.features:
                pos = feature.index
                binarrays.append({
                    'position':
                    positions[pos],
                    'normal':
                    normals[pos],
                    'bbox': [[float(i) for i in j] for j in bboxes[pos]],
                })
                if ids is not None:
                    gids.append(ids[pos])
            gltf = GlTF.from_binary_arrays(binarrays, identity)
            bt = None
            if ids is not None:
                bt = BatchTable()
                bt.add_property_from_array("id", gids)
            b3dm = B3dm.from_glTF(gltf, bt).to_array()
            f = open("tiles/{0}.b3dm".format(node.id), 'wb')
            f.write(b3dm)
示例#2
0
def arrays2tileset(positions,
                   normals,
                   bboxes,
                   bboxesNonRotated,
                   transform,
                   ids=None,
                   doubleSided=False,
                   layerId=None):
    print("Creating tileset...")
    maxTileSize = 2000
    indices = [i for i in range(len(positions))]

    # Compute extent
    xMin = yMin = float('inf')
    xMax = yMax = -float('inf')

    for bbox in bboxesNonRotated:
        xMin = min(xMin, bbox[0][0])
        yMin = min(yMin, bbox[0][1])
        xMax = max(xMax, bbox[1][0])
        yMax = max(yMax, bbox[1][1])

    extent = BoundingBox([xMin, yMin], [xMax, yMax])
    extentX = xMax - xMin
    extentY = yMax - yMin

    # Create quadtree
    tree = Node()
    tilesArr = []
    for i in range(0, int(math.ceil(extentX / maxTileSize))):
        for j in range(0, int(math.ceil(extentY / maxTileSize))):
            tile = tile_extent(extent, maxTileSize, i, j)

            for idx, box in zip(indices, bboxesNonRotated):
                bbox = BoundingBox(box[0], box[1])

                if tile.inside(bbox.center()):
                    tilesArr.append([idx, Feature(idx, bbox)])

    # Sort geoms by id before creating the b3dm and tileset
    npTiles = np.asarray(tilesArr)
    npTiles = npTiles[np.argsort(npTiles[:, 0])]
    for npTile in npTiles:
        node = Node([npTile[1]])
        tree.add(node)

    # Export b3dm & tileset
    tileset = tree.to_tileset(transform, layerId=layerId)
    f = open("tileset.json".format(node.id), 'w')
    f.write(json.dumps(tileset))
    print("Creating tiles...")
    nodes = tree.all_nodes()
    identity = np.identity(4).flatten('F')
    try:
        os.makedirs("tiles")
    except OSError as e:
        if e.errno != errno.EEXIST:
            raise
    for node in nodes:
        if len(node.features) != 0:
            binarrays = []
            gids = []
            for feature in node.features:
                pos = feature.index
                binarrays.append({
                    'position':
                    positions[pos],
                    'normal':
                    normals[pos][1],
                    'bbox': [[float(i) for i in j] for j in bboxes[pos]],
                })
                if ids is not None:
                    gids.append(ids[pos])
            gltf = GlTF.from_binary_arrays(binarrays,
                                           identity,
                                           doubleSided=doubleSided,
                                           nMaxMin=normals[pos][0])
            bt = None
            if ids is not None:
                ft = FeatureTable()
                ft.add_property_from_value("BATCH_LENGTH", len(gids))

                bt = BatchTable()
                bt.add_property_from_array("id", gids)

            b3dm = B3dm.from_glTF(gltf, bt=bt, ft=ft).to_array()
            f = open("tiles/{0}.b3dm".format(node.id), 'wb')
            f.write(b3dm)