a `§»e&3ã@s,ddlZddlZddlZddlZddlZddlZddlmZddlmZddlm Z ddl m Z ddlm Z ddlm Z ddlmZdd lmZdd lmZmZdd lmZdd lmZdd lmZdd„Zd(dd„Zd)dd„Zd*dd„Zdd„Zdd„Z dd„Z!d+d d!„Z"d"d#„Z#d,d$d%„Z$d-d&d'„Z%dS).éN)Úsystem)Úlog)Úcontext)Úrun)Úentwine)Úio)Ú parallel_map)Ú double_quote)Ú as_polygonÚ as_geojson)Ú run_pipeline)Úclassify)ÚcommandscCs tj |¡std|ƒ‚d}d}d}t|dddÊ}| ¡ ¡ ¡}d}|dkrî| ¡ ¡ ¡}| d¡}t |ƒd krÔ|dd kr’|d d vr’d }|dd kr°|d dvr°d }n$|ddkrÔ|ddkrÔt |d ƒ}|d7}|dkrHtdƒ‚qHWdƒn1s0Y||||ddœS)Nz%s does not existFrÚrÚignore©ÚerrorsÚ end_headerÚ éÚpropertyé)ÚnxZnormalxZnormal_xT)ZviewsÚelementéÚvertexédú*Cannot find end_header field. Invalid PLY?)Ú has_normalsÚ vertex_countÚ has_viewsZ header_lines) ÚosÚpathÚexistsÚIOErrorÚopenÚreadlineÚstripÚlowerÚsplitÚlenÚint)Z input_plyrr rÚfÚlineÚiÚprops©r0ú/code/opendm/point_cloud.pyÚply_infos4     *ür2csØt d |¡¡tj |¡s6t d |¡¡t d¡tj ˆ¡sLt   ˆ¡t t  ˆ¡ƒdkrxt d ˆ¡¡t d¡d|tj  ˆ|¡|f}| d¡r¢|d7}|dur¶|d |7}t  |¡‡fd d „t  ˆ¡DƒS) Nz8Splitting point cloud filtering in chunks of {} verticeszG{} does not exist, cannot split point cloud. The program will now exit.rrz:%s already contains some files. The program will now exit.z)pdal split -i "%s" -o "%s" --capacity %s ú.plyzK--writers.ply.sized_types=false --writers.ply.storage_mode="little endian" ú--writers.ply.dims="%s"csg|]}tj ˆ|¡‘qSr0)r!r"Újoin)Ú.0r,©Úoutdirr0r1Ú Iózsplit..)rÚODM_INFOÚformatr!r"r#Ú ODM_ERRORÚsysÚexitrÚmkdir_pr*Úlistdirr5Úendswithr)Úinput_point_cloudr8Zfilename_templateZcapacityÚdimsÚcmdr0r7r1r)2s         r)ç@rc CsZtj |¡s&t d |¡¡t d¡d|d|d|g}|dkr`t d|¡|  d|¡d }t d  |||¡¡|  d |¡|  d |¡|  d |¡|durt d |¡¡t j dd\} } t  | ¡t | dƒ} |  t|ƒ¡Wdƒn1s0Y|  d| ¡t dtjd |¡f¡tj |¡sVt d |¡¡dS)z Filters a point cloud z-{} does not exist. The program will now exit.rz --input "%s"z --output "%s"z--concurrency %srz#Sampling points around a %sm radiusz --radius %séz;Filtering {} (statistical, meanK {}, standard deviation {})z --meank %sz--std %sz --stats "%s"Nz Boundary {}z.boundary.json©ÚsuffixÚwz--boundary "%s"z"%s" %srz#{} not found, filtering has failed.)r!r"r#rr=r<r>r?r;ÚappendÚtempfileÚmkstempÚcloser%Úwriter rrrÚfpcfilter_pathr5Ú ODM_WARNING) rCZoutput_point_cloudZ output_statsÚstandard_deviationZ sample_radiusÚboundaryÚmax_concurrencyÚargsZmeankÚfdZboundary_json_filer,r0r0r1ÚfilterLs2  ý   .rWç@cs¶‡‡fdd„}tj ˆ¡s |ƒStˆdƒx}t | ¡¡}d|vr€|d}|dkrjt|dƒWdƒS|ƒWdƒSn|ƒWdƒSWdƒn1s¨0YdS)Ncst dˆ¡ˆddS)Nz3Cannot read %s, falling back to resolution estimategY@g@)rrQr0©Úresolution_fallbackÚ stats_filer0r1Úfallbacksszget_spacing..fallbackrÚspacingrr)r!r"Úisfiler%ÚjsonÚloadsÚreadÚround)r[rZr\r,ÚjÚdr0rYr1Ú get_spacingrs  recCst d ||¡¡dS)Nz,pdal info --dimensions "X,Y,Z" "{0}" > "{1}"©rrr<)Úpointcloud_pathZinfo_file_pathr0r0r1Úexport_info_json…srhcCst d ||¡¡dS)Nú!pdal info --summary "{0}" > "{1}"rf)rgZsummary_file_pathr0r0r1Úexport_summary_json‰srjc Csôtjdd\}}t |¡d}| ¡ d¡r@d}td ||¡ƒz|sVtd ||¡ƒWn d}td ||¡ƒYn0i}t|dƒJ}t   |  ¡¡}|sÈ|  d ¡}|dur¼t d |ƒ‚|  d ¡}nh|  d ¡}|duræt d |ƒ‚|  d¡} | durt d|ƒ‚|   d¡} | dur&t d|ƒ‚|   d¡}|durFt d|ƒ‚|  dd¡dus²|  dd¡dus²|  dd¡dus²|  dd¡dus²|  dd¡dus²|  dd¡durÆt d|t|ƒfƒ‚Wdƒn1sÜ0Yt |¡|S)Nz.jsonrHFr3Tzpdal info "{0}" > "{1}"rirÚsummaryz3Cannot compute summary for %s (summary key missing)ÚboundsÚstatsz0Cannot compute bounds for %s (stats key missing)Úbboxz/Cannot compute bounds for %s (bbox key missing)Únativez1Cannot compute bounds for %s (native key missing)z1Cannot compute bounds for %s (bounds key missing)ZmaxxZminxZmaxyZminyZmaxzZminzz.Cannot compute bounds for %s (invalid keys) %s)rLrMr!rNr(rBrr<r%r_r`raÚgetÚ ExceptionÚstrÚremove) rCrVZ json_filer\rlr,Úresultrkrmrnror0r0r1Ú get_extentŒsR       ÿþýüû4 ruFcCspt|ƒ}|dkrt d¡dSt |¡r@t d|¡t |¡d tt |ƒ¡|dœ}t   dj fi|¤Ž¡dS)Nrú%No input point cloud files to processú!Removing previous point cloud: %sr)Z all_inputsÚoutputz&lasmerge -i {all_inputs} -o "{output}") r*rrQrÚ file_existsr!rsr5Úmapr rrr<)Úinput_point_cloud_filesÚ output_fileÚrerunÚ num_filesÚkwargsr0r0r1Úmerge¾s   þr€c CsÈt|ƒ}|dkrt d¡dSt |¡r@t d|¡t |¡tdd„|Dƒƒ}|d}t|dƒL}t|ddd ’}|  ¡}|  |  d ¡¡d}|  ¡  ¡d krú|  ¡}|  ¡ d ¡rÐ|  d |  d ¡¡n|  |  d ¡¡|d7}|dkr”tdƒ‚q”Wdƒn1s0Y|D]„} d}t| dƒ^} |   ¡}|  ¡  ¡dkrr|   ¡}|d7}|dkr:tdƒ‚q:|  |  ¡¡Wdƒn1s–0YqWdƒn1sº0Y|S)NrrvrwcSsg|]}t|ƒd‘qS)r)r2)r6Zpcfr0r0r1r9Ýr:z"fast_merge_ply..ÚwbrrrÚutf8rzelement vertex zelement vertex %s rrrÚrbs end_header)r*rrQrryr!rsÚsumr%r&rOÚencoder'r(Ú startswithr$ra) r{r|r~rZ master_fileÚoutZfheadr-r.ZipcÚfinr0r0r1Úfast_merge_plyÐsB   *   Rr‰c Csdt|ƒ}|dkrt d¡dSdddd|dur6d|ndd  tt||gƒ¡g}t d  |¡¡dS) NrrvZpdalr€z--writers.ply.sized_types=falsez*--writers.ply.storage_mode="little endian"r4Úr)r*rrQr5rzr rr)r{r|rDr~rEr0r0r1Ú merge_plys ú r‹cCs|jrîtj |jd¡}t |¡r$|rît d  |j ¡¡t   |j |j |j|j|j¡t d  |j ¡¡t |j |jƒt|dƒb}| d¡| d  |j ¡¡| d  |j¡¡| d  |j¡¡| d   |j¡¡Wdƒn1sä0Y|jrt  |j ¡|jrPt d ¡t |j¡r(|r@t d   |j |j¡¡nt d |j¡|jržt d ¡t |j¡rv|rŽt d  |j |j¡¡nt d|j¡|jrÊt d¡tj|j g|j |j|d|j!rt d¡tj"|j dd}tj#|j g|dddS)Nzpc_classify_done.txtz6Classifying {} using Simple Morphological Filter (1/2)z)Classifying {} using OpenPointClass (2/2)rJzClassify: smrf z Scalar: {} z Slope: {} zThreshold: {} z Window: {} zCreating CSV file (XYZ format)z|pdal translate -i "{}" -o "{}" --writers.text.format=csv --writers.text.order="X,Y,Z" --writers.text.keep_unspecified=false zFound existing CSV file %szCreating LAS filezpdal translate -i "{}" -o "{}" zFound existing LAS file %sz"Creating Entwine Point Tile output)rTr}z+Creating Cloud Optimized Point Cloud (COPC)z.copc)ÚpostfixT)Zconvert_rgb_8_to_16)$Ú pc_classifyr!r"r5Úodm_georeferencingrryrr;r<Úodm_georeferencing_model_lazrr Ú smrf_scalarÚ smrf_slopeÚsmrf_thresholdÚ smrf_windowrTr%rOÚ pc_rectifyZrectifyÚpc_csvÚodm_georeferencing_xyz_filerrrQÚpc_lasÚodm_georeferencing_model_lasÚpc_eptrÚbuildÚentwine_pointcloudÚpc_copcÚrelated_file_pathZ build_copc)rUÚtreer}Zpc_classify_markerr,Z copc_outputr0r0r1Úpost_point_cloud_stepssVü  0  ú ý  rŸ)N)rFrNr)rX)F)N)F)&r!r>ÚshutilrLÚmathr_ÚopendmrrrZ opendm.systemrrrÚopendm.concurrencyrÚ opendm.utilsr Zopendm.boundaryr r Zopendm.dem.pdalr Z opendm.opcr Z opendm.demrr2r)rWrerhrjrur€r‰r‹rŸr0r0r0r1Ús.0           #  & 2 5