From 6914f4ef9a61373905e5d08694807f460a5e940d Mon Sep 17 00:00:00 2001 From: Alex-Lewandowski Date: Fri, 31 May 2024 13:21:02 -0800 Subject: [PATCH 1/6] convert UTM coords to WGS84 in write_kmz_overlay --- src/mintpy/save_kmz.py | 273 ++++++++++++++++++++++------------------- 1 file changed, 150 insertions(+), 123 deletions(-) diff --git a/src/mintpy/save_kmz.py b/src/mintpy/save_kmz.py index 4e78222b4..0a32dbd3e 100644 --- a/src/mintpy/save_kmz.py +++ b/src/mintpy/save_kmz.py @@ -13,43 +13,61 @@ import numpy as np from lxml import etree -from matplotlib import colorbar, colors, pyplot as plt, ticker +from matplotlib import colorbar, colors +from matplotlib import pyplot as plt +from matplotlib import ticker from pykml.factory import KML_ElementMaker as KML import mintpy from mintpy import subset -from mintpy.utils import ( - attribute as attr, - plot as pp, - ptime, - readfile, - utils as ut, -) +from mintpy.utils import attribute as attr +from mintpy.utils import plot as pp +from mintpy.utils import ptime, readfile +from mintpy.utils import utils as ut +from mintpy.utils import utils0 as ut0 ############################################################ -def plot_colorbar(out_file, vmin, vmax, unit='cm/year', cmap='jet', figsize=(0.18, 3.6), - nbins=None, label='Mean LOS velocity'): +def plot_colorbar( + out_file, + vmin, + vmax, + unit="cm/year", + cmap="jet", + figsize=(0.18, 3.6), + nbins=None, + label="Mean LOS velocity", +): fig, cax = plt.subplots(figsize=figsize) norm = colors.Normalize(vmin=vmin, vmax=vmax) - cbar = colorbar.ColorbarBase(cax, cmap=plt.get_cmap(cmap), norm=norm, orientation='vertical') - cbar.set_label(f'{label} [{unit}]', fontsize=12) + cbar = colorbar.ColorbarBase( + cax, cmap=plt.get_cmap(cmap), norm=norm, orientation="vertical" + ) + cbar.set_label(f"{label} [{unit}]", fontsize=12) # update ticks if nbins: cbar.locator = ticker.MaxNLocator(nbins=nbins) cbar.update_ticks() - cbar.ax.tick_params(which='both', labelsize=12) - fig.patch.set_facecolor('white') + cbar.ax.tick_params(which="both", labelsize=12) + fig.patch.set_facecolor("white") fig.patch.set_alpha(0.7) - print('writing', out_file) - fig.savefig(out_file, bbox_inches='tight', facecolor=fig.get_facecolor(), dpi=300) + print("writing", out_file) + fig.savefig(out_file, bbox_inches="tight", facecolor=fig.get_facecolor(), dpi=300) return out_file -def generate_cbar_element(cbar_file, cmap, vmin, vmax, unit='cm/year', loc='lower left', - nbins=None, label='Mean LOS velocity'): +def generate_cbar_element( + cbar_file, + cmap, + vmin, + vmax, + unit="cm/year", + loc="lower left", + nbins=None, + label="Mean LOS velocity", +): """Generate colorbar as an screen overlay object. Parameters: cbar_file - str, colorbar image file path @@ -68,33 +86,31 @@ def generate_cbar_element(cbar_file, cmap, vmin, vmax, unit='cm/year', loc='lowe unit=unit, cmap=cmap, nbins=nbins, - label=label) + label=label, + ) # colobar location - if loc.split()[0] == 'lower': - oy, sy = '0', '0' - elif loc.split()[0] == 'upper': - oy, sy = '1', '1' - if loc.split()[1] == 'left': - ox, sx = '0', '0' - elif loc.split()[1] == 'right': - ox, sx = '1', '1' + if loc.split()[0] == "lower": + oy, sy = "0", "0" + elif loc.split()[0] == "upper": + oy, sy = "1", "1" + if loc.split()[1] == "left": + ox, sx = "0", "0" + elif loc.split()[1] == "right": + ox, sx = "1", "1" # generate KML screen overlay object cbar_overlay = KML.ScreenOverlay( - KML.name('colorbar'), - KML.Icon( - KML.href(f"{os.path.basename(cbar_file)}"), - KML.viewBoundScale(0.75) - ), + KML.name("colorbar"), + KML.Icon(KML.href(f"{os.path.basename(cbar_file)}"), KML.viewBoundScale(0.75)), KML.overlayXY(x=ox, y=oy, xunits="fraction", yunits="fraction"), KML.screenXY(x=sx, y=sy, xunits="fraction", yunits="fraction"), KML.size(x="0", y="250", xunits="pixel", yunits="pixel"), KML.rotation(0), KML.visibility(1), - KML.open(0) + KML.open(0), ) - #print('add colorbar.') + # print('add colorbar.') return cbar_overlay @@ -126,13 +142,13 @@ def create_placemark_element(lat, lon, row, col, val, icon_file, inps): # style KML.Style( KML.IconStyle( - KML.color(get_hex_color(val, inps.colormap, inps.norm)), - KML.scale(0.5), - KML.Icon(KML.href(icon_file), + KML.color(get_hex_color(val, inps.colormap, inps.norm)), + KML.scale(0.5), + KML.Icon( + KML.href(icon_file), ), ), ), - # extended data KML.ExtendedData( KML.Data( @@ -156,7 +172,6 @@ def create_placemark_element(lat, lon, row, col, val, icon_file, inps): name="Value", ), ), - # point coord KML.Point( KML.coordinates(f"{lon},{lat}"), @@ -166,7 +181,9 @@ def create_placemark_element(lat, lon, row, col, val, icon_file, inps): return placemark -def write_kmz_file(out_file_base, kml_doc, data_files=None, res_files=None, keep_kml_file=False): +def write_kmz_file( + out_file_base, kml_doc, data_files=None, res_files=None, keep_kml_file=False +): """Write KML and KMZ files. Parameters: out_file_base - str, output file name without extension kml_doc - KML.Document() object @@ -177,19 +194,19 @@ def write_kmz_file(out_file_base, kml_doc, data_files=None, res_files=None, keep """ # default values data_files = [] if data_files is None else data_files - res_files = [] if res_files is None else res_files + res_files = [] if res_files is None else res_files work_dir = os.path.dirname(out_file_base) - kml_file = f'{out_file_base}.kml' - kmz_file = f'{out_file_base}.kmz' + kml_file = f"{out_file_base}.kml" + kmz_file = f"{out_file_base}.kmz" # 1. Write KML file kml = KML.kml() kml.append(kml_doc) - print('writing '+kml_file) - with open(kml_file, 'w') as f: - f.write(etree.tostring(kml, pretty_print=True).decode('utf8')) + print("writing " + kml_file) + with open(kml_file, "w") as f: + f.write(etree.tostring(kml, pretty_print=True).decode("utf8")) # 2. Copy resource files if res_files: @@ -205,16 +222,16 @@ def write_kmz_file(out_file_base, kml_doc, data_files=None, res_files=None, keep os.chdir(work_dir) # 2) zip all data files - with ZipFile(kmz_file, 'w') as fz: + with ZipFile(kmz_file, "w") as fz: for fname in [kml_file] + data_files + res_files: fz.write(os.path.relpath(fname)) if not keep_kml_file: os.remove(fname) - print(f'remove {fname}') + print(f"remove {fname}") # 3) go back to the running directory os.chdir(run_dir) - print(f'merged all files to {kmz_file}') + print(f"merged all files to {kmz_file}") return kmz_file @@ -233,40 +250,54 @@ def write_kmz_overlay(data, meta, out_file, inps): """ south, north, west, east = ut.four_corners(meta) + north, east = ut0.utm2latlon(meta, east, north) + south, west = ut0.utm2latlon(meta, west, south) # 1. Make PNG file - Data - print('plotting data ...') + print("plotting data ...") # Figure size if not inps.fig_size: - inps.fig_size = pp.auto_figure_size(ds_shape=[north-south, east-west], scale=2.0) + inps.fig_size = pp.auto_figure_size( + ds_shape=[north - south, east - west], scale=2.0 + ) fig = plt.figure(figsize=inps.fig_size, frameon=False) - ax = fig.add_axes([0., 0., 1., 1.]) + ax = fig.add_axes([0.0, 0.0, 1.0, 1.0]) ax.set_axis_off() # Plot - data matrix - ax.imshow(data, vmin=inps.vlim[0], vmax=inps.vlim[1], cmap=inps.colormap, - aspect='auto', interpolation='nearest') + ax.imshow( + data, + vmin=inps.vlim[0], + vmax=inps.vlim[1], + cmap=inps.colormap, + aspect="auto", + interpolation="nearest", + ) # Plot - reference pixel - rx = meta.get('REF_X', None) - ry = meta.get('REF_Y', None) + rx = meta.get("REF_X", None) + ry = meta.get("REF_Y", None) if inps.disp_ref_pixel and rx is not None and ry is not None: - ax.plot(int(rx), int(ry), inps.ref_marker, - color=inps.ref_marker_color, - ms=inps.ref_marker_size) - print('show reference point') + ax.plot( + int(rx), + int(ry), + inps.ref_marker, + color=inps.ref_marker_color, + ms=inps.ref_marker_size, + ) + print("show reference point") else: - print('no plot for reference point.') + print("no plot for reference point.") - width = int(meta['WIDTH']) - length = int(meta['LENGTH']) + width = int(meta["WIDTH"]) + length = int(meta["LENGTH"]) ax.set_xlim([0, width]) ax.set_ylim([length, 0]) out_file_base = os.path.splitext(out_file)[0] - data_png_file = out_file_base + '_data.png' - print(f'writing {data_png_file} with dpi={inps.fig_dpi}') + data_png_file = out_file_base + "_data.png" + print(f"writing {data_png_file} with dpi={inps.fig_dpi}") plt.savefig(data_png_file, pad_inches=0.0, transparent=True, dpi=inps.fig_dpi) # 2. Generate KML file @@ -276,10 +307,8 @@ def write_kmz_overlay(data, meta, out_file, inps): img_name = os.path.splitext(os.path.basename(data_png_file))[0] img_overlay = KML.GroundOverlay( KML.name(img_name), - KML.Icon( - KML.href(os.path.basename(data_png_file)) - ), - KML.altitudeMode('clampToGround'), + KML.Icon(KML.href(os.path.basename(data_png_file))), + KML.altitudeMode("clampToGround"), KML.LatLonBox( KML.north(str(north)), KML.east(str(east)), @@ -290,7 +319,7 @@ def write_kmz_overlay(data, meta, out_file, inps): kml_doc.append(img_overlay) # Add colorbar png file - cbar_file = f'{out_file_base}_cbar.png' + cbar_file = f"{out_file_base}_cbar.png" cbar_overlay = generate_cbar_element( cbar_file, cmap=inps.colormap, @@ -299,7 +328,8 @@ def write_kmz_overlay(data, meta, out_file, inps): unit=inps.disp_unit, loc=inps.cbar_loc, nbins=inps.cbar_bin_num, - label=inps.cbar_label) + label=inps.cbar_label, + ) kml_doc.append(cbar_overlay) # Write KML file @@ -307,7 +337,8 @@ def write_kmz_overlay(data, meta, out_file, inps): out_file_base, kml_doc, data_files=[data_png_file, cbar_file], - keep_kml_file=inps.keep_kml_file) + keep_kml_file=inps.keep_kml_file, + ) return kmz_file @@ -326,19 +357,19 @@ def write_kmz_placemark(data, meta, out_file, geom_file, inps): """ out_file_base = os.path.splitext(out_file)[0] - dot_file = 'shaded_dot.png' - star_file = 'star.png' + dot_file = "shaded_dot.png" + star_file = "star.png" # read latitude / longitude - lats = readfile.read(geom_file, datasetName='latitude', box=inps.pix_box)[0] - lons = readfile.read(geom_file, datasetName='longitude', box=inps.pix_box)[0] + lats = readfile.read(geom_file, datasetName="latitude", box=inps.pix_box)[0] + lons = readfile.read(geom_file, datasetName="longitude", box=inps.pix_box)[0] ## Generate KML file kml_doc = KML.Document() # 1. colorbar png file - print('plot and add colorbar as a ScreenOverlay element') - cbar_file = f'{out_file_base}_cbar.png' + print("plot and add colorbar as a ScreenOverlay element") + cbar_file = f"{out_file_base}_cbar.png" cbar_overlay = generate_cbar_element( cbar_file, cmap=inps.colormap, @@ -347,16 +378,17 @@ def write_kmz_placemark(data, meta, out_file, geom_file, inps): unit=inps.disp_unit, loc=inps.cbar_loc, nbins=inps.cbar_bin_num, - label=inps.cbar_label) + label=inps.cbar_label, + ) kml_doc.append(cbar_overlay) # 2. reference point - xmin = int(meta.get('SUBSET_XMIN', 0)) - ymin = int(meta.get('SUBSET_YMIN', 0)) + xmin = int(meta.get("SUBSET_XMIN", 0)) + ymin = int(meta.get("SUBSET_YMIN", 0)) - if 'REF_Y' in meta.keys(): - print('add reference point as a star icon') - ry, rx = int(meta['REF_Y']), int(meta['REF_X']) + if "REF_Y" in meta.keys(): + print("add reference point as a star icon") + ry, rx = int(meta["REF_Y"]), int(meta["REF_X"]) rlat = lats[ry, rx] rlon = lons[ry, rx] ref_point = create_placemark_element( @@ -366,8 +398,9 @@ def write_kmz_placemark(data, meta, out_file, geom_file, inps): col=rx + xmin, val=0.0, icon_file=star_file, - inps=inps) - ref_point.name = 'ReferencePoint' + inps=inps, + ) + ref_point.name = "ReferencePoint" ref_point.Style.IconStyle.scale = 1.0 kml_doc.append(ref_point) @@ -377,7 +410,7 @@ def write_kmz_placemark(data, meta, out_file, geom_file, inps): # 3. data folder for all points data_folder = KML.Folder(KML.name("Data")) - print(f'generating point element with step size of {inps.step} pixels') + print(f"generating point element with step size of {inps.step} pixels") length, width = data.shape prog_bar = ptime.progressBar(maxValue=length) for y in range(0, length, inps.step): @@ -395,10 +428,11 @@ def write_kmz_placemark(data, meta, out_file, geom_file, inps): col=x + xmin, val=value, icon_file=dot_file, - inps=inps) + inps=inps, + ) data_folder.append(placemark) - prog_bar.update(y+1, every=1, suffix=f'row={y+1}/{length}') + prog_bar.update(y + 1, every=1, suffix=f"row={y+1}/{length}") prog_bar.close() kml_doc.append(data_folder) @@ -408,7 +442,8 @@ def write_kmz_placemark(data, meta, out_file, geom_file, inps): kml_doc, data_files=[cbar_file], res_files=[dot_file, star_file], - keep_kml_file=inps.keep_kml_file) + keep_kml_file=inps.keep_kml_file, + ) return kmz_file @@ -417,12 +452,12 @@ def write_kmz_placemark(data, meta, out_file, geom_file, inps): def save_kmz(inps): # matplotlib backend setting - plt.switch_backend('Agg') + plt.switch_backend("Agg") ## 1. Read metadata and data - ftype = readfile.read_attribute(inps.file)['FILE_TYPE'] - if ftype == 'timeseries' and inps.dset and '_' in inps.dset: - inps.ref_date, inps.dset = inps.dset.split('_') + ftype = readfile.read_attribute(inps.file)["FILE_TYPE"] + if ftype == "timeseries" and inps.dset and "_" in inps.dset: + inps.ref_date, inps.dset = inps.dset.split("_") else: inps.ref_date = None atr = readfile.read_attribute(inps.file, datasetName=inps.dset) @@ -430,42 +465,41 @@ def save_kmz(inps): # pix_box inps.pix_box = subset.subset_input_dict2box(vars(inps), atr)[0] inps.pix_box = ut.coordinate(atr).check_box_within_data_coverage(inps.pix_box) - data_box = (0, 0, int(atr['WIDTH']), int(atr['LENGTH'])) - print(f'data coverage in y/x: {data_box}') - print(f'subset coverage in y/x: {inps.pix_box}') + data_box = (0, 0, int(atr["WIDTH"]), int(atr["LENGTH"])) + print(f"data coverage in y/x: {data_box}") + print(f"subset coverage in y/x: {inps.pix_box}") atr = attr.update_attribute4subset(atr, inps.pix_box) # read data data = readfile.read(inps.file, datasetName=inps.dset, box=inps.pix_box)[0] - if ftype == 'timeseries' and inps.ref_date: + if ftype == "timeseries" and inps.ref_date: data -= readfile.read(inps.file, datasetName=inps.ref_date, box=inps.pix_box)[0] # mask mask = pp.read_mask( - inps.file, - mask_file=inps.mask_file, - datasetName=inps.dset, - box=inps.pix_box)[0] + inps.file, mask_file=inps.mask_file, datasetName=inps.dset, box=inps.pix_box + )[0] if mask is not None: - print(f'masking out pixels with zero value in file: {inps.mask_file}') + print(f"masking out pixels with zero value in file: {inps.mask_file}") data[mask == 0] = np.nan if inps.zero_mask: - print('masking out pixels with zero value') + print("masking out pixels with zero value") data[data == 0] = np.nan del mask # Data Operation - Display Unit & Rewrapping - data, inps.disp_unit, inps.disp_scale, inps.wrap = pp.scale_data4disp_unit_and_rewrap( - data, - metadata=atr, - disp_unit=inps.disp_unit, - wrap=inps.wrap, - wrap_range=inps.wrap_range, + data, inps.disp_unit, inps.disp_scale, inps.wrap = ( + pp.scale_data4disp_unit_and_rewrap( + data, + metadata=atr, + disp_unit=inps.disp_unit, + wrap=inps.wrap, + wrap_range=inps.wrap_range, + ) ) if inps.wrap: inps.vlim = inps.wrap_range - ## 2. Generate Google Earth KMZ # disp min/max and colormap cmap_lut = 256 @@ -477,25 +511,18 @@ def save_kmz(inps): # output filename inps.fig_title = pp.auto_figure_title(inps.file, inps.dset, vars(inps)) - inps.outfile = inps.outfile if inps.outfile else f'{inps.fig_title}.kmz' + inps.outfile = inps.outfile if inps.outfile else f"{inps.fig_title}.kmz" inps.outfile = os.path.abspath(inps.outfile) # write KMZ file - if 'Y_FIRST' in atr.keys(): + if "Y_FIRST" in atr.keys(): # create ground overlay KML for file in geo-coord - write_kmz_overlay( - data, - meta=atr, - out_file=inps.outfile, - inps=inps) + write_kmz_overlay(data, meta=atr, out_file=inps.outfile, inps=inps) else: # create placemark KML for file in radar-coord write_kmz_placemark( - data, - meta=atr, - out_file=inps.outfile, - geom_file=inps.geom_file, - inps=inps) + data, meta=atr, out_file=inps.outfile, geom_file=inps.geom_file, inps=inps + ) return From 6db906aef0b0a363337a8a4b43a34c884173fac9 Mon Sep 17 00:00:00 2001 From: Alex-Lewandowski Date: Fri, 31 May 2024 13:38:14 -0800 Subject: [PATCH 2/6] check for UTM_ZONE in metadata before converting bbox coords to wgs84 --- src/mintpy/save_kmz.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/mintpy/save_kmz.py b/src/mintpy/save_kmz.py index 0a32dbd3e..b34bf3129 100644 --- a/src/mintpy/save_kmz.py +++ b/src/mintpy/save_kmz.py @@ -250,8 +250,9 @@ def write_kmz_overlay(data, meta, out_file, inps): """ south, north, west, east = ut.four_corners(meta) - north, east = ut0.utm2latlon(meta, east, north) - south, west = ut0.utm2latlon(meta, west, south) + if "UTM_ZONE" in meta.keys(): + north, east = ut0.utm2latlon(meta, east, north) + south, west = ut0.utm2latlon(meta, west, south) # 1. Make PNG file - Data print("plotting data ...") From 5a2431290e4d11b12dfc470aee5b3a36d036d840 Mon Sep 17 00:00:00 2001 From: Alex-Lewandowski Date: Fri, 31 May 2024 14:09:21 -0800 Subject: [PATCH 3/6] undo extensive formatting --- src/mintpy/save_kmz.py | 274 +++++++++++++++++++---------------------- 1 file changed, 125 insertions(+), 149 deletions(-) diff --git a/src/mintpy/save_kmz.py b/src/mintpy/save_kmz.py index b34bf3129..88e5eb4ae 100644 --- a/src/mintpy/save_kmz.py +++ b/src/mintpy/save_kmz.py @@ -13,61 +13,44 @@ import numpy as np from lxml import etree -from matplotlib import colorbar, colors -from matplotlib import pyplot as plt -from matplotlib import ticker +from matplotlib import colorbar, colors, pyplot as plt, ticker from pykml.factory import KML_ElementMaker as KML import mintpy from mintpy import subset -from mintpy.utils import attribute as attr -from mintpy.utils import plot as pp -from mintpy.utils import ptime, readfile -from mintpy.utils import utils as ut -from mintpy.utils import utils0 as ut0 +from mintpy.utils import ( + attribute as attr, + plot as pp, + ptime, + readfile, + utils as ut, + utils0 as ut0, +) ############################################################ -def plot_colorbar( - out_file, - vmin, - vmax, - unit="cm/year", - cmap="jet", - figsize=(0.18, 3.6), - nbins=None, - label="Mean LOS velocity", -): +def plot_colorbar(out_file, vmin, vmax, unit='cm/year', cmap='jet', figsize=(0.18, 3.6), + nbins=None, label='Mean LOS velocity'): fig, cax = plt.subplots(figsize=figsize) norm = colors.Normalize(vmin=vmin, vmax=vmax) - cbar = colorbar.ColorbarBase( - cax, cmap=plt.get_cmap(cmap), norm=norm, orientation="vertical" - ) - cbar.set_label(f"{label} [{unit}]", fontsize=12) + cbar = colorbar.ColorbarBase(cax, cmap=plt.get_cmap(cmap), norm=norm, orientation='vertical') + cbar.set_label(f'{label} [{unit}]', fontsize=12) # update ticks if nbins: cbar.locator = ticker.MaxNLocator(nbins=nbins) cbar.update_ticks() - cbar.ax.tick_params(which="both", labelsize=12) - fig.patch.set_facecolor("white") + cbar.ax.tick_params(which='both', labelsize=12) + fig.patch.set_facecolor('white') fig.patch.set_alpha(0.7) - print("writing", out_file) - fig.savefig(out_file, bbox_inches="tight", facecolor=fig.get_facecolor(), dpi=300) + print('writing', out_file) + fig.savefig(out_file, bbox_inches='tight', facecolor=fig.get_facecolor(), dpi=300) return out_file -def generate_cbar_element( - cbar_file, - cmap, - vmin, - vmax, - unit="cm/year", - loc="lower left", - nbins=None, - label="Mean LOS velocity", -): +def generate_cbar_element(cbar_file, cmap, vmin, vmax, unit='cm/year', loc='lower left', + nbins=None, label='Mean LOS velocity'): """Generate colorbar as an screen overlay object. Parameters: cbar_file - str, colorbar image file path @@ -86,31 +69,33 @@ def generate_cbar_element( unit=unit, cmap=cmap, nbins=nbins, - label=label, - ) + label=label) # colobar location - if loc.split()[0] == "lower": - oy, sy = "0", "0" - elif loc.split()[0] == "upper": - oy, sy = "1", "1" - if loc.split()[1] == "left": - ox, sx = "0", "0" - elif loc.split()[1] == "right": - ox, sx = "1", "1" + if loc.split()[0] == 'lower': + oy, sy = '0', '0' + elif loc.split()[0] == 'upper': + oy, sy = '1', '1' + if loc.split()[1] == 'left': + ox, sx = '0', '0' + elif loc.split()[1] == 'right': + ox, sx = '1', '1' # generate KML screen overlay object cbar_overlay = KML.ScreenOverlay( - KML.name("colorbar"), - KML.Icon(KML.href(f"{os.path.basename(cbar_file)}"), KML.viewBoundScale(0.75)), + KML.name('colorbar'), + KML.Icon( + KML.href(f"{os.path.basename(cbar_file)}"), + KML.viewBoundScale(0.75) + ), KML.overlayXY(x=ox, y=oy, xunits="fraction", yunits="fraction"), KML.screenXY(x=sx, y=sy, xunits="fraction", yunits="fraction"), KML.size(x="0", y="250", xunits="pixel", yunits="pixel"), KML.rotation(0), KML.visibility(1), - KML.open(0), + KML.open(0) ) - # print('add colorbar.') + #print('add colorbar.') return cbar_overlay @@ -142,13 +127,13 @@ def create_placemark_element(lat, lon, row, col, val, icon_file, inps): # style KML.Style( KML.IconStyle( - KML.color(get_hex_color(val, inps.colormap, inps.norm)), - KML.scale(0.5), - KML.Icon( - KML.href(icon_file), + KML.color(get_hex_color(val, inps.colormap, inps.norm)), + KML.scale(0.5), + KML.Icon(KML.href(icon_file), ), ), ), + # extended data KML.ExtendedData( KML.Data( @@ -172,6 +157,7 @@ def create_placemark_element(lat, lon, row, col, val, icon_file, inps): name="Value", ), ), + # point coord KML.Point( KML.coordinates(f"{lon},{lat}"), @@ -181,9 +167,7 @@ def create_placemark_element(lat, lon, row, col, val, icon_file, inps): return placemark -def write_kmz_file( - out_file_base, kml_doc, data_files=None, res_files=None, keep_kml_file=False -): +def write_kmz_file(out_file_base, kml_doc, data_files=None, res_files=None, keep_kml_file=False): """Write KML and KMZ files. Parameters: out_file_base - str, output file name without extension kml_doc - KML.Document() object @@ -194,19 +178,19 @@ def write_kmz_file( """ # default values data_files = [] if data_files is None else data_files - res_files = [] if res_files is None else res_files + res_files = [] if res_files is None else res_files work_dir = os.path.dirname(out_file_base) - kml_file = f"{out_file_base}.kml" - kmz_file = f"{out_file_base}.kmz" + kml_file = f'{out_file_base}.kml' + kmz_file = f'{out_file_base}.kmz' # 1. Write KML file kml = KML.kml() kml.append(kml_doc) - print("writing " + kml_file) - with open(kml_file, "w") as f: - f.write(etree.tostring(kml, pretty_print=True).decode("utf8")) + print('writing '+kml_file) + with open(kml_file, 'w') as f: + f.write(etree.tostring(kml, pretty_print=True).decode('utf8')) # 2. Copy resource files if res_files: @@ -222,16 +206,16 @@ def write_kmz_file( os.chdir(work_dir) # 2) zip all data files - with ZipFile(kmz_file, "w") as fz: + with ZipFile(kmz_file, 'w') as fz: for fname in [kml_file] + data_files + res_files: fz.write(os.path.relpath(fname)) if not keep_kml_file: os.remove(fname) - print(f"remove {fname}") + print(f'remove {fname}') # 3) go back to the running directory os.chdir(run_dir) - print(f"merged all files to {kmz_file}") + print(f'merged all files to {kmz_file}') return kmz_file @@ -255,50 +239,38 @@ def write_kmz_overlay(data, meta, out_file, inps): south, west = ut0.utm2latlon(meta, west, south) # 1. Make PNG file - Data - print("plotting data ...") + print('plotting data ...') # Figure size if not inps.fig_size: - inps.fig_size = pp.auto_figure_size( - ds_shape=[north - south, east - west], scale=2.0 - ) + inps.fig_size = pp.auto_figure_size(ds_shape=[north-south, east-west], scale=2.0) fig = plt.figure(figsize=inps.fig_size, frameon=False) - ax = fig.add_axes([0.0, 0.0, 1.0, 1.0]) + ax = fig.add_axes([0., 0., 1., 1.]) ax.set_axis_off() # Plot - data matrix - ax.imshow( - data, - vmin=inps.vlim[0], - vmax=inps.vlim[1], - cmap=inps.colormap, - aspect="auto", - interpolation="nearest", - ) + ax.imshow(data, vmin=inps.vlim[0], vmax=inps.vlim[1], cmap=inps.colormap, + aspect='auto', interpolation='nearest') # Plot - reference pixel - rx = meta.get("REF_X", None) - ry = meta.get("REF_Y", None) + rx = meta.get('REF_X', None) + ry = meta.get('REF_Y', None) if inps.disp_ref_pixel and rx is not None and ry is not None: - ax.plot( - int(rx), - int(ry), - inps.ref_marker, - color=inps.ref_marker_color, - ms=inps.ref_marker_size, - ) - print("show reference point") + ax.plot(int(rx), int(ry), inps.ref_marker, + color=inps.ref_marker_color, + ms=inps.ref_marker_size) + print('show reference point') else: - print("no plot for reference point.") + print('no plot for reference point.') - width = int(meta["WIDTH"]) - length = int(meta["LENGTH"]) + width = int(meta['WIDTH']) + length = int(meta['LENGTH']) ax.set_xlim([0, width]) ax.set_ylim([length, 0]) out_file_base = os.path.splitext(out_file)[0] - data_png_file = out_file_base + "_data.png" - print(f"writing {data_png_file} with dpi={inps.fig_dpi}") + data_png_file = out_file_base + '_data.png' + print(f'writing {data_png_file} with dpi={inps.fig_dpi}') plt.savefig(data_png_file, pad_inches=0.0, transparent=True, dpi=inps.fig_dpi) # 2. Generate KML file @@ -308,8 +280,10 @@ def write_kmz_overlay(data, meta, out_file, inps): img_name = os.path.splitext(os.path.basename(data_png_file))[0] img_overlay = KML.GroundOverlay( KML.name(img_name), - KML.Icon(KML.href(os.path.basename(data_png_file))), - KML.altitudeMode("clampToGround"), + KML.Icon( + KML.href(os.path.basename(data_png_file)) + ), + KML.altitudeMode('clampToGround'), KML.LatLonBox( KML.north(str(north)), KML.east(str(east)), @@ -320,7 +294,7 @@ def write_kmz_overlay(data, meta, out_file, inps): kml_doc.append(img_overlay) # Add colorbar png file - cbar_file = f"{out_file_base}_cbar.png" + cbar_file = f'{out_file_base}_cbar.png' cbar_overlay = generate_cbar_element( cbar_file, cmap=inps.colormap, @@ -329,8 +303,7 @@ def write_kmz_overlay(data, meta, out_file, inps): unit=inps.disp_unit, loc=inps.cbar_loc, nbins=inps.cbar_bin_num, - label=inps.cbar_label, - ) + label=inps.cbar_label) kml_doc.append(cbar_overlay) # Write KML file @@ -338,8 +311,7 @@ def write_kmz_overlay(data, meta, out_file, inps): out_file_base, kml_doc, data_files=[data_png_file, cbar_file], - keep_kml_file=inps.keep_kml_file, - ) + keep_kml_file=inps.keep_kml_file) return kmz_file @@ -358,19 +330,19 @@ def write_kmz_placemark(data, meta, out_file, geom_file, inps): """ out_file_base = os.path.splitext(out_file)[0] - dot_file = "shaded_dot.png" - star_file = "star.png" + dot_file = 'shaded_dot.png' + star_file = 'star.png' # read latitude / longitude - lats = readfile.read(geom_file, datasetName="latitude", box=inps.pix_box)[0] - lons = readfile.read(geom_file, datasetName="longitude", box=inps.pix_box)[0] + lats = readfile.read(geom_file, datasetName='latitude', box=inps.pix_box)[0] + lons = readfile.read(geom_file, datasetName='longitude', box=inps.pix_box)[0] ## Generate KML file kml_doc = KML.Document() # 1. colorbar png file - print("plot and add colorbar as a ScreenOverlay element") - cbar_file = f"{out_file_base}_cbar.png" + print('plot and add colorbar as a ScreenOverlay element') + cbar_file = f'{out_file_base}_cbar.png' cbar_overlay = generate_cbar_element( cbar_file, cmap=inps.colormap, @@ -379,17 +351,16 @@ def write_kmz_placemark(data, meta, out_file, geom_file, inps): unit=inps.disp_unit, loc=inps.cbar_loc, nbins=inps.cbar_bin_num, - label=inps.cbar_label, - ) + label=inps.cbar_label) kml_doc.append(cbar_overlay) # 2. reference point - xmin = int(meta.get("SUBSET_XMIN", 0)) - ymin = int(meta.get("SUBSET_YMIN", 0)) + xmin = int(meta.get('SUBSET_XMIN', 0)) + ymin = int(meta.get('SUBSET_YMIN', 0)) - if "REF_Y" in meta.keys(): - print("add reference point as a star icon") - ry, rx = int(meta["REF_Y"]), int(meta["REF_X"]) + if 'REF_Y' in meta.keys(): + print('add reference point as a star icon') + ry, rx = int(meta['REF_Y']), int(meta['REF_X']) rlat = lats[ry, rx] rlon = lons[ry, rx] ref_point = create_placemark_element( @@ -399,9 +370,8 @@ def write_kmz_placemark(data, meta, out_file, geom_file, inps): col=rx + xmin, val=0.0, icon_file=star_file, - inps=inps, - ) - ref_point.name = "ReferencePoint" + inps=inps) + ref_point.name = 'ReferencePoint' ref_point.Style.IconStyle.scale = 1.0 kml_doc.append(ref_point) @@ -411,7 +381,7 @@ def write_kmz_placemark(data, meta, out_file, geom_file, inps): # 3. data folder for all points data_folder = KML.Folder(KML.name("Data")) - print(f"generating point element with step size of {inps.step} pixels") + print(f'generating point element with step size of {inps.step} pixels') length, width = data.shape prog_bar = ptime.progressBar(maxValue=length) for y in range(0, length, inps.step): @@ -429,11 +399,10 @@ def write_kmz_placemark(data, meta, out_file, geom_file, inps): col=x + xmin, val=value, icon_file=dot_file, - inps=inps, - ) + inps=inps) data_folder.append(placemark) - prog_bar.update(y + 1, every=1, suffix=f"row={y+1}/{length}") + prog_bar.update(y+1, every=1, suffix=f'row={y+1}/{length}') prog_bar.close() kml_doc.append(data_folder) @@ -443,8 +412,7 @@ def write_kmz_placemark(data, meta, out_file, geom_file, inps): kml_doc, data_files=[cbar_file], res_files=[dot_file, star_file], - keep_kml_file=inps.keep_kml_file, - ) + keep_kml_file=inps.keep_kml_file) return kmz_file @@ -453,12 +421,12 @@ def write_kmz_placemark(data, meta, out_file, geom_file, inps): def save_kmz(inps): # matplotlib backend setting - plt.switch_backend("Agg") + plt.switch_backend('Agg') ## 1. Read metadata and data - ftype = readfile.read_attribute(inps.file)["FILE_TYPE"] - if ftype == "timeseries" and inps.dset and "_" in inps.dset: - inps.ref_date, inps.dset = inps.dset.split("_") + ftype = readfile.read_attribute(inps.file)['FILE_TYPE'] + if ftype == 'timeseries' and inps.dset and '_' in inps.dset: + inps.ref_date, inps.dset = inps.dset.split('_') else: inps.ref_date = None atr = readfile.read_attribute(inps.file, datasetName=inps.dset) @@ -466,41 +434,42 @@ def save_kmz(inps): # pix_box inps.pix_box = subset.subset_input_dict2box(vars(inps), atr)[0] inps.pix_box = ut.coordinate(atr).check_box_within_data_coverage(inps.pix_box) - data_box = (0, 0, int(atr["WIDTH"]), int(atr["LENGTH"])) - print(f"data coverage in y/x: {data_box}") - print(f"subset coverage in y/x: {inps.pix_box}") + data_box = (0, 0, int(atr['WIDTH']), int(atr['LENGTH'])) + print(f'data coverage in y/x: {data_box}') + print(f'subset coverage in y/x: {inps.pix_box}') atr = attr.update_attribute4subset(atr, inps.pix_box) # read data data = readfile.read(inps.file, datasetName=inps.dset, box=inps.pix_box)[0] - if ftype == "timeseries" and inps.ref_date: + if ftype == 'timeseries' and inps.ref_date: data -= readfile.read(inps.file, datasetName=inps.ref_date, box=inps.pix_box)[0] # mask mask = pp.read_mask( - inps.file, mask_file=inps.mask_file, datasetName=inps.dset, box=inps.pix_box - )[0] + inps.file, + mask_file=inps.mask_file, + datasetName=inps.dset, + box=inps.pix_box)[0] if mask is not None: - print(f"masking out pixels with zero value in file: {inps.mask_file}") + print(f'masking out pixels with zero value in file: {inps.mask_file}') data[mask == 0] = np.nan if inps.zero_mask: - print("masking out pixels with zero value") + print('masking out pixels with zero value') data[data == 0] = np.nan del mask # Data Operation - Display Unit & Rewrapping - data, inps.disp_unit, inps.disp_scale, inps.wrap = ( - pp.scale_data4disp_unit_and_rewrap( - data, - metadata=atr, - disp_unit=inps.disp_unit, - wrap=inps.wrap, - wrap_range=inps.wrap_range, - ) + data, inps.disp_unit, inps.disp_scale, inps.wrap = pp.scale_data4disp_unit_and_rewrap( + data, + metadata=atr, + disp_unit=inps.disp_unit, + wrap=inps.wrap, + wrap_range=inps.wrap_range, ) if inps.wrap: inps.vlim = inps.wrap_range + ## 2. Generate Google Earth KMZ # disp min/max and colormap cmap_lut = 256 @@ -512,18 +481,25 @@ def save_kmz(inps): # output filename inps.fig_title = pp.auto_figure_title(inps.file, inps.dset, vars(inps)) - inps.outfile = inps.outfile if inps.outfile else f"{inps.fig_title}.kmz" + inps.outfile = inps.outfile if inps.outfile else f'{inps.fig_title}.kmz' inps.outfile = os.path.abspath(inps.outfile) # write KMZ file - if "Y_FIRST" in atr.keys(): + if 'Y_FIRST' in atr.keys(): # create ground overlay KML for file in geo-coord - write_kmz_overlay(data, meta=atr, out_file=inps.outfile, inps=inps) + write_kmz_overlay( + data, + meta=atr, + out_file=inps.outfile, + inps=inps) else: # create placemark KML for file in radar-coord write_kmz_placemark( - data, meta=atr, out_file=inps.outfile, geom_file=inps.geom_file, inps=inps - ) + data, + meta=atr, + out_file=inps.outfile, + geom_file=inps.geom_file, + inps=inps) - return + return \ No newline at end of file From 5106657493200d7215b4a1c1178badf428882440 Mon Sep 17 00:00:00 2001 From: Alex-Lewandowski Date: Fri, 31 May 2024 14:11:44 -0800 Subject: [PATCH 4/6] empty line at end of file --- src/mintpy/save_kmz.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/mintpy/save_kmz.py b/src/mintpy/save_kmz.py index 88e5eb4ae..ec4e56676 100644 --- a/src/mintpy/save_kmz.py +++ b/src/mintpy/save_kmz.py @@ -502,4 +502,5 @@ def save_kmz(inps): geom_file=inps.geom_file, inps=inps) - return \ No newline at end of file + return + \ No newline at end of file From aac5f3ffc00535ce19d104b662ac416cc3f22503 Mon Sep 17 00:00:00 2001 From: Alex-Lewandowski Date: Fri, 31 May 2024 14:31:10 -0800 Subject: [PATCH 5/6] fix end of file --- src/mintpy/save_kmz.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/mintpy/save_kmz.py b/src/mintpy/save_kmz.py index ec4e56676..90a03ddc2 100644 --- a/src/mintpy/save_kmz.py +++ b/src/mintpy/save_kmz.py @@ -503,4 +503,3 @@ def save_kmz(inps): inps=inps) return - \ No newline at end of file From 2b49ad176dd4277f7985696e25239a8a9f09d570 Mon Sep 17 00:00:00 2001 From: Zhang Yunjun Date: Thu, 6 Jun 2024 09:52:24 +0800 Subject: [PATCH 6/6] Update save_kmz.py --- src/mintpy/save_kmz.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mintpy/save_kmz.py b/src/mintpy/save_kmz.py index 90a03ddc2..bada5d836 100644 --- a/src/mintpy/save_kmz.py +++ b/src/mintpy/save_kmz.py @@ -24,7 +24,6 @@ ptime, readfile, utils as ut, - utils0 as ut0, ) @@ -234,9 +233,10 @@ def write_kmz_overlay(data, meta, out_file, inps): """ south, north, west, east = ut.four_corners(meta) + # convert from UTM to WGS84 when necessary, as KML only natively supports WGS84 if "UTM_ZONE" in meta.keys(): - north, east = ut0.utm2latlon(meta, east, north) - south, west = ut0.utm2latlon(meta, west, south) + north, east = ut.utm2latlon(meta, east, north) + south, west = ut.utm2latlon(meta, west, south) # 1. Make PNG file - Data print('plotting data ...')