2

I have an application that can import terrain data in an XYZ text format where X = latitude, Y = longitude and Z = elevation.

I am trying to convert a LiDAR .las file to this format using las2las.

I use las2las to convert the .las file and then read the converted .las file in Python using laspy to read the XYZ values. The X and Y values do not reflect the proper latitude/longitude of the area that the LiDAR file contains.

To illustrate, here is the .xml from the LiDAR file showing metadata, note that latitude around 46.XXXXXXXX and Longitude -96.XXXXXXX (which is what I expect):

<?xml version="1.0" standalone="yes"?>
<Metadata>
<EntityID>IWI_RedRiver-C_2008_000723</EntityID>
<ProjectName>IWI_RedRiver-C_2008</ProjectName>
<ProjectMetadataFiles>http://dds.cr.usgs.gov/lidar_v2/ND-MN/2008/IWI_RedRiver-C_2008/metadata/IWI_RedRiver-C_2008_metadata.zip</ProjectMetadataFiles>
<State>ND-MN</State>
<BeginDate>2008-04-21</BeginDate>
<EndDate>2008-05-16</EndDate>
<VerticalDatum>NAVD88</VerticalDatum>
<MapProjection>UTM</MapProjection>
<MapZone>14</MapZone>
<MapProjectionDefinition>PROJCS["NAD_1983_UTM_Zone_14N",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",-99.0],PARAMETER["Scale_Factor",0.9996],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0],AUTHORITY["EPSG",26914]]</MapProjectionDefinition>
<CenterLat>46.8520722</CenterLat>
<CenterLon>-96.8356110</CenterLon>
<ULLat>46.8613222</ULLat>
<ULLon>-96.8483721</ULLon>
<URLat>46.8608250</URLat>
<URLon>-96.8221249</URLon>
<LRLat>46.8428221</LRLat>
<LRLon>-96.8228554</LRLon>
<LLLat>46.8433194</LLLat>
<LLLon>-96.8490916</LLLon>
<MinX>664000.000</MinX>
<MaxX>665999.990</MaxX>
<MinY>5189999.998</MinY>
<MaxY>5191999.989</MaxY>
<MinZ>253.551</MinZ>
<MaxZ>330.992</MaxZ>
<VendorID>IWI_RedRiver-C_2008_R06645190</VendorID>
<NumOfPulseRecords>2559425</NumOfPulseRecords>
<NumOfPulsesByReturn>(1) 2424977 (2) 129573 (3) 4807 (4) 68</NumOfPulsesByReturn>
<NumOfPtRecords>2559425</NumOfPtRecords>
<NumOfPtsByReturn>(1) 2491531 (2) 66447 (3) 1442 (4) 5</NumOfPtsByReturn>
<Intensity>0,255</Intensity>
<NominalPulseSpacing>1.28432</NominalPulseSpacing>
<PulseDensity>0.60625</PulseDensity>
<PulseDensityNPSUnits>METER</PulseDensityNPSUnits>
<VendorNominalPulseSpacing>1.7</VendorNominalPulseSpacing>
<VendorPointDensity>.35</VendorPointDensity>
<VendorPointDensityNPSUnits>METER</VendorPointDensityNPSUnits>
<FileFormat>las</FileFormat>
<LASVersion>1.0</LASVersion>
</Metadata>

The LiDAR file I am trying to get lat/long from is called IWI_RedRiver-C_2008_000723.las so I run las2las with these parameters:

las2las -i c:\terrainfiles\lidar\IWI_RedRiver-C_2008_000723.las -o out.las -utm 14N -target_latlong

I get XYZ values in this range:

X,Y,Z:  8433152 -8240716 27584

It is not close to what I'm expecting from the .xml file (which is the correct lat/lon).

Am I using las2las wrong? I have tried other las2las params such as -epsg 26914, and -sp83 ND_S and I get different X,Y,Z values but still off.

For Example:

las2las -i c:\terrainfiles\lidar\IWI_RedRiver-C_2008_000723.las -o out.las -utm 14N -sp83 ND_S -target_latlong

produces :

X,Y,Z:  4590852 505294 27624

I see las2txt appears to do what I want from my Python script but it gives a completely different outcome as well. If I run it on the previous output of las2las with this command:

las2txt -parse xyz -i out.las -o out.xyz

I get output that looks like this:

86.4590852 -94.9494706 276.24
86.4590849 -94.9492982 276.24
86.4590847 -94.9491291 276.32
86.4590845 -94.9489549 276.24
86.4590842 -94.9487867 276.28
86.4590869 -94.9489067 284.62
86.4590894 -94.9488187 276.20

Is there a better way to convert LiDAR .las to XYZ where X and Y are latitude/longitude values?

  • Instead of using 14N, try using 14T. Based on example here, it uses the latitude band letter rather than the hemisphere letter. – mkennedy Dec 18 '17 at 23:26
  • This appears to work using las2txt, if you put this down as an answer I will mark the questions as answered. – Jeff Dec 28 '17 at 15:59
  • Done! Thank you for letting me know that it worked. – mkennedy Dec 28 '17 at 17:55
2

I didn't expect that this would be the answer, but it turns out that las2las uses the UTM latitude band letters rather than the hemisphere 'N' (North) or 'S' (South) letters with the zone number. While not stated directly, I found an example in this help page

Here's an example from that page:

>> las2las -i s1885565.laz -o out.las -sp83 OH_S -feet -elevation_feet -target_sp83 OH_N -target_survey_feet -target_elevation_survey_feet 
>> las2las -i TO_core_last_zoom.laz -o out.laz -utm 17T
>> las2las -i TO_core_last_zoom.laz -o out.laz -utm 17T -target_latlong

Note the '-utm 17T'. The 'R', 'S', and 'T' bands are solidly in the contiguous United States (AKA lower 48). You can check out Wikipedia for more information on the latitude bands.

In this particular case, instead of using 14N, try using 14T.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.