Más

¿Conversión de formatos shapefile o ráster a LAS?

¿Conversión de formatos shapefile o ráster a LAS?


Estoy buscando una solución para convertir de formato ESRI shapefile a LAS o de un formato ráster común a LAS. Tengo acceso al siguiente software:

  • ArcGIS 10.2 for Desktop (arcinfo con extensiones de analista espacial y analista 3d),
  • Mapeador global,
  • LASTools (sin licencia),
  • QGIS 2.8,
  • Whitebox GAT.

Tengo la funcionalidad en LASToolsshp2las.exeherramienta, pero como no tengo una licencia, solo puede manejar 2 millones de puntos antes de que agregue ruido XYZ. Debido al gran volumen de datos con los que estoy trabajando, no es práctico cortarlos en miles de piezas más pequeñas para procesar mosaicos de menos de 2 millones de puntos.

Existía el potencial de una solución alternativa utilizando eltext2lasherramienta, pero los resultados de esta herramienta también son inaceptables debido a un efecto de escalonamiento / contorneado. A pesar de los esfuerzos para garantizar que no se produzca ningún redondeo o truncamiento de los datos de entrada durante la transformación.

¿Existe alguna forma de convertir estos formatos a través de software libre o de código abierto?

¿O estoy pensando en comprar una licencia para FME o LASTools o algún otro software?


Sus entidades deben ser puntos, puede convertir ráster a punto usando Ráster a punto.

Con la herramienta AddXY puede agregar las coordenadas de X, Y (y si está presente Z) a los puntos, si no, debería haber algún tipo de campo de elevación ya allí o está en el arroyo ...

Inicie ArcMap, apague la pantalla (no es necesario actualizar), agregue los puntos, formatee los campos y simplemente mantenga X, Y, Z, abra la tabla de atributos (pista: puede reordenar los campos arrastrando en ArcGis 10+ pero deben estar en el orden correcto antes de la exportación). Exporte la tabla y use LAStools XYZ2las para convertir a un archivo LAS.

Aparentemente Global Mapper hará esto con Exportar Ráster y Datos de Elevación, no sé si esta herramienta espera formato Ráster o Vector… no hay mucha ayuda en la 'ayuda'.

Si está interesado, aquí está el código C ++ (en funcionamiento).

