Skip to content

Commit

Permalink
feat: support colorization for <0.2m clouds (including height=0/width=0)
Browse files Browse the repository at this point in the history
  • Loading branch information
CharlesGaydon committed Aug 8, 2023
1 parent 3cca39a commit 9a8fd43
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 15 deletions.
8 changes: 6 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
# dev

# 1.3.0
- color: support colorization for <0.2m clouds (including height=0/width=0)
- color: ceil width/height to have a bbox that contains all points

# 1.2.0
color: keep downloaded orthoimages by returning them to make them stay in executionn scope
- color: keep downloaded orthoimages by returning them to make them stay in execution scope

# 1.1.1
- unlock: fix main
Expand All @@ -11,7 +15,7 @@ color: keep downloaded orthoimages by returning them to make them stay in execut

# 1.1.0
- standardization: handle malformed laz input ("Global encoding WKT flag not set for point format 6 - 10")
color: extract unlock module from colorization and rename colorization function
- color: extract unlock module from colorization and rename colorization function

# 1.0.0
- first public version
Expand Down
2 changes: 1 addition & 1 deletion pdaltools/_version.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
__version__ = "1.2.0"
__version__ = "1.3.0"


if __name__ == "__main__":
Expand Down
84 changes: 72 additions & 12 deletions pdaltools/color.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import json
from math import ceil
import subprocess as sp
import tempfile
import pdal
Expand Down Expand Up @@ -45,7 +46,9 @@ def newfn(*args, **kwargs):
else:
raise err
if need_retry:
print(f"{attempt}/{times} Nouvel essai après une pause de {pretty_time_delta(new_delay)} .. ")
print(
f"{attempt}/{times} Nouvel essai après une pause de {pretty_time_delta(new_delay)} .. "
)
if not debug:
time.sleep(new_delay)
new_delay = new_delay * factor
Expand All @@ -58,13 +61,26 @@ def newfn(*args, **kwargs):
return decorator


def download_image_from_geoportail(proj, layer, minx, miny, maxx, maxy, pixel_per_meter, outfile, timeout):
def download_image_from_geoportail(
proj, layer, minx, miny, maxx, maxy, pixel_per_meter, outfile, timeout
):
# Give single-point clouds a width/height of at least one pixel to have valid BBOX and SIZE
if minx == maxx:
maxx = minx + 1 / pixel_per_meter
if miny == maxy:
maxy = miny + 1 / pixel_per_meter

# for layer in layers:
URL_GPP = "https://wxs.ign.fr/ortho/geoportail/r/wms?"
URL_FORMAT = "&EXCEPTIONS=text/xml&FORMAT=image/geotiff&SERVICE=WMS&VERSION=1.3.0&REQUEST=GetMap&STYLES="
URL_EPSG = "&CRS=EPSG:" + str(proj)
URL_BBOX = "&BBOX=" + str(minx) + "," + str(miny) + "," + str(maxx) + "," + str(maxy)
URL_SIZE = "&WIDTH=" + str(int((maxx - minx) * pixel_per_meter)) + "&HEIGHT=" + str(int((maxy - miny) * pixel_per_meter))
URL_SIZE = (
"&WIDTH="
+ str(ceil((maxx - minx) * pixel_per_meter))
+ "&HEIGHT="
+ str(ceil((maxy - miny) * pixel_per_meter))
)

URL = URL_GPP + "LAYERS=" + layer + URL_FORMAT + URL_EPSG + URL_BBOX + URL_SIZE

Expand Down Expand Up @@ -134,26 +150,48 @@ def color(

if veget_index_file and veget_index_file != "":
print(f"Remplissage du champ Deviation à partir du fichier {veget_index_file}")
pipeline |= pdal.Filter.colorization(raster=veget_index_file, dimensions="Deviation:1:256.0")
pipeline |= pdal.Filter.colorization(
raster=veget_index_file, dimensions="Deviation:1:256.0"
)
writer_extra_dims = ["Deviation=ushort"]

tmp_ortho = None
if color_rvb_enabled:
tmp_ortho = tempfile.NamedTemporaryFile().name
download_image_from_geoportail_retrying(
proj, "ORTHOIMAGERY.ORTHOPHOTOS", minx, miny, maxx, maxy, pixel_per_meter, tmp_ortho, timeout_second
proj,
"ORTHOIMAGERY.ORTHOPHOTOS",
minx,
miny,
maxx,
maxy,
pixel_per_meter,
tmp_ortho,
timeout_second,
)
pipeline |= pdal.Filter.colorization(
raster=tmp_ortho, dimensions="Red:1:256.0, Green:2:256.0, Blue:3:256.0"
)
pipeline |= pdal.Filter.colorization(raster=tmp_ortho, dimensions="Red:1:256.0, Green:2:256.0, Blue:3:256.0")

tmp_ortho_irc = None
if color_ir_enabled:
tmp_ortho_irc = tempfile.NamedTemporaryFile().name
download_image_from_geoportail_retrying(
proj, "ORTHOIMAGERY.ORTHOPHOTOS.IRC", minx, miny, maxx, maxy, pixel_per_meter, tmp_ortho_irc, timeout_second
proj,
"ORTHOIMAGERY.ORTHOPHOTOS.IRC",
minx,
miny,
maxx,
maxy,
pixel_per_meter,
tmp_ortho_irc,
timeout_second,
)
pipeline |= pdal.Filter.colorization(raster=tmp_ortho_irc, dimensions="Infrared:1:256.0")

pipeline |= pdal.Writer.las(filename=output_file, extra_dims=writer_extra_dims, minor_version="4", dataformat_id="8")
pipeline |= pdal.Writer.las(
filename=output_file, extra_dims=writer_extra_dims, minor_version="4", dataformat_id="8"
)

print("Traitement du nuage de point")
pipeline.execute()
Expand All @@ -168,15 +206,37 @@ def parse_args():
parser = argparse.ArgumentParser("Colorize tool")
parser.add_argument("--input", "-i", type=str, required=True, help="Input file")
parser.add_argument("--output", "-o", type=str, default="", help="Output file")
parser.add_argument("--proj", "-p", type=str, default="", help="Projection, default will use projection from metadata input")
parser.add_argument("--resolution", "-r", type=float, default=5, help="Resolution, in pixel per meter")
parser.add_argument(
"--proj",
"-p",
type=str,
default="",
help="Projection, default will use projection from metadata input",
)
parser.add_argument(
"--resolution", "-r", type=float, default=5, help="Resolution, in pixel per meter"
)
parser.add_argument("--timeout", "-t", type=int, default=300, help="Timeout, in seconds")
parser.add_argument("--rvb", action="store_true", help="Colorize RVB")
parser.add_argument("--ir", action="store_true", help="Colorize IR")
parser.add_argument("--vegetation", type=str, default="", help="Vegetation file, value will be stored in Deviation field")
parser.add_argument(
"--vegetation",
type=str,
default="",
help="Vegetation file, value will be stored in Deviation field",
)
return parser.parse_args()


if __name__ == "__main__":
args = parse_args()
color(args.input, args.output, args.proj, args.resolution, args.timeout, args.rvb, args.ir, args.vegetation)
color(
args.input,
args.output,
args.proj,
args.resolution,
args.timeout,
args.rvb,
args.ir,
args.vegetation,
)

0 comments on commit 9a8fd43

Please sign in to comment.