Skip to content
LidarKit

What is COPC?

A LAZ file arranged so that a viewer can fetch only the part it is looking at.

COPC — Cloud Optimized Point Cloud — is a way of laying out a LAZ file so that software can read part of it without downloading all of it. The points are grouped into the nodes of an octree, each node is one compressed chunk, and a small index at the end says where every chunk is. A viewer opens the header, reads the index, and fetches only the nodes that fall inside its view at the level of detail it needs.

The specification was published in 2021 by Hobu, Inc., and it is deliberately small: a COPC file is an ordinary LAZ 1.4 file with two extra records and a rule about how the points are ordered. Anything that reads LAZ reads it. Anything that understands the two records can stream it.

The problem it solves

A plain LAS or LAZ file stores points in whatever order the scanner produced them, usually by time. To draw any part of it you have to read all of it, because the points for one corner of the survey are scattered through the entire file. For a 200 MB tile on a local disk that is fine. For a 20 GB survey in cloud storage, viewed over a network, it is not — and the first web point cloud viewers dealt with it by pre-processing the data into thousands of small files in a directory tree, one per octree node.

That works, but a directory of ten thousand files is awkward to move, version, or hand to a client. COPC puts the same octree inside a single file, and relies on a feature every HTTP server already has: the Range header, which asks for one byte span of a file. The result is a single .copc.laz that opens in every LAZ tool and streams into any COPC-aware one.

How the file is organised

PartWhereWhat it is
LAS 1.4 headerBytes 0–374An ordinary header. Point format must be 6, 7 or 8, compression bit set.
copc info VLRBytes 375–588Must be the first VLR. 160-byte payload: octree centre and half-size, root spacing, location of the root hierarchy page, GPS time range.
Other VLRsAfter the info recordThe laszip parameters, the WKT coordinate system, anything else — as in any LAZ.
Point dataFrom the point data offsetOne LAZ chunk per octree node, in any order, located by the hierarchy rather than the chunk table.
copc hierarchy EVLRAfter the pointsThe index: 32-byte entries giving each node's key, byte offset, byte size and point count, in pages that can themselves be loaded on demand.

The octree

The root node is a cube — a cube, not the bounding box — centred on the octree centre and extending half-size in every direction, large enough to contain all the points. Each level divides every node into eight children. A node is named by its key: the level and its X, Y and Z position within that level, so 0-0-0-0 is the root, 1-0-1-0 one of its children, and so on to whatever depth the data needs.

Every node holds a subsample of the points inside its cube, thinned so that no two are closer than the node's spacing — the root spacing from the info record, halved at each level. Points held by a node are not repeated in its children; the children hold the points the parent left out. So the root alone is a coarse but complete picture of the whole survey, root plus level one is finer, and the union of every node is the entire file exactly once.

That is what makes level of detail free. A viewer looking at the whole survey from far away draws the root and one or two levels down. Zooming into a building, it fetches the deeper nodes under that building only, and nothing for the fields around it.

The hierarchy

The hierarchy EVLR is the index. Each 32-byte entry names a node and says where its chunk is and how many points it holds. A point count of −1 means the entry points at another page of hierarchy entries rather than at data, so a viewer can load the index for a deep octree incrementally too, instead of reading a multi-megabyte table before showing anything. A count of zero means the node is empty but may have children.

To see a real hierarchy laid out — depth, nodes and points per level, spacing per level, and whether the index agrees with the header — open a file in the COPC viewer's inspector panel. It reads the info record and the hierarchy pages and nothing else.

What the host has to do

Streaming depends on the server, and three things can go wrong, each with a different cause:

  • Cross-origin requests refused. A browser will not read a file from another domain unless that domain sends an Access-Control-Allow-Origin header. Nothing a viewer does can fix this; the host has to be configured.
  • Range ignored. A server that answers a range request with the whole file (status 200 instead of 206) serves COPC exactly as badly as plain LAZ. Most object stores honour ranges; some static-site hosts and CDN configurations do not.
  • Content-Range hidden. Browsers may only read a short list of response headers cross-origin, and Content-Range — which carries the total file size — is not on it. The host must add it to Access-Control-Expose-Headers. Amazon S3 does not by default. A viewer can work around this with a HEAD request, but not every host allows those either.

