ISCE_INSAR/contrib/geo_autoRIFT/geogrid/GeogridOptical.py

407 lines
14 KiB
Python
Raw Normal View History

2020-07-21 21:50:01 +00:00
#!/usr/bin/env python3
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Copyright 2019 California Institute of Technology. ALL RIGHTS RESERVED.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# United States Government Sponsorship acknowledged. This software is subject to
# U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
# (No [Export] License Required except when exporting to an embargoed country,
# end user, or in support of a prohibited end use). By downloading this software,
# the user agrees to comply with all applicable U.S. export laws and regulations.
# The user has the responsibility to obtain export licenses, or other export
# authority as may be required before exporting this software to any 'EAR99'
# embargoed foreign country or citizen of those countries.
#
# Authors: Piyush Agram, Yang Lei
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
import pdb
import subprocess
import re
import string
class GeogridOptical():
'''
Class for mapping regular geographic grid on radar imagery.
'''
def runGeogrid(self):
'''
Do the actual processing.
'''
2021-11-03 19:11:14 +00:00
from . import geogridOptical
2020-07-21 21:50:01 +00:00
##Determine appropriate EPSG system
2021-11-03 19:11:14 +00:00
self.epsgDem = self.getProjectionSystem(self.demname)
self.epsgDat = self.getProjectionSystem(self.dat1name)
2020-07-21 21:50:01 +00:00
###Determine extent of data needed
bbox = self.determineBbox()
2021-11-03 19:11:14 +00:00
##Create and set parameters
self.setState()
##check parameters
self.checkState()
2020-07-21 21:50:01 +00:00
2021-11-03 19:11:14 +00:00
##Run
geogridOptical.geogridOptical_Py(self._geogridOptical)
self.get_center_latlon()
##Get parameters
self.getState()
##Clean up
self.finalize()
def get_center_latlon(self):
'''
Get center lat/lon of the image.
'''
from osgeo import gdal
gdal.AllRegister()
self.epsgDem = 4326
self.epsgDat = self.getProjectionSystem(self.dat1name)
self.determineBbox()
if gdal.__version__[0] == '2':
self.cen_lat = (self._ylim[0] + self._ylim[1]) / 2
self.cen_lon = (self._xlim[0] + self._xlim[1]) / 2
else:
self.cen_lon = (self._ylim[0] + self._ylim[1]) / 2
self.cen_lat = (self._xlim[0] + self._xlim[1]) / 2
print("Scene-center lat/lon: " + str(self.cen_lat) + " " + str(self.cen_lon))
2020-07-21 21:50:01 +00:00
2021-11-03 19:11:14 +00:00
def getProjectionSystem(self, filename):
2020-07-21 21:50:01 +00:00
'''
Testing with Greenland.
'''
if not filename:
raise Exception('File {0} does not exist'.format(filename))
from osgeo import gdal, osr
2021-11-03 19:11:14 +00:00
ds = gdal.Open(filename, gdal.GA_ReadOnly)
2020-07-21 21:50:01 +00:00
srs = osr.SpatialReference()
srs.ImportFromWkt(ds.GetProjection())
srs.AutoIdentifyEPSG()
ds = None
# pdb.set_trace()
if srs.IsGeographic():
epsgstr = srs.GetAuthorityCode('GEOGCS')
elif srs.IsProjected():
epsgstr = srs.GetAuthorityCode('PROJCS')
elif srs.IsLocal():
raise Exception('Local coordinate system encountered')
else:
raise Exception('Non-standard coordinate system encountered')
if not epsgstr: #Empty string->use shell command gdalsrsinfo for last trial
2021-11-03 19:11:14 +00:00
cmd = 'gdalsrsinfo -o epsg {0}'.format(filename)
2020-07-21 21:50:01 +00:00
epsgstr = subprocess.check_output(cmd, shell=True)
# pdb.set_trace()
epsgstr = re.findall("EPSG:(\d+)", str(epsgstr))[0]
# pdb.set_trace()
if not epsgstr: #Empty string
raise Exception('Could not auto-identify epsg code')
# pdb.set_trace()
epsgcode = int(epsgstr)
# pdb.set_trace()
return epsgcode
def determineBbox(self, zrange=[-200,4000]):
'''
Dummy.
'''
import numpy as np
import datetime
from osgeo import osr
2021-11-03 19:11:14 +00:00
2020-07-21 21:50:01 +00:00
# import pdb
# pdb.set_trace()
2021-11-03 19:11:14 +00:00
samples = self.startingX + np.array([0, self.numberOfSamples-1]) * self.XSize
lines = self.startingY + np.array([0, self.numberOfLines-1]) * self.YSize
2020-07-21 21:50:01 +00:00
coordDat = osr.SpatialReference()
if self.epsgDat:
coordDat.ImportFromEPSG(self.epsgDat)
else:
raise Exception('EPSG code does not exist for image data')
2021-11-03 19:11:14 +00:00
2020-07-21 21:50:01 +00:00
coordDem = osr.SpatialReference()
if self.epsgDem:
coordDem.ImportFromEPSG(self.epsgDem)
else:
raise Exception('EPSG code does not exist for DEM')
2021-11-03 19:11:14 +00:00
2020-07-21 21:50:01 +00:00
trans = osr.CoordinateTransformation(coordDat, coordDem)
2021-11-03 19:11:14 +00:00
2020-07-21 21:50:01 +00:00
utms = []
xyzs = []
### Four corner coordinates
for ss in samples:
for ll in lines:
for zz in zrange:
utms.append([ss,ll,zz])
x,y,z = trans.TransformPoint(ss, ll, zz)
xyzs.append([x,y,z])
utms = np.array(utms)
xyzs = np.array(xyzs)
self._xlim = [np.min(xyzs[:,0]), np.max(xyzs[:,0])]
self._ylim = [np.min(xyzs[:,1]), np.max(xyzs[:,1])]
2021-11-03 19:11:14 +00:00
def getState(self):
2021-02-03 00:29:29 +00:00
2021-11-03 19:11:14 +00:00
from . import geogridOptical
2020-07-21 21:50:01 +00:00
2021-11-03 19:11:14 +00:00
self.pOff = geogridOptical.getXOff_Py(self._geogridOptical)
self.lOff = geogridOptical.getYOff_Py(self._geogridOptical)
self.pCount = geogridOptical.getXCount_Py(self._geogridOptical)
self.lCount = geogridOptical.getYCount_Py(self._geogridOptical)
self.X_res = geogridOptical.getXPixelSize_Py(self._geogridOptical)
self.Y_res = geogridOptical.getYPixelSize_Py(self._geogridOptical)
2020-07-21 21:50:01 +00:00
2021-11-03 19:11:14 +00:00
def setState(self):
'''
Create C object and populate.
'''
2020-07-21 21:50:01 +00:00
2021-11-03 19:11:14 +00:00
from . import geogridOptical
2020-07-21 21:50:01 +00:00
2021-11-03 19:11:14 +00:00
if self._geogridOptical is not None:
geogridOptical.destroyGeoGridOptical_Py(self._geogridOptical)
2020-07-21 21:50:01 +00:00
2021-11-03 19:11:14 +00:00
self._geogridOptical = geogridOptical.createGeoGridOptical_Py()
geogridOptical.setOpticalImageDimensions_Py( self._geogridOptical, self.numberOfSamples, self.numberOfLines)
geogridOptical.setXParameters_Py( self._geogridOptical, self.startingX, self.XSize)
geogridOptical.setYParameters_Py( self._geogridOptical, self.startingY, self.YSize)
geogridOptical.setRepeatTime_Py(self._geogridOptical, self.repeatTime)
geogridOptical.setDtUnity_Py( self._geogridOptical, self.srs_dt_unity)
geogridOptical.setMaxFactor_Py( self._geogridOptical, self.srs_max_scale)
geogridOptical.setUpperThreshold_Py( self._geogridOptical, self.srs_max_search)
geogridOptical.setLowerThreshold_Py(self._geogridOptical, self.srs_min_search)
geogridOptical.setEPSG_Py(self._geogridOptical, self.epsgDem, self.epsgDat)
geogridOptical.setChipSizeX0_Py(self._geogridOptical, self.chipSizeX0)
geogridOptical.setGridSpacingX_Py(self._geogridOptical, self.gridSpacingX)
geogridOptical.setXLimits_Py(self._geogridOptical, self._xlim[0], self._xlim[1])
geogridOptical.setYLimits_Py(self._geogridOptical, self._ylim[0], self._ylim[1])
if self.demname:
geogridOptical.setDEM_Py(self._geogridOptical, self.demname)
if (self.dhdxname is not None) and (self.dhdyname is not None):
geogridOptical.setSlopes_Py(self._geogridOptical, self.dhdxname, self.dhdyname)
if (self.vxname is not None) and (self.vyname is not None):
geogridOptical.setVelocities_Py(self._geogridOptical, self.vxname, self.vyname)
if (self.srxname is not None) and (self.sryname is not None):
geogridOptical.setSearchRange_Py(self._geogridOptical, self.srxname, self.sryname)
if (self.csminxname is not None) and (self.csminyname is not None):
geogridOptical.setChipSizeMin_Py(self._geogridOptical, self.csminxname, self.csminyname)
if (self.csmaxxname is not None) and (self.csmaxyname is not None):
geogridOptical.setChipSizeMax_Py(self._geogridOptical, self.csmaxxname, self.csmaxyname)
if (self.ssmname is not None):
geogridOptical.setStableSurfaceMask_Py(self._geogridOptical, self.ssmname)
geogridOptical.setWindowLocationsFilename_Py( self._geogridOptical, self.winlocname)
geogridOptical.setWindowOffsetsFilename_Py( self._geogridOptical, self.winoffname)
geogridOptical.setWindowSearchRangeFilename_Py( self._geogridOptical, self.winsrname)
geogridOptical.setWindowChipSizeMinFilename_Py( self._geogridOptical, self.wincsminname)
geogridOptical.setWindowChipSizeMaxFilename_Py( self._geogridOptical, self.wincsmaxname)
geogridOptical.setWindowStableSurfaceMaskFilename_Py( self._geogridOptical, self.winssmname)
geogridOptical.setRO2VXFilename_Py( self._geogridOptical, self.winro2vxname)
geogridOptical.setRO2VYFilename_Py( self._geogridOptical, self.winro2vyname)
geogridOptical.setNodataOut_Py(self._geogridOptical, self.nodata_out)
2020-07-21 21:50:01 +00:00
2021-11-03 19:11:14 +00:00
def checkState(self):
'''
Create C object and populate.
'''
if self.repeatTime < 0:
raise Exception('Input image 1 must be older than input image 2')
2020-07-21 21:50:01 +00:00
2021-11-03 19:11:14 +00:00
def finalize(self):
'''
Clean up all the C pointers.
'''
2020-07-21 21:50:01 +00:00
2021-11-03 19:11:14 +00:00
from . import geogridOptical
geogridOptical.destroyGeoGridOptical_Py(self._geogridOptical)
self._geogridOptical = None
2020-07-21 21:50:01 +00:00
2021-11-03 19:11:14 +00:00
def coregister(self,in1,in2):
2021-02-03 00:29:29 +00:00
import os
import numpy as np
2021-11-03 19:11:14 +00:00
2021-02-03 00:29:29 +00:00
from osgeo import gdal, osr
import struct
2021-11-03 19:11:14 +00:00
DS1 = gdal.Open(in1, gdal.GA_ReadOnly)
2021-02-03 00:29:29 +00:00
trans1 = DS1.GetGeoTransform()
xsize1 = DS1.RasterXSize
ysize1 = DS1.RasterYSize
2021-11-03 19:11:14 +00:00
epsg1 = self.getProjectionSystem(in1)
DS2 = gdal.Open(in2, gdal.GA_ReadOnly)
2021-02-03 00:29:29 +00:00
trans2 = DS2.GetGeoTransform()
xsize2 = DS2.RasterXSize
ysize2 = DS2.RasterYSize
2021-11-03 19:11:14 +00:00
epsg2 = self.getProjectionSystem(in2)
if epsg1 != epsg2:
raise Exception('The current version of geo_autoRIFT assumes the two images are in the same projection, i.e. it cannot handle two different projections; the users are thus recommended to do the tranformation themselves before running geo_autoRIFT.')
2021-02-03 00:29:29 +00:00
2021-11-03 19:11:14 +00:00
2021-02-03 00:29:29 +00:00
W = np.max([trans1[0],trans2[0]])
N = np.min([trans1[3],trans2[3]])
2021-11-03 19:11:14 +00:00
E = np.min([trans1[0]+(xsize1-1)*trans1[1],trans2[0]+(xsize2-1)*trans2[1]])
S = np.max([trans1[3]+(ysize1-1)*trans1[5],trans2[3]+(ysize2-1)*trans2[5]])
2021-02-03 00:29:29 +00:00
x1a = int(np.round((W-trans1[0])/trans1[1]))
x1b = int(np.round((E-trans1[0])/trans1[1]))
y1a = int(np.round((N-trans1[3])/trans1[5]))
y1b = int(np.round((S-trans1[3])/trans1[5]))
2021-11-03 19:11:14 +00:00
2021-02-03 00:29:29 +00:00
x2a = int(np.round((W-trans2[0])/trans2[1]))
x2b = int(np.round((E-trans2[0])/trans2[1]))
y2a = int(np.round((N-trans2[3])/trans2[5]))
y2b = int(np.round((S-trans2[3])/trans2[5]))
2021-11-03 19:11:14 +00:00
if (x1a > (xsize1-1))|(x1b > (xsize1-1))|(x2a > (xsize2-1))|(x2b > (xsize2-1))|(y1a > (ysize1-1))|(y1b > (ysize1-1))|(y2a > (ysize2-1))|(y2b > (ysize2-1)):
raise Exception('Uppper bound of coregistered image index should be <= size of image1 (and image2) minus 1')
if (x1a < 0)|(x1b < 0)|(x2a < 0)|(x2b < 0)|(y1a < 0)|(y1b < 0)|(y2a < 0)|(y2b < 0):
raise Exception('Lower bound of coregistered image index should be >= 0')
if ((x1b-x1a) != (x2b-x2a))|((y1b-y1a) != (y2b-y2a)):
raise Exception('Coregistered image size mismatch between image1 and image2')
2021-02-03 00:29:29 +00:00
x1a = int(x1a)
x1b = int(x1b)
y1a = int(y1a)
y1b = int(y1b)
x2a = int(x2a)
x2b = int(x2b)
y2a = int(y2a)
y2b = int(y2b)
trans = (W, trans1[1], 0.0, N, 0.0, trans1[5])
return x1a, y1a, x1b-x1a+1, y1b-y1a+1, x2a, y2a, x2b-x2a+1, y2b-y2a+1, trans
2020-07-21 21:50:01 +00:00
2021-11-03 19:11:14 +00:00
2020-07-21 21:50:01 +00:00
def __init__(self):
super(GeogridOptical, self).__init__()
##Optical image related parameters
self.startingY = None
self.startingX = None
self.XSize = None
self.YSize = None
self.numberOfSamples = None
self.numberOfLines = None
self.repeatTime = None
self.chipSizeX0 = None
2021-11-03 19:11:14 +00:00
self.gridSpacingX = None
2020-07-21 21:50:01 +00:00
##Input related parameters
self.dat1name = None
self.demname = None
self.dhdxname = None
self.dhdyname = None
self.vxname = None
self.vyname = None
self.srxname = None
self.sryname = None
self.csminxname = None
self.csminyname = None
self.csmaxxname = None
self.csmaxyname = None
self.ssmname = None
2021-11-03 19:11:14 +00:00
2020-07-21 21:50:01 +00:00
##Output related parameters
self.winlocname = None
self.winoffname = None
self.winsrname = None
self.wincsminname = None
self.wincsmaxname = None
self.winssmname = None
self.winro2vxname = None
self.winro2vyname = None
2021-11-03 19:11:14 +00:00
##dt-varying search range scale (srs) rountine parameters
self.srs_dt_unity = 182
self.srs_max_scale = 5
self.srs_max_search = 20000
self.srs_min_search = 0
2020-07-21 21:50:01 +00:00
##Coordinate system
self.epsgDem = None
self.epsgDat = None
self._xlim = None
self._ylim = None
self.nodata_out = None
2021-11-03 19:11:14 +00:00
##Pointer to C
self._geogridOptical = None
2020-07-21 21:50:01 +00:00
2021-11-03 19:11:14 +00:00
##parameters for autoRIFT
self.pOff = None
self.lOff = None
self.pCount = None
self.lCount = None
self.X_res = None
self.Y_res = None