Ejemplo n.º 1
0
def test_xyz():
    las = pylas.create()
    shape = (150, )
    las.X = np.zeros(shape, dtype=np.int32)
    las.Y = np.ones(shape, dtype=np.int32)
    las.Z = np.zeros(shape, dtype=np.int32)
    las.Z[:] = -152

    las = write_then_read_again(las)

    assert np.alltrue(las.X == 0)
    assert np.alltrue(las.Y == 1)
    assert np.alltrue(las.Z == -152)
Ejemplo n.º 2
0
def test_coords_when_setting_offsets_and_scales(las):
    new_las = pylas.create()

    new_las.header.offsets = las.header.offsets
    new_las.header.scales = las.header.scales

    new_las.x = las.x
    new_las.y = las.y
    new_las.z = las.z

    assert np.allclose(las.x, new_las.x)
    assert np.allclose(las.y, new_las.y)
    assert np.allclose(las.z, new_las.z)
Ejemplo n.º 3
0
def test_create_fmt_0():
    new = pylas.create(point_format=0)

    with pytest.raises(ValueError):
        new.red = np.zeros(len(new.points), np.uint16)

    with pytest.raises(ValueError):
        new.red = np.zeros(len(new.points), np.uint16)

    with pytest.raises(ValueError):
        new.red = np.zeros(len(new.points), np.uint16)

    with pytest.raises(ValueError):
        new.gps_time = np.zeros(len(new.points), np.float64)
Ejemplo n.º 4
0
def test_extraction(file):
    new = pylas.create(point_format_id=0)

    assert file.points_data.point_format_id == 3

    # automatic promotion of point format
    new.points = file.points[file.classification == 2]
    assert new.points_data.point_format_id == 3
    assert new.header.point_format_id == 3

    assert len(new.points) == sum(file.classification == 2)
    assert np.alltrue(new.classification == 2)

    file = write_then_read_again(new)
    assert np.alltrue(file.classification == 2)
Ejemplo n.º 5
0
def test_cant_create_scaled_extra_bytes_with_scales_array_smaller(num_elements):
    las = pylas.create()
    with pytest.raises(ValueError) as error:
        las.add_extra_dim(
            pylas.ExtraBytesParams(
                "must fail",
                f"{num_elements}int64",
                scales=np.array([0.1] * (num_elements - 1)),
                offsets=np.array([0.0] * num_elements),
            )
        )
    assert (
        str(error.value)
        == f"len(scales) ({num_elements - 1}) is not the same as the number of elements ({num_elements})"
    )
Ejemplo n.º 6
0
def test_create_fmt_1(file):
    new = pylas.create(point_format_id=1)

    with pytest.raises(ValueError):
        new.red = file.red

    with pytest.raises(ValueError):
        new.red = file.green

    with pytest.raises(ValueError):
        new.red = file.blue

    new.gps_time = file.gps_time
    assert np.allclose(new.gps_time, file.gps_time)

    new = write_then_read_again(new)
    assert np.allclose(new.gps_time, file.gps_time)
Ejemplo n.º 7
0
def test_create_fmt_6(file1_4):
    new = pylas.create(point_format_id=6)
    assert new.header.version == "1.4"

    dim_names_fmt_6 = pylas.point.dims.get_dtype_of_format_id(6).names

    for dim_name in dim_names_fmt_6:
        new[dim_name] = file1_4[dim_name]

    for dim_name in dim_names_fmt_6:
        assert np.allclose(new[dim_name],
                           file1_4[dim_name]), "{} not equal".format(dim_name)

    new = write_then_read_again(new)
    for dim_name in dim_names_fmt_6:
        assert np.allclose(new[dim_name],
                           file1_4[dim_name]), "{} not equal".format(dim_name)
Ejemplo n.º 8
0
def test_create_fmt_6(file1_4):
    new = pylas.create(point_format=6)
    assert str(new.header.version) == "1.4"

    dim_names_fmt_6 = PointFormat(6).dtype().names

    for dim_name in dim_names_fmt_6:
        new[dim_name] = file1_4[dim_name]

    for dim_name in dim_names_fmt_6:
        assert np.allclose(new[dim_name],
                           file1_4[dim_name]), "{} not equal".format(dim_name)

    new = write_then_read_again(new)
    for dim_name in dim_names_fmt_6:
        assert np.allclose(new[dim_name],
                           file1_4[dim_name]), "{} not equal".format(dim_name)
Ejemplo n.º 9
0
def test_create_fmt_3(file):
    new = pylas.create(point_format=3)

    new.red = file.red
    new.green = file.green
    new.blue = file.blue
    new.gps_time = file.gps_time

    assert np.allclose(new.red, file.red)
    assert np.allclose(new.green, file.green)
    assert np.allclose(new.blue, file.blue)
    assert np.allclose(new.gps_time, file.gps_time)

    new = write_then_read_again(new)
    assert np.allclose(new.red, file.red)
    assert np.allclose(new.green, file.green)
    assert np.allclose(new.blue, file.blue)
    assert np.allclose(new.gps_time, file.gps_time)
Ejemplo n.º 10
0
def test_create_fmt_2(file):
    new = pylas.create(point_format=2)

    with pytest.raises(ValueError):
        new.gps_time = file.gps_time

    new.red = file.red
    new.green = file.green
    new.blue = file.blue

    assert np.allclose(new.red, file.red)
    assert np.allclose(new.green, file.green)
    assert np.allclose(new.blue, file.blue)

    new = write_then_read_again(new)
    assert np.allclose(new.red, file.red)
    assert np.allclose(new.green, file.green)
    assert np.allclose(new.blue, file.blue)
Ejemplo n.º 11
0
def test_create_fmt_1():
    new = pylas.create(point_format=1)

    with pytest.raises(ValueError):
        new.red = np.zeros(len(new.points), np.uint16)

    with pytest.raises(ValueError):
        new.red = np.zeros(len(new.points), np.uint16)

    with pytest.raises(ValueError):
        new.red = np.zeros(len(new.points), np.uint16)

    gps_time = np.random.uniform(0, 25641, len(new.points))
    new.gps_time = gps_time
    assert np.allclose(new.gps_time, gps_time)

    new = write_then_read_again(new)
    assert np.allclose(new.gps_time, gps_time)
Ejemplo n.º 12
0
    def write(self, point_cloud, attributes='all', file_version='1.2', point_format_id=3):
        """
        Write point cloud to a LAS(LAZ) file.

        :param point_cloud:
        :param attributes: list of attributes to write ('all' for all attributes in point_cloud)
        :param file_version:
        :param point_format_id:
        :return:
        """
        file = pylas.create(point_format_id=point_format_id,
                            file_version=file_version)

        points = point_cloud[keys.point]
        attributes = select_valid_attributes([attr for attr in points.keys()], attributes)

        # NOTE: adding extra dims and assignment should be done in two steps,
        # some fields (e.g. raw_classification) are otherwise overwritten
        for attribute in attributes:
            data, type = _get_data_and_type(points[attribute])
            type_short = convert_to_short_type(type)
            if attribute not in 'xyz':
                # x,y,z are not there but file methods can be used to convert coords to int4
                if attribute not in file.points.dtype.names:
                    file.add_extra_dim(name=attribute, type=type_short)
            file_type_short = convert_to_short_type(getattr(file, attribute).dtype.name)
            if not file_type_short == type_short:
                raise TypeError('Data type in file does not match the one in point cloud: '
                                'for {}, {} vs {}'.format(attribute, file_type_short, type_short))

        for attribute in attributes:
            data, _ = _get_data_and_type(points[attribute])
            if data.size == 0:
                raise ValueError('Cannot write empty point-cloud!')
            else:
                setattr(file, attribute, data)

        try:
            file.write(self.path)
        except ValueError as err:
            raise ValueError('Error in writing LAS file (file_version {}, point_format_id {}). '
                             'pylas error below:\n{}'.format(file_version, point_format_id, err))
Ejemplo n.º 13
0
def write(
    point_data,
    output_path: Union[Path, str],
    *,
    crs: Optional[int] = None,
    xyz_offset: Tuple[float] = None,
    point_format: Optional[int] = None,
    scale: Tuple[float] = None,
    data_min_max: Optional[Dict[str, Tuple]] = None,
):
    """Write point cloud data to an output path.

    Look in point_formats.py to see the type of each destination field.

    Args:
        point_data (dict-like): Any object that implements the __getitem__ method.
            So a dictionnary, a pandas DataFrame, or a numpy structured array will
            all work.
        output_path (Union[Path, str]): The output path to write the las file.
            The output directory is created if it doesn't exist.
        xyz_offset (Tuple[float], optional): Apply this xyz offset before
            writing the coordinates. This can be useful for large coordinates
            loaded as float32 with an offset.
            The offset is applied by adding it to the coordinate.
            Defaults to (0, 0, 0).
        crs (int, optional): The EPSG code to write in the las header.
        point_format (int, optional): The las point format type identifier
            Only formats 0, 1, 2, 3, 6 and 7 are accepted.
            If None is given, the best point format will be guessed
            based on the provided fields.
        scale (Tuple[float], optional): The coordinate precision.
            Coordinates in the las file are stored in int32. This means that there is
            always a slight loss in precision. Most real world use cases are not
            affected if the scale is set correctly. So this should be set to the
            smallest error you can afford to have in the final file.
            Setting this to a number too small could lead to errors when using
            large coordinates.
            The default computes the scale based on the maximum range of a 32 bits
            signed integer.
        data_min_max (dict): Scale some dimensions according to these minimum and
            maximum values. Only these fields can be scaled: intensity, red, green,
            blue For example: the red channel is stored as uint16 inside a las file.
            If the red data in the source point_data is uint8, you can set
            data_min_max = {'red': (0, 255)}
            and the data will be scaled to the uint16 range 0-65536.
    """
    Path(output_path).parent.mkdir(parents=True, exist_ok=True)

    if data_min_max is None:
        data_min_max = {}

    standard_dimensions = point_formats.standard_dimensions | {"xyz", "XYZ"}
    extra_dimensions = sorted(set(point_data) - standard_dimensions)

    if not point_format:
        point_format = point_formats.best_point_format(point_data, extra_dimensions)

    if point_format not in point_formats.supported_point_formats:
        raise ValueError(
            f"Unsupported point format {point_format} "
            f"(not in {point_formats.supported_point_formats})"
        )

    point_format_type = point_formats.point_formats[point_format]

    xyz = None
    for coords in ["xyz", "XYZ"]:
        if coords in point_data:
            # expects an array of the shape (n_points, 3)
            xyz = [
                point_data[coords][:, 0],
                point_data[coords][:, 1],
                point_data[coords][:, 2],
            ]
            break
        if all(c in point_data for c in coords):
            xyz = [point_data[c] for c in coords]
            break

    if not xyz:
        raise ValueError("Could not find xyz coordinates from input data.")

    las = pylas.create(file_version="1.4", point_format_id=point_format)

    if crs is not None:
        wkt = pyproj.CRS.from_epsg(crs).to_wkt()
        las.vlrs.append(WktCoordinateSystemVlr(wkt))
        las.header.global_encoding.wkt = 1

    for dim in extra_dimensions:
        dtype = point_data[dim].dtype
        las.add_extra_dim(name=dim, type=f"{dtype.kind}{dtype.itemsize}")

    min_, max_, offset = _min_max_offset(xyz)

    offset = offset if xyz_offset is None else xyz_offset
    if xyz_offset is None:
        xyz_offset = (0, 0, 0)

    min_ += xyz_offset
    max_ += xyz_offset
    las.header.mins, las.header.maxs, las.header.offsets = min_, max_, offset
    las.header.scales = scale if scale else _get_scale(min_, max_, offset)

    las.x = xyz[0].astype("d") + xyz_offset[0]
    las.y = xyz[1].astype("d") + xyz_offset[1]
    las.z = xyz[2].astype("d") + xyz_offset[2]

    if "gps_time" in point_format_type and "gps_time" in point_data:
        las.gps_time = point_data["gps_time"]

    if "intensity" in point_format_type and "intensity" in point_data:
        las.intensity = scale_data(
            "intensity", point_data["intensity"], data_min_max.get("intensity")
        )

    if "classification" in point_format_type and "classification" in point_data:
        # convert pd.Series to numpy array, if applicable
        las.classification = np.array(point_data["classification"])

    colors = ["red", "green", "blue"]
    if all(c in point_format_type and c in point_data for c in colors):
        for c in colors:
            setattr(las, c, scale_data(c, point_data[c], data_min_max.get(c)))

    for dim in extra_dimensions:
        setattr(las, dim, point_data[dim])

    las.write(str(output_path))
Ejemplo n.º 14
0
    if equation[0] < 0 and equation[1] < 0 and equation[2] < 0:
        dist_ind = np.where(distances < 0)
    else:
        dist_ind = np.where(distances > 0)

    # for x in range(10):
    #   print(distances[dist_ind[0][x]])

    # Check for no high points
    if not dist_ind:
        print("There are no points above the plane " + name)
        continue

    # Gather data for output las file
    out_x = las_x[dist_ind[0]]
    out_y = las_y[dist_ind[0]]
    out_z = las_z[dist_ind[0]]

    las_out = pylas.create()
    las_out.x = out_x
    las_out.y = out_y
    las_out.z = out_z

    # Write .las file
    las_out.write(name + ".las")
    print("done")

# Close CSV file
csvfile.close()
Ejemplo n.º 15
0
def test_good_version_is_used():
    for i in range(6, 8):
        las = pylas.create(point_format=i)
        assert las.header.version.major == 1
        assert las.header.version.minor == 4
Ejemplo n.º 16
0
def test_wrong_version():
    for i in range(6, 8):
        with pytest.raises(pylas.errors.PylasError):
            _ = pylas.create(point_format=i, file_version="1.2")
Ejemplo n.º 17
0
print("==== ", las.points)

bad_idx = np.where(las.points['Z'] >= mean * 1.05)
bad_ffp = np.take(las.points, bad_idx)
reduced_bad_ffp = np.squeeze(bad_ffp)

colors = reduced_bad_ffp[["red", "green", 'blue']]
vf = np.vectorize(convert_color)
converted = vf(colors[:10])

filered_colors = 150 < converted[0] < 250

#todo funkcja, ktora sprawdzi czy kolor jest powyzej czy ponizej

import pdb
pdb.set_trace()

# for color in colors:
#     converted = convert_color(color)

# import pdb;pdb.set_trace()

# filtered_points.write('data/filtered_points.las')
new_test1 = pylas.create(point_format_id=2)
new_test1.points = reduced_bad_ffp
new_test1.vlrs = las.vlrs
new_test1.header = las.header
new_test1.write('data/filtered_points_experiments.las')

print(11111251552, las.points_data)