A good COPC viewer reports which of the three it hit rather than saying "could not load", because the fix for each is different and none of them is in the viewer.

Making a COPC file

Converting to COPC means rewriting the file: every point is sorted into its octree node, each node is compressed as a chunk of its own, and the info and hierarchy records are written around the result. It takes roughly as long as reading and writing the data, because every point moves. The source does not need to be LAS 1.4 — older point formats are promoted to 6, 7 or 8 on the way, and any class above 31 or return above 5 that the older format could not express was never there to lose.

Conversion to COPC is not offered on this site yet. The viewer reads files that already are, and the inspector tells you whether a file is one.

Reading one

Every LAZ reader opens a COPC file as a whole, because it is valid LAZ. Streaming needs a reader that understands the two records and asks the host for byte ranges.

Open a COPC file in your browser — from disk or straight from a URL. The viewer reads the hierarchy and fetches only the nodes in view, shows the running download total so the trade-off stays visible, and names the specific hosting problem when a URL will not stream.

Checking whether a file is COPC

The extension is a convention, not a guarantee. A real COPC file has the copc info record as its very first VLR, at byte 375, in a LAZ 1.4 file with point format 6, 7 or 8. A LAZ file that was merely renamed will have a laszip or projection record there instead, and a file that carries a copc record but was later re-compressed by a tool that did not understand it has an index pointing at chunks that no longer exist. The LAS inspector decodes the info record and checks the rest of the layout against the specification, so either case is visible in a second.

For what COPC is being compared against, see LAS vs LAZ; for the underlying container, what is a LAS file.

Frequently asked questions

What is a COPC file?
A Cloud Optimized Point Cloud is a LAZ 1.4 file whose point records are grouped into the nodes of an octree, with a small index record describing where each node sits in the file. Because it is valid LAZ, any LAZ reader opens it as a whole; because of the index, a COPC-aware reader can fetch only the nodes it needs with HTTP range requests.
Is COPC a different format from LAZ?
No. A COPC file is a LAZ file, with the usual .laz extension and conventionally a .copc.laz double extension. What makes it COPC is the arrangement of the points into an octree, one compressed chunk per node, plus two extra records: a copc info VLR that must be the first record in the file, and a hierarchy EVLR at the end.
What does COPC require of the LAS file?
LAS 1.4, point data record format 6, 7 or 8, LAZ compression with a chunk table, the copc info VLR as the first VLR immediately after the 375-byte header, and every point stored in an octree node. Formats 0 to 5 and the waveform formats 9 and 10 are not allowed.
How do I convert LAZ to COPC?
By rewriting the file: every point is sorted into its octree node, each node is compressed as a chunk of its own, and the info and hierarchy records are written around the result. Any LAS or LAZ can be converted, with older point formats promoted to 6, 7 or 8, and it takes about as long as reading and writing the data. Conversion to COPC is not offered on this site yet; the COPC viewer reads files that already are.
Why does a COPC file not stream from my server?
The host has to allow cross-origin requests, honour HTTP Range headers with a 206 response, and expose the Content-Range header to browsers through Access-Control-Expose-Headers. Object stores such as S3 do the first two by default but not the third unless configured; a static host that ignores Range returns the whole file. A COPC-aware viewer will tell you which one failed.
Does COPC open in ordinary LAZ software?
Yes. A COPC file is valid LAZ, so anything that reads LAZ opens it whole, and nothing is lost in either direction. Streaming — fetching only the nodes in view — needs a COPC-aware reader that understands the info and hierarchy records. The COPC viewer on this site is one, from a local file or straight from a URL.
Should I archive as COPC?
You can, since a COPC file is complete, lossless LAZ and loses nothing. It is slightly larger than a plain LAZ of the same points because spatially grouped points compress a little less well than scan-ordered ones, and it opens everywhere LAZ does. If the data will ever be served to a viewer, COPC saves converting later.