I am trying to convert a .las file from WGS84 to UTM17. I have some drone imagery that was used to generate a 3d point cloud/ .las file, but it is in latitude/ longitude instead of easting/ northing.
I tried using laspy, a great python API for reading las files. I was able to use this to convert the XYZ info from the .las to a csv file. I then used this csv file and a package in R to convert the coordinates. Now I am trying to use laspy to write a new .las file with the correct coordinates.
Here's my code so far:
import numpy import laspy #pandas used here to convert csv to array import pandas #Import a .las file and name it something van_taken = laspy.file.File("C:\Users\Mainframe2\PycharmProjects\LAS Conversion\Coordinate Conversion\Taken.Lands.Points.las", mode="rw") converted_csv = pandas.read_csv("C:\Users\Mainframe2\PycharmProjects\LAS Conversion\Coordinate Conversion\Taken.Lands.UTM.csv") converted_csv = converted_csv.as_matrix() #get individual column from array using Pandas converted_x = converted_csv[:,1] converted_y = converted_csv[:,2] converted_z = converted_csv[:,3] #Convert original points to new points van_taken.x = converted_x van_taken.y = converted_y van_taken.z = converted_z
This is where the problem arises.
van_taken.x array([-83.0830127, -83.0830128, -83.0830127, ..., -83.0830927, -83.0830926, -83.0830929]) converted_x array([ 269873.21570411, 269872.62699301, 269873.32416573, ..., 269073.15716998, 269074.64298861, 269071.18083953]) van_taken.x = converted_x
van_taken.x array([-297.8583648, -297.8583648, -297.8583648, ..., -297.8583648, -297.8583648, -297.8583648])
For some reason, it appears that when I try to set them equal, van_taken.x refuses to be equal to what it says.
I've looked through the documentation and can't seem to find anything. Is there some scale or offset that is causing this to happen? Once I figure this out I will be able to save the .las file and convert to the correct coordinate system.
>>> van_taken.header.scale [1e-07, 1e-07, 0.01] >>> van_taken.header.offset [-83.11, 10.0, -1000.0]
I changed the scale to
van_taken.header.scale = [1,1,1]
>>> van_taken.x array([ 269872.89, 269872.89, 269872.89, ..., 269072.89, 269074.89, 269070.89]) >>> converted_x array([ 269873.21570411, 269872.62699301, 269873.32416573, ...,
Changing the scale seemed to make the number more realistic, but they are still different now. I'm going to experiment with a couple different scales.
Grant Brown's answer works like a charm. I copied and pasted it. For some reason when I ran the whole code at once in Pycharm, it gave me some syntax errors. But I just ran it line by line and it didn't have a problem.
>>> converted_x array([ 269873.2157 , 269872.62699, 269873.32417, ..., 269073.15717, 269074.64299, 269071.18084]) >>> van_taken.x array([ 269873.2157 , 269872.62699011, 269873.32417004, ..., 269073.15716974, 269074.64298997, 269071.18084039])
Grant's answer is accurate at least to the number of decimal places we have in our file. (I reduced the number of decimals I originally had from 10 places to 5, since 5 is sub milimeter precision.)
Finally, I just want to say remember to close the file. I was a complete noob here, but after closing the file I noticed the file size was exactly the same size. I therefore incorrectly concluded that the file was not overwritten. But, as Grant explains.
"Unless you changed the number of points, the file is guaranteed to remain the same size. It's a binary file, and everything in it takes up a very precise amount of space. No matter what you do, LAS files store coordinates as integers. This is not something you can change or convert, ever. What you can do is change the scale and offset value, which allows you to construct coordinates in whatever system you want; they're the map between the data storage format and the coordinates you're actually interested in."
I got this one sorted out.