Skip to content

Cloud from numpy doesn't save las with shift. #218

Open

Description

@asymons-Veris

Hello -

We have upgraded to the latest release of CloudComPy (February 20, 2024 -> June 19, 2025) and we have trouble saving LAS/LAZ clouds created from numpy arrays - The shift is not used when saving. The same issue does not occur for bin/xyz.

Without respecting the shift, the points overflow on save, with LAS header offset of saved file as [0,0,0].

What we want is to save out the file using the shift that was set.

To reproduce:

import numpy as np
import cloudComPy as cc 

print("=== Create cloud ===")
points = np.array([[0.0, 0.0, 0.0]], dtype=np.float32)
cloud = cc.ccPointCloud("test")
cloud.coordsFromNPArray_copy(points)
cloud.setGlobalShift(0.0, -2_500_000.0, 0.0)

print("Shift:", cloud.getGlobalShift())
print("isShifted:", cloud.isShifted())
print("Points:", cloud.toNpArrayCopy())

print("=== Save ===")
cc.SavePointCloud(cloud, "test.las")

print("=== Load ===")
loaded = cc.loadPointCloud("test.las", mode=cc.CC_SHIFT_MODE.XYZ, x=0.0, y=-2_500_000.0, z=0.0)
print("Shift:", loaded.getGlobalShift())
print("isShifted:", loaded.isShifted())
print("Points:", loaded.toNpArrayCopy())
Output:
=== Create cloud ===
Shift: (0.0, -2500000.0, 0.0)
isShifted: True
Points: [[0. 0. 0.]]
=== Save ===
=== Load ===
Shift: (0.0, -2500000.0, 0.0)
isShifted: True
Points: [[       0.  -4647483.5        0. ]]    ## Should be [0,0,0]

LAS saving works when I load/save a cloud that already has an appropriate shift in the header.

Possibly related to the expanded options in CloudCompare that suggests can look at the LAS header instead of the set shift when saving:
https://www.cloudcompare.org/forum/viewtopic.php?p=30162#p30162

Appreciate any ideas or short-term fixes.

Activity

  1. prascle commented on Nov 5, 2025

    @prascle
    Collaborator

    Hi,
    Sorry for the late reply.
    I can reproduce the problem. Thanks for the link to the CloudCompare forum. I think you're right, I'll try with the extended settings. Unfortunately, I don't see any way to set these parameters without development: I'll try to release a fix as soon as possible...

    Regards,
    Paul

  2. bthetford commented on Jan 13, 2026

    @bthetford

    I think I'm experiencing the same problem. I do notice a difference in the output if I use setGlobalShift() or not. If I have a float64 ndarray points that looks like this:

    [[6782917.06005859 1994384.39001465      68.7990036 ]
     [6782917.02001953 1994387.44000244      68.73300171]
    
    
    
     [6782916.85998535 1994389.76998901      69.19200134]
     ...
     [6783537.13000488 1994592.09997559      73.98200226]
     [6783543.06994629 1994577.16998291      74.60600281]
     [6783542.7800293  1994583.85998535      74.37599945]]
    

    And I create a ccPointCloud instance and write it to las like this:

    cloud = cc.ccPointCloud()
    cloud.coordsFromNPArray_copy(points)
    cloud.setGlobalShift(-6782000.0, -1994000.0, 0.0)
    res = cc.SavePointCloud(cloud, "test.las")
    

    Dragging the result into CloudCompare, this is what I see:

    Image

    There's no "input" option, and the X and Y coords are the same and the numbers are strange (they should all be around 6782000 and -1994000). Viewing the file, it appears transformed in 3D.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions