Skip to content

add support for InSAR Explorer #1330

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions docs/QGIS.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,6 @@ ramp_color('RdBu', scale_linear(VEL, -20, 20, 0, 1))
<p align="left">
<img width="800" src="https://insarlab.github.io/figs/docs/mintpy/QGIS-PS-TSV-point.png">
</p>

The exported shapefile can also be used in QGIS [InSAR Explorer plugin](https://plugins.qgis.org/plugins/insar_explorer-dev/) for visualization of time-series data.
For more details on using the plugin, please refer to the [InSAR Explorer documentation](https://insar-explorer.readthedocs.io/).
28 changes: 28 additions & 0 deletions docs/insar_explorer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
Displacement time-series can be visualized in QGIS InSAR Explorer plugin. The plugin supports time-series data as GRD files or shapefile.

### Setup QGIS and InSAR Explorer ###
1. Download and Install [QGIS](https://qgis.org/en/site/) if you have not done so.
2. Install InSAR Explorer:
- Install the latest stable version of the [InSAR Explorer plugin](https://plugins.qgis.org/plugins/insar_explorer-dev/) via “Plugins -> Manage and Install Plugins.”
- Alternatively, download the plugin as a *.zip file from the [InSAR Explorer GitHub repository](https://github.com/luhipi/insar-explorer) and install it through “Plugins -> Manage and Install Plugins -> Install from ZIP.”
3. Launch InSAR Explorer: Access it from the toolbar or through “Plugins -> InSAR Explorer -> InSAR Explorer.”


### Using GRD files ###
1. Export MintPy results to GRD files compatible with the QGIS InSAR Explorer plugin using `save_explorer.py`.

```
$ save_explorer.py geo_timeseries.h5 -v geo_velocity.h5 -o geo_maskTempCoh.h5 -o timeseries/
```

2. Load data in QGIS: Open one of the exported GRD files (for example `geo_velocity_mm.h5`), in QGIS.
3. Launch InSAR Explorer and Click on any point to plot the time series.

### Using shapefile ###
1. Export to shapefile can be done using `save_qgis.py` script.
2. Load the shapefile in QGIS.
3. Launch InSAR Explorer and Click on any point to plot the time series.


### More information ###
For more details on using the plugin, please refer to the [InSAR Explore documentation](https://insar-explorer.readthedocs.io/).
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ nav:
- Google Earth KMZ: google_earth.md
- HDF-EOS5: hdfeos5.md
- QGIS: QGIS.md
- InSAR Explorer: insar_explorer.md
- API Documentation:
- Attributes: api/attributes.md
- Colormaps: api/colormaps.md
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ Issues = "https://github.com/insarlab/MintPy/issues"
"save_kmz_timeseries.py" = "mintpy.cli.save_kmz_timeseries:main"
"save_qgis.py" = "mintpy.cli.save_qgis:main"
"save_roipac.py" = "mintpy.cli.save_roipac:main"
"save_explorer.py" = "mintpy.cli.save_explorer:main"
"smallbaselineApp.py" = "mintpy.cli.smallbaselineApp:main"
"solid_earth_tides.py" = "mintpy.cli.solid_earth_tides:main"
"spatial_average.py" = "mintpy.cli.spatial_average:main"
Expand Down
8 changes: 8 additions & 0 deletions src/mintpy/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,13 @@ def get_save_roipac_parser(subparsers=None):
return parser


def get_save_explorer_parser(subparsers=None):
from mintpy.cli import save_explorer
parser = save_explorer.create_parser(subparsers)
parser.set_defaults(func=save_explorer.main)
return parser


def get_smallbaselineApp_parser(subparsers=None):
from mintpy.cli import smallbaselineApp
parser = smallbaselineApp.create_parser(subparsers)
Expand Down Expand Up @@ -660,6 +667,7 @@ def get_parser():
get_save_kmz_parser(sp)
get_save_qgis_parser(sp)
get_save_roipac_parser(sp)
get_save_explorer_parser(sp)

# visualization
get_info_parser(sp)
Expand Down
80 changes: 80 additions & 0 deletions src/mintpy/cli/save_explorer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
#!/usr/bin/env python3
############################################################
# Program is part of MintPy #
# Copyright (c) 2013, Zhang Yunjun, Heresh Fattahi #
# Author: Mahmud Haghighi, Mar 2025 #
############################################################


import sys

from mintpy.utils import readfile
from mintpy.utils.arg_utils import create_argument_parser

####################################################################################
DESCRIPTION = """More information:
Documentation for InSAR Explorer: https://luhipi.github.io/insar-explorer
Install it on QGIS via Plugins > Manage and Install Plugins....
"""
EXAMPLE = """example:
save_explorer.py geo_timeseries_demErr.h5
save_explorer.py geo_timeseries_demErr.h5 -v geo_velocity.h5 -m geo_maskTempCoh.h5
save_explorer.py geo_timeseries_demErr.h5 -v geo_velocity.h5 -o timeseries -m geo_maskTempCoh.h5
save_explorer.py geo_timeseries_demErr_mask.h5 -v geo_velocity_mask.h5 -o timeseries -m geo_maskTempCoh.h5
"""



def create_parser(subparsers=None):
synopsis = 'Convert time series to GRD files compatible with InSAR Explorer. '
epilog = EXAMPLE + '\n' + DESCRIPTION
name = __name__.split('.')[-1]
parser = create_argument_parser(
name, synopsis=synopsis, description=synopsis, epilog=epilog, subparsers=subparsers)

parser.add_argument('file',
help='Time series file to be converted, in geo coordinate.')
parser.add_argument('-v', '--vel', dest='vel_file',
help='velocity file to be converted, in geo coordinate.')
parser.add_argument('-m', '--mask', dest='mask_file',
help='mask file, in geo coordinates. Default: no mask applied.')
parser.add_argument('-o', '--output', dest='outdir',
default='InSAR-Explorer',
help='Name of the output directory where files will be created. Default: InSAR-Explorer')
return parser


def cmd_line_parse(iargs=None):
# parse
parser = create_parser()
inps = parser.parse_args(args=iargs)

# check
atr = readfile.read_attribute(inps.file)

# check: input file coordinate system
if 'Y_FIRST' not in atr.keys():
raise Exception('ERROR: input file is not geocoded.')

ftype = atr['FILE_TYPE']
if not ftype in ['timeseries']:
raise Exception(f"NO required timeseries found in file {inps.file}!")

return inps


####################################################################################
def main(iargs=None):
# parse
inps = cmd_line_parse(iargs)

# import
from mintpy.save_explorer import save_explorer

# run
save_explorer(inps)


####################################################################################
if __name__ == '__main__':
main(sys.argv[1:])
70 changes: 70 additions & 0 deletions src/mintpy/save_explorer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
############################################################
# Program is part of MintPy #
# Copyright (c) 2013, Zhang Yunjun, Heresh Fattahi #
# Author: Mahmud Haghighi, Mar 2025 #
############################################################


import os

import numpy as np

from mintpy.save_gmt import write_grd_file
from mintpy.utils import readfile


####################################################################################
def convert2mm(data, atr):
if atr['UNIT'] in ['m', 'm/year']:
return data * 1000
elif atr['UNIT'] in ['cm', 'cm/year']:
return data * 10
elif atr['UNIT'] in ['mm', 'mm/year']:
return data
else:
raise ValueError(f"ERROR: unit {atr['UNIT']} is not supported!")


def save_explorer(inps):

if not os.path.exists(inps.outdir):
print('output directory does not exist. creating directory: '+inps.outdir)
os.makedirs(inps.outdir)

if inps.mask_file:
mask, atr = readfile.read(inps.mask_file)
else:
mask = None

# export velocity file
if inps.vel_file:
data, atr = readfile.read(inps.vel_file)
data = convert2mm(data, atr)

if mask is not None:
data[~mask] = np.nan

out_file = os.path.join(inps.outdir, os.path.splitext(os.path.basename(inps.vel_file))[0] + '_mm.grd')
write_grd_file(data, atr, out_file)


# get slice list
slice_list = readfile.get_slice_list(inps.file)

for i, slice_name in enumerate(slice_list): # write each slice to a separate file
if not slice_name.lower().startswith('timeseries'):
continue

data, atr = readfile.read(inps.file, datasetName=slice_name)
# convert to mm
data = convert2mm(data, atr)

if mask is not None:
data[~mask] = np.nan

out_file = inps.outdir + '/' + slice_name + '_mm.grd'
write_grd_file(data, atr, out_file)
print(f'{i+1}/{len(slice_list)}: {out_file}')

print('Done.')
return