#include "stdafx.h" #include  #incluir  #incluir  #incluir  #incluir  #pragma pack (push, 1) // establece el empaquetado de la estructura en 1 struct LAShdrFirst {char FileSig [4]; sin firmar __int16 FileSource; unsigned __int16 Reserved_Unused; unsigned __int32 Project_ID_Data1; unsigned __int16 Project_ID_Data2; unsigned __int16 Project_ID_Data3; char Project_ID_Data4 [8]; carácter sin firmar Version_Major; carácter sin firmar Version_Minor; char System_ID [32]; char Software [32]; unsigned __int16 FC_Day, FC_Year, Header_Size; unsigned __int32 Offset_to_Data; unsigned __int32 VarLenRecs; char sin firmar Pt_DataFormat; }; struct LAShdrSecond {unsigned __int16 Pt_DataRecLen; unsigned __int32 PointCount; unsigned __int32 Point_by_Return_0; unsigned __int32 Point_by_Return_1; unsigned __int32 Point_by_Return_2; unsigned __int32 Point_by_Return_3; unsigned __int32 Point_by_Return_4; }; struct LAShdrSpatial {double Xscale; escala Y doble; escala Z doble; doble Xoffset; doble Yoffset; doble Zoffset; doble MaxX; doble MinX; doble MaxY; doble MinY; doble MaxZ; doble MinZ; }; struct LASrec0 {int X; int Y; int Z; Intensidad corta sin firmar; char DataByte; Clasificación de caracteres sin firmar; char ScanAngle; char UserData; PointSourceID corto sin firmar; ; #pragma pack (pop) // regresa el empaque a lo que sea const int MaxTxtSize = 256; void Convert (char * Directory, char * InFileName) {printf ("Convertir% s \% s  n", Directory, InFileName); char * nName = (char *) malloc (MaxTxtSize); para (int i = 0; iFileSig [0] = 'L'; Primero-> FileSig [1] = 'A'; Primero-> FileSig [2] = 'S'; Primero-> FileSig [3] = 'F'; Primero-> Offset_to_Data = 229; Primero-> Pt_DataFormat = 0; Primero-> Version_Major = 1; Primero-> Version_Minor = 2; Segundo-> Pt_DataRecLen = 20; Espacial-> Xscale = 0.01; Espacial-> Yscale = 0.01; Espacial-> Escala Z = 0.01; char * InFilePath = (char *) malloc (MaxTxtSize); char * OutFilePath = (char *) malloc (MaxTxtSize); std :: string FileLine; char * FileData; sprintf (InFilePath, "% s \% s", Directorio, InFileName); sprintf (OutFilePath, "% s \% s", Directorio, nName); doble pX, pY, pZ; unsigned __int32 PointCount = 0; unsigned __int16 Intensidad = 0; char * TextValues ​​= (char *) malloc (32); bool ExtentStarted = falso; para (int i = 0; i <32; i ++) {TextValues ​​[i] = ' 0'; } int vPnt = 0; int MaxLen; int pCnt, TVp; std :: ifstream InFile (InFilePath, std :: ios :: in); std :: ofstream OutLasFile (OutFilePath, std :: ios :: out | std :: ios :: binary); OutLasFile.write ((char *) Primero, sizeof (LAShdrFirst)); OutLasFile.seekp (First-> Offset_to_Data, std :: ios :: beg); // busca el primer registro do {getline (InFile, FileLine); MaxLen = FileLine.size (); if (MaxLen> 0) {FileData = new char [MaxLen + 1]; std :: copy (FileLine.begin (), FileLine.end (), FileData); FileData [MaxLen] = ' 0'; // null termina MUY IMPORTANTE vPnt = 0; TVp = 0; for (pCnt = 0; pCnt <= MaxLen; pCnt ++) {if (FileData [pCnt] == ​​"|| FileData [pCnt] == ​​',' || FileData [pCnt] == ​​' t' || FileData [ pCnt] == ​​' 0') // coma o cadena final. {if (vPnt == 0) pX = atof (TextValues); else if (vPnt == 1) pY = atof (TextValues); else if (vPnt == 2) pZ = atof (TextValues); else if (vPnt == 3) Intensity = atoi (TextValues); TVp = 0; vPnt ++; for (int i = 0; i <32; i ++) {TextValues ​​[i] = ' 0';}} else {TextValues ​​[TVp] = FileData [pCnt]; TVp ++;}} if (ExtentStarted) {Spatial-> MinX = (pX  MinX)? PX: Spatial-> MinX; Espacial-> MaxX = (pX> Espacial-> MaxX)? PX: Espacial-> MaxX; Espacial-> MinY = (pY  MinY)? PY: Espacial-> MinY; Espacial-> MaxY = (pY> Espacial-> MaxY)? PY: Espacial-> MaxY; Espacial-> MinZ = (pZ  MinZ)? PZ: Espacial-> MinZ; Espacial-> MaxZ = (pZ> Espacial-> MaxZ)? PZ: Espacial-> MaxZ;} else {Espacial-> MinX = pX; Espacial-> MaxX = pX; Espacial-> MinY = pY; Espacial-> MaxY = pY; Espacial-> MinZ = pZ; Espacial-> MaxZ = pZ; ExtentStarted = true;} Record-> X = pX * 100; Registro-> Y = pY * 100; Registro-> Z = pZ * 100; Record-> Intensity = Intensidad; OutLasFile.write ((char *) & Record-> X, 4); OutLasFile.write ((char *) & Record-> Y, 4); OutLasFile.write ((char *) & Record-> Z, 4); OutLasFile.write ((char *) & Record-> Intensity, 2); OutLasFile.write ((char *) & Record-> DataByte, 1); OutLasFile.write ((char *) & Registro-> Clasificación, 1); OutLasFile.write (Empty4,4); PointCount ++; eliminar [] FileData; }} while (! InFile.eof ()); OutLasFile.flush (); Segundo-> Point_by_Return_0 = PointCount; Segundo-> PointCount = PointCount; OutLasFile.seekp (105, estándar :: ios :: beg); OutLasFile.write ((char *) & Second-> Pt_DataRecLen, 2); OutLasFile.write ((char *) & Second-> PointCount, 4); OutLasFile.write ((char *) & Second-> Point_by_Return_0,4); OutLasFile.write (Empty4,4); // no escribir puntos por retorno OutLasFile.write (Empty4,4); OutLasFile.write (Empty4,4); OutLasFile.write (Empty4,4); OutLasFile.write ((char *) Spatial, sizeof (LAShdrSpatial)); InFile.close (); OutLasFile.close (); gratis (TextValues); libre (nName); gratis (InFilePath); gratis (OutFilePath); gratis (Primero); gratis (segundo); gratis (espacial); gratis (Grabar); libre (Empty4); } int _tmain (int argc, _TCHAR * argv []) {if (argc == 1) {printf ("XYZI formato delimitado por comas o espacios al convertidor LAS versión 1.1.  n"); printf (" n"); printf ("Herramienta escrita en C ++ por Michael Miles-Stimson de RPS Spatial  n"); printf (" n"); printf ("Convierte el archivo con formato X, Y, Z (, I) al formato LAS versión 1.2.  n"); printf ("Asegúrese de que no haya una línea de encabezado en el archivo XYZI  n"); printf ("Antes de ejecutar esta herramienta.  n"); printf (" n"); printf ("Esta herramienta convierte todos los archivos de la carpeta de entrada que tiene  n"); printf ("extensión .XYZI o .XYZ, nombrando el archivo con el nombre completo añadiendo  n"); printf (". las, es decir, abcd.xyzi se convierte en abcd_xyzi.las.  n"); printf (" nTodos los puntos tendrán una clasificación de 0  n"); printf (" n"); printf ("Uso: XYZI_To_LAS  n "); return 0;} char * fName = (char *) malloc (MaxTxtSize); char * dName = (char *) malloc (MaxTxtSize); wcstombs (dName, argv [1], MaxTxtSize); wchar_t * wtf = nuevo wchar_t [MaxTxtSize]; swprintf (wtf, MaxTxtSize, L "% s  *. XYZI", argv [1]); WIN32_FIND_DATA fData; HANDLE hFind; hFind = FindFirstFile (wtf, & fData); if (hFind! INVALID_HANDLE_VALUE) {wcstombs (fName, fData.cFileName, MaxTxtSize); // printf ("Primer archivo% s  n", fName); Convertir (dName, fName); while (FindNextFile (hFind, & fData)! = 0) { wcstombs (fName, fData.cFileName, MaxTxtSize); Convert (dName, fName); // printf (">% s  n", fName);}} swprintf (wtf, MaxTxtSize, L "% s  *. XYZ ", argv [1]); hFind = FindFirstFile (wtf, & fData); if (hFind! = INVALID_HANDLE_VALUE) {wcstombs (fName, fData.cFileName, MaxTxtSize); Convertir (dName, fName); while (FindNextFile (hDataFind, )! = 0) {wcstombs (fName, fData.cFileName, MaxTxtSize); Convert (dName, fName); // printf (">% s  n", fName);}} eliminar [] wtf; free (fName) ; gratis (dName); return 0;}

Esto convierte una carpeta de archivos XYZI en ASPRS LAS 1.2 con tipo de registro de puntos 0. La extensión debe ser XYZI pero puede estar delimitada por comas, espacios o tabulaciones. No hay muchos comentarios y es bastante descuidado, pero fue solo mi segundo programa en C ++. Copie y pegue el código en un nuevo proyecto de Visual C ++ (aplicación de consola), compile y luego ejecútelo en la línea de comandos.

Nota: He incrustado físicamente solo una parte de mi LASheader.h (2266 líneas en este encabezado) en este código, por lo que es posible que falte una estructura, lo revisé rápidamente y no puedo ver nada obvio.


El lector PDAL GDAL leerá cualquier fuente ráster legible por GDAL y la convertirá en una nube de puntos. A continuación, puede utilizar otras funciones de PDAL como filtro necesario y procesar los datos.


Ver el vídeo: Clip Raster in ArcMap Basic processing in GIS