예제 #1
0
    def test_build(self):
        with open('tests/square.wkb', 'rb') as f:
            wkb = f.read()
        with open('tests/squareUV.wkb', 'rb') as f:
            wkbuv = f.read()
        ts = TriangleSoup.from_wkb_multipolygon(wkb, [wkbuv])
        positions = ts.getPositionArray()
        normals = ts.getNormalArray()
        uvs = ts.getDataArray(0)
        box = [[0, 0, 0], [10, 10, 0]]
        arrays = [{
            'position': positions,
            'normal': normals[1],
            'uv': uvs,
            'bbox': box
        }]

        transform = np.array(
            [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]],
            dtype=float)
        transform = transform.flatten('F')
        glTF = GlTF.from_binary_arrays(arrays,
                                       transform,
                                       textureUri='squaretexture.jpg')
        t = B3dm.from_glTF(glTF)

        # get an array
        t.to_array()
        self.assertEqual(t.header.version, 1.0)
        self.assertEqual(t.header.tile_byte_length, 1492)
        self.assertEqual(t.header.ft_json_byte_length, 0)
        self.assertEqual(t.header.ft_bin_byte_length, 0)
        self.assertEqual(t.header.bt_json_byte_length, 0)
        self.assertEqual(t.header.bt_bin_byte_length, 0)
예제 #2
0
    def test_build(self):
        with open('tests/building.wkb', 'rb') as f:
            wkb = f.read()
        ts = TriangleSoup.from_wkb_multipolygon(wkb)
        positions = ts.getPositionArray()
        normals = ts.getNormalArray()
        box = [[-8.74748499994166, -7.35523200035095, -2.05385796777344],
               [8.8036420000717, 7.29930999968201, 2.05386103222656]]
        arrays = [{'position': positions, 'normal': normals[1], 'bbox': box}]

        transform = np.array([[1, 0, 0, 1842015.125], [0, 1, 0, 5177109.25],
                              [0, 0, 1, 247.87364196777344], [0, 0, 0, 1]],
                             dtype=float)
        # translation : 1842015.125, 5177109.25, 247.87364196777344
        transform = transform.flatten('F')
        glTF = GlTF.from_binary_arrays(arrays, transform)
        t = B3dm.from_glTF(glTF)

        # get an array
        t.to_array()
        self.assertEqual(t.header.version, 1.0)
        self.assertEqual(t.header.tile_byte_length, 2860)
        self.assertEqual(t.header.ft_json_byte_length, 0)
        self.assertEqual(t.header.ft_bin_byte_length, 0)
        self.assertEqual(t.header.bt_json_byte_length, 0)
        self.assertEqual(t.header.bt_bin_byte_length, 0)
예제 #3
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)
예제 #4
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)