Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add COPC reading support #219

Merged
merged 1 commit into from
Jun 2, 2022
Merged

Add COPC reading support #219

merged 1 commit into from
Jun 2, 2022

Conversation

tmontaigu
Copy link
Member

This adds the CopcReader class to laspy
that understands the COPC LAZ format, enabling to
do spatial and / or LOD based queries.

The class require lazrs to work,
and optionaly, if requests is installed
COPC over HTTP is supported.

laspy/copc.py Outdated Show resolved Hide resolved
laspy/copc.py Outdated Show resolved Hide resolved
laspy/copc.py Outdated Show resolved Hide resolved
laspy/copc.py Outdated Show resolved Hide resolved
@hobu
Copy link
Contributor

hobu commented May 17, 2022

In addition to filtering by a bounds, it would also be really useful to filter by a resolution or tree level. PDAL has some examples of this resolution-based filtering at https://github.com/PDAL/PDAL/tree/master/io/private/copc and https://github.com/PDAL/PDAL/blob/master/io/CopcReader.cpp#L241

@tmontaigu
Copy link
Member Author

In addition to filtering by a bounds, it would also be really useful to filter by a resolution or tree level. PDAL has some examples of this resolution-based filtering at https://github.com/PDAL/PDAL/tree/master/io/private/copc and https://github.com/PDAL/PDAL/blob/master/io/CopcReader.cpp#L241

The query function is defined as

    def query(
        self,
        bounds: Optional[Bounds] = None,
        level: Optional[Union[int, range]] = None,
    ) -> ScaleAwarePointRecord:

So you can filter by bounds or level or both at the same time , some wrapper functions also exists

    def spatial_query(self, bounds: Bounds) -> ScaleAwarePointRecord:
        return self.query(bounds=bounds, level=None)

    def level_query(self, level: Union[int, range]) -> ScaleAwarePointRecord:
        return self.query(bounds=None, level=level)

@hobu
Copy link
Contributor

hobu commented May 17, 2022

A helper function to allow users to convert level->resolution would be very useful.

@tmontaigu
Copy link
Member Author

Ok I got confused, resolution != level

@hobu
Copy link
Contributor

hobu commented May 17, 2022

Ok I got confused, resolution != level

Yes. They're directly related, but we have found with EPT and COPC it is much easier to say "select everything at or below 3m" instead of having to calculate based on the dimensions of the octree what level would correspond to everything 3m or below.

@tmontaigu tmontaigu force-pushed the copc-reader branch 2 times, most recently from fc25096 to 370fcfe Compare May 17, 2022 20:55
@hobu
Copy link
Contributor

hobu commented May 17, 2022

@tmontaigu
Copy link
Member Author

resolution was added as a query parameter

@hobu
Copy link
Contributor

hobu commented May 18, 2022

I attempted to test this but got the following:

AttributeError: module 'lazrs' has no attribute 'decompress_points_with_chunk_table'

I presume this is due to lazrs not being released with chunk table support quite yet?

@tmontaigu
Copy link
Member Author

Yes, I plan on releasing lazrs later this week, after that this PR will be testable easily

@tmontaigu
Copy link
Member Author

The new version of lazrs was pushed to pypi so it should be easier to test now

@hobu
Copy link
Contributor

hobu commented May 19, 2022

OSX arm wheels for lazrs didn't post https://pypi.org/project/lazrs/#files

@hobu
Copy link
Contributor

hobu commented May 19, 2022

I installed my own lazrs.

It seems a bit slower than PDAL while fetching over the network. Are you reading the entire octree down to the client?

time pdal info --all https://s3.amazonaws.com/hobu-lidar/melbourne-2018.copc.laz   
1.59s user 1.48s system 110% cpu 2.786 total
time python copc.py https://s3.amazonaws.com/hobu-lidar/melbourne-2018.copc.laz
copc_reader_ready for https://s3.amazonaws.com/hobu-lidar/melbourne-2018.copc.laz
Spatial Query gave: <ScaleAwarePointRecord(fmt: <PointFormat(7, 0 bytes of extra dims)>, len: 77486, point size: 36)>
0.021911293026868
Spatial Query gave: <ScaleAwarePointRecord(fmt: <PointFormat(7, 0 bytes of extra dims)>, len: 101208, point size: 36)>
0.028619339553767862
It took: 10.786364793777466  seconds
python copc.py https://s3.amazonaws.com/hobu-lidar/melbourne-2018.copc.laz  2.86s user 2.64s system 50% cpu 10.950 total

@tmontaigu
Copy link
Member Author

tmontaigu commented May 20, 2022

OSX arm wheels for lazrs didn't post https://pypi.org/project/lazrs/#files

I have not posted these wheels yet

It seems a bit slower than PDAL while fetching over the network. Are you reading the entire octree down to the client?

Yes the entire octree hierarchy info is fetched at the begnning.
The idea was that when doing multiple queries on the same ressource, we would not have to refetch the octree info.
I'll change it to only fetch progressively the node informations and see how much it improves.

The pdal info only reads the header and does not fetch any octree info nor points ?

The python example reads the whole hierarchy and then queries two quarter of the bounds with a Some resolution

@tmontaigu
Copy link
Member Author

I just pushed changes that makes it so that the octree hierarchies are fetched when actually needed (and not fetch every thing on init like before)

@hobu
Copy link
Contributor

hobu commented May 20, 2022

I just pushed changes that makes it so that the octree hierarchies are fetched when actually needed (and not fetch every thing on init like before)

Confirmed and behaving as I would expect now.

I have not posted these wheels yet

I didn't realize these weren't automated. laz-rs/laz-rs-python#9 implied they were, but maybe that isn't quite done yet.

@hobu
Copy link
Contributor

hobu commented May 20, 2022

Sorry, my pdal info call was this:

time pdal info --all https://s3.amazonaws.com/hobu-lidar/melbourne-2018.copc.laz --readers.copc.resolution=20.0

That reads across the entire domain and fetches points to a 20m resolution (376303 points)

@tmontaigu
Copy link
Member Author

Confirmed and behaving as I would expect now.

Ok nice

I didn't realize these weren't automated. laz-rs/laz-rs-python#9 implied they were, but maybe that isn't quite done yet.

Yeah its a thing that I want to do, it should not be hard, but CI is not the most interesting thing to do in projects 😅

This adds the `CopcReader` class to laspy
that understands the COPC LAZ format, enabling to
do spatial and / or LOD based queries.

The class require `lazrs` to work,
and optionaly, if `requests` is installed
COPC over HTTP is supported.
@tmontaigu tmontaigu marked this pull request as ready for review May 27, 2022 14:11
@tmontaigu tmontaigu merged commit caa1116 into master Jun 2, 2022
@tmontaigu tmontaigu deleted the copc-reader branch June 28, 2022 22:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants