def test_image_info_ge01(self): image = 'GE01_20090707163115_297600_5V090707P0002976004A222012202432M_001529596_u08mr3413.tif' image_info = mosaic.ImageInfo(os.path.join(self.srcdir,image), 'IMAGE') self.assertEqual(image_info.xres, 16.0) self.assertEqual(image_info.yres, 16.0) self.assertEqual(image_info.proj, 'PROJCS["unnamed",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433],AUTHORITY["EPSG","4326"]],PROJECTION["Polar_Stereographic"],PARAMETER["latitude_of_origin",70],PARAMETER["central_meridian",-45],PARAMETER["scale_factor",1],PARAMETER["false_easting",0],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]]]') self.assertEqual(image_info.bands, 1) self.assertEqual(image_info.datatype, 1) mosaic_args = MosaicArgs() mosaic_params = mosaic.getMosaicParameters(image_info, mosaic_args) image_info.getScore(mosaic_params) self.assertEqual(image_info.sensor, 'GE01') self.assertEqual(image_info.sunel, 45.98) self.assertEqual(image_info.ona, 26.86) self.assertEqual(image_info.cloudcover, 0.0) self.assertEqual(image_info.tdi, 8.0) self.assertEqual(image_info.panfactor ,1) #self.assertEqual(image_info.exposure_factor, 0) self.assertEqual(image_info.date_diff, -9999) self.assertAlmostEqual(image_info.score, 79.1422222) image_info.get_raster_stats() stat_dct = {1: [40.0, 200.0, 135.82811420290182, 33.54100534555833]} datapixelcount_dct = {1: 4435509} self.assertEqual(image_info.stat_dct, stat_dct) self.assertEqual(image_info.datapixelcount_dct, datapixelcount_dct)
def test_image_info_wv01_with_tday_and_exposure(self): image = 'WV01_20080807153945_1020010003A5AC00_08AUG07153945-P1BS-052060421010_01_P011_u08mr3413.tif' image_info = mosaic.ImageInfo(os.path.join(self.srcdir,image), 'IMAGE') self.assertEqual(image_info.xres, 16.0) self.assertEqual(image_info.yres, 16.0) self.assertEqual(image_info.proj, 'PROJCS["unnamed",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433],AUTHORITY["EPSG","4326"]],PROJECTION["Polar_Stereographic"],PARAMETER["latitude_of_origin",70],PARAMETER["central_meridian",-45],PARAMETER["scale_factor",1],PARAMETER["false_easting",0],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]]]') self.assertEqual(image_info.bands, 1) self.assertEqual(image_info.datatype, 1) mosaic_args = MosaicArgs() mosaic_args.tday = '09-01' mosaic_args.use_exposure = True mosaic_params = mosaic.getMosaicParameters(image_info, mosaic_args) self.assertEqual(mosaic_params.m, 9) self.assertEqual(mosaic_params.d, 1) image_info.getScore(mosaic_params) self.assertEqual(image_info.sensor, 'WV01') self.assertEqual(image_info.sunel, 39.0) self.assertEqual(image_info.ona, 18.5) self.assertEqual(image_info.cloudcover, 0.0) self.assertEqual(image_info.tdi, 16.0) self.assertEqual(image_info.panfactor ,1) #self.assertEqual(image_info.exposure_factor, 0) self.assertEqual(image_info.date_diff, 24) self.assertAlmostEqual(image_info.score, 86.0924408)
def test_image_info_wv02_with_cc_max(self): image = 'WV02_20110504155551_103001000BA45E00_11MAY04155551-P1BS-500085264180_01_P002_u08mr3413.tif' image_info = mosaic.ImageInfo(os.path.join(self.srcdir,image), 'IMAGE') self.assertEqual(image_info.xres, 16.0) self.assertEqual(image_info.yres, 16.0) self.assertEqual(image_info.proj, 'PROJCS["unnamed",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433],AUTHORITY["EPSG","4326"]],PROJECTION["Polar_Stereographic"],PARAMETER["latitude_of_origin",70],PARAMETER["central_meridian",-45],PARAMETER["scale_factor",1],PARAMETER["false_easting",0],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]]]') self.assertEqual(image_info.bands, 1) self.assertEqual(image_info.datatype, 1) mosaic_args = MosaicArgs() mosaic_args.max_cc = 0.20 mosaic_params = mosaic.getMosaicParameters(image_info, mosaic_args) image_info.getScore(mosaic_params) self.assertEqual(image_info.sensor, 'WV02') self.assertEqual(image_info.sunel, 39.2) self.assertEqual(image_info.ona, 19.0) self.assertEqual(image_info.cloudcover, 0.29) self.assertEqual(image_info.tdi, 48.0) self.assertEqual(image_info.panfactor ,1) #self.assertEqual(image_info.exposure_factor, 0) self.assertEqual(image_info.date_diff, -9999) self.assertAlmostEqual(image_info.score, -1) image_info.get_raster_stats() stat_dct = {1: [80.0, 191.0, 185.7102777536714, 6.965814755751974]} datapixelcount_dct = {1: 1152100} self.assertEqual(image_info.stat_dct, stat_dct) self.assertEqual(image_info.datapixelcount_dct, datapixelcount_dct)
def test_image_info_wv01(self): image = 'WV01_20080807153945_1020010003A5AC00_08AUG07153945-P1BS-052060421010_01_P011_u08mr3413.tif' image_info = mosaic.ImageInfo(os.path.join(self.srcdir,image), 'IMAGE') self.assertEqual(image_info.xres, 16.0) self.assertEqual(image_info.yres, 16.0) self.assertEqual(image_info.proj, 'PROJCS["unnamed",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433],AUTHORITY["EPSG","4326"]],PROJECTION["Polar_Stereographic"],PARAMETER["latitude_of_origin",70],PARAMETER["central_meridian",-45],PARAMETER["scale_factor",1],PARAMETER["false_easting",0],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]]]') self.assertEqual(image_info.bands, 1) self.assertEqual(image_info.datatype, 1) mosaic_args = MosaicArgs() mosaic_params = mosaic.getMosaicParameters(image_info, mosaic_args) image_info.getScore(mosaic_params) self.assertEqual(image_info.sensor, 'WV01') self.assertEqual(image_info.sunel, 39.0) self.assertEqual(image_info.ona, 18.5) self.assertEqual(image_info.cloudcover, 0.0) self.assertEqual(image_info.tdi, 16.0) self.assertEqual(image_info.panfactor ,1) #self.assertEqual(image_info.exposure_factor, 0) self.assertEqual(image_info.date_diff, -9999) self.assertEqual(image_info.year_diff, -9999) self.assertAlmostEqual(image_info.score, 79.2) image_info.get_raster_stats() stat_dct = {1: [24.0, 192.0, 60.0042506228806, 18.321626067645923]} datapixelcount_dct = {1: 1403559} for i in range(len(image_info.stat_dct[1])): self.assertAlmostEqual(image_info.stat_dct[1][i], stat_dct[1][i]) self.assertEqual(image_info.datapixelcount_dct, datapixelcount_dct)
def test_image_info_wv02_ndvi(self): srcdir = os.path.join(os.path.join(test_dir,'mosaic','ndvi')) image = 'WV02_20110901210434_103001000B41DC00_11SEP01210434-M1BS-052730735130_01_P007_u16rf3413_ndvi.tif' image_info = mosaic.ImageInfo(os.path.join(srcdir,image), 'IMAGE') self.assertEqual(image_info.xres, 64.0) self.assertEqual(image_info.yres, 64.0) self.assertEqual(image_info.proj, 'PROJCS["unnamed",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433],AUTHORITY["EPSG","4326"]],PROJECTION["Polar_Stereographic"],PARAMETER["latitude_of_origin",70],PARAMETER["central_meridian",-45],PARAMETER["scale_factor",1],PARAMETER["false_easting",0],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]]]') self.assertEqual(image_info.bands, 1) self.assertEqual(image_info.datatype, 6) mosaic_args = MosaicArgs() mosaic_params = mosaic.getMosaicParameters(image_info, mosaic_args) image_info.getScore(mosaic_params) self.assertEqual(image_info.sensor, 'WV02') self.assertEqual(image_info.sunel, 37.7) self.assertEqual(image_info.ona, 19.4) self.assertEqual(image_info.cloudcover, 0.0) self.assertEqual(image_info.tdi, 24.0) self.assertEqual(image_info.panfactor ,1) #self.assertEqual(image_info.exposure_factor, 0) self.assertEqual(image_info.date_diff, -9999) self.assertAlmostEqual(image_info.score, 78.555555555) image_info.get_raster_stats() stat_dct = {} datapixelcount_dct = {} self.assertEqual(image_info.stat_dct, stat_dct) self.assertEqual(image_info.datapixelcount_dct, datapixelcount_dct)
def test_image_info_ge01(self): image = 'GE01_20090707163115_297600_5V090707P0002976004A222012202432M_001529596_u08mr3413.tif' image_info = mosaic.ImageInfo(os.path.join(self.srcdir,image), 'IMAGE') self.assertEqual(image_info.xres, 16.0) self.assertEqual(image_info.yres, 16.0) self.assertEqual(image_info.proj, 'PROJCS["unnamed",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433],AUTHORITY["EPSG","4326"]],PROJECTION["Polar_Stereographic"],PARAMETER["latitude_of_origin",70],PARAMETER["central_meridian",-45],PARAMETER["scale_factor",1],PARAMETER["false_easting",0],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]]]') self.assertEqual(image_info.bands, 1) self.assertEqual(image_info.datatype, 1) mosaic_args = MosaicArgs() mosaic_params = mosaic.getMosaicParameters(image_info, mosaic_args) image_info.getScore(mosaic_params) self.assertEqual(image_info.sensor, 'GE01') self.assertEqual(image_info.sunel, 45.98) self.assertEqual(image_info.ona, 26.86) self.assertEqual(image_info.cloudcover, 0.0) self.assertEqual(image_info.tdi, 8.0) self.assertEqual(image_info.panfactor ,1) #self.assertEqual(image_info.exposure_factor, 0) self.assertEqual(image_info.date_diff, -9999) self.assertEqual(image_info.year_diff, -9999) self.assertAlmostEqual(image_info.score, 79.1422222) image_info.get_raster_stats() stat_dct = {1: [40.0, 200.0, 135.82811420290182, 33.54100534555833]} datapixelcount_dct = {1: 4435509} for i in range(len(image_info.stat_dct[1])): self.assertAlmostEqual(image_info.stat_dct[1][i], stat_dct[1][i]) self.assertEqual(image_info.datapixelcount_dct, datapixelcount_dct)
def test_image_info_wv02_with_cc_max(self): image = 'WV02_20110504155551_103001000BA45E00_11MAY04155551-P1BS-500085264180_01_P002_u08mr3413.tif' image_info = mosaic.ImageInfo(os.path.join(self.srcdir,image), 'IMAGE') self.assertEqual(image_info.xres, 16.0) self.assertEqual(image_info.yres, 16.0) self.assertEqual(image_info.proj, 'PROJCS["unnamed",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433],AUTHORITY["EPSG","4326"]],PROJECTION["Polar_Stereographic"],PARAMETER["latitude_of_origin",70],PARAMETER["central_meridian",-45],PARAMETER["scale_factor",1],PARAMETER["false_easting",0],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]]]') self.assertEqual(image_info.bands, 1) self.assertEqual(image_info.datatype, 1) mosaic_args = MosaicArgs() mosaic_args.max_cc = 0.20 mosaic_params = mosaic.getMosaicParameters(image_info, mosaic_args) image_info.getScore(mosaic_params) self.assertEqual(image_info.sensor, 'WV02') self.assertEqual(image_info.sunel, 39.2) self.assertEqual(image_info.ona, 19.0) self.assertEqual(image_info.cloudcover, 0.29) self.assertEqual(image_info.tdi, 48.0) self.assertEqual(image_info.panfactor ,1) #self.assertEqual(image_info.exposure_factor, 0) self.assertEqual(image_info.date_diff, -9999) self.assertEqual(image_info.year_diff, -9999) self.assertAlmostEqual(image_info.score, -1) image_info.get_raster_stats() stat_dct = {1: [80.0, 191.0, 185.7102777536714, 6.965814755751974]} datapixelcount_dct = {1: 1152100} for i in range(len(image_info.stat_dct[1])): self.assertAlmostEqual(image_info.stat_dct[1][i], stat_dct[1][i]) self.assertEqual(image_info.datapixelcount_dct, datapixelcount_dct)
def test_image_info_wv01_with_tday_and_exposure(self): image = 'WV01_20080807153945_1020010003A5AC00_08AUG07153945-P1BS-052060421010_01_P011_u08mr3413.tif' image_info = mosaic.ImageInfo(os.path.join(self.srcdir,image), 'IMAGE') self.assertEqual(image_info.xres, 16.0) self.assertEqual(image_info.yres, 16.0) self.assertEqual(image_info.proj, 'PROJCS["unnamed",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433],AUTHORITY["EPSG","4326"]],PROJECTION["Polar_Stereographic"],PARAMETER["latitude_of_origin",70],PARAMETER["central_meridian",-45],PARAMETER["scale_factor",1],PARAMETER["false_easting",0],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]]]') self.assertEqual(image_info.bands, 1) self.assertEqual(image_info.datatype, 1) mosaic_args = MosaicArgs() mosaic_args.tday = '09-01' mosaic_args.use_exposure = True mosaic_params = mosaic.getMosaicParameters(image_info, mosaic_args) self.assertEqual(mosaic_params.m, 9) self.assertEqual(mosaic_params.d, 1) image_info.getScore(mosaic_params) self.assertEqual(image_info.sensor, 'WV01') self.assertEqual(image_info.sunel, 39.0) self.assertEqual(image_info.ona, 18.5) self.assertEqual(image_info.cloudcover, 0.0) self.assertEqual(image_info.tdi, 16.0) self.assertEqual(image_info.panfactor, 1) #self.assertEqual(image_info.exposure_factor, 0) self.assertEqual(image_info.date_diff, 24) self.assertEqual(image_info.year_diff, -9999) self.assertAlmostEqual(image_info.score, 86.0924408)
def test_ndvi_info_wv02_pansh(self): image = 'WV02_20110901210434_103001000B41DC00_11SEP01210434-M1BS-052730735130_01_P007_u16rf3413_pansh_ndvi.tif' image_info = mosaic.ImageInfo(os.path.join(self.srcdir, image), 'IMAGE') self.assertEqual(image_info.xres, 16.0) self.assertEqual(image_info.yres, 16.0) self.assertEqual( image_info.proj, 'PROJCS["unnamed",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433],AUTHORITY["EPSG","4326"]],PROJECTION["Polar_Stereographic"],PARAMETER["latitude_of_origin",70],PARAMETER["central_meridian",-45],PARAMETER["scale_factor",1],PARAMETER["false_easting",0],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]]]' ) self.assertEqual(image_info.bands, 1) self.assertEqual(image_info.datatype, 3) mosaic_args = MosaicArgs() mosaic_params = mosaic.getMosaicParameters(image_info, mosaic_args) image_info.getScore(mosaic_params) self.assertEqual(image_info.sensor, 'WV02') self.assertEqual(image_info.sunel, 37.7) self.assertEqual(image_info.ona, 19.4) self.assertEqual(image_info.cloudcover, 0.0) self.assertEqual(image_info.tdi, 24.0) self.assertEqual(image_info.panfactor, 1) self.assertEqual(image_info.date_diff, -9999) self.assertEqual(image_info.year_diff, -9999) self.assertAlmostEqual(image_info.score, 78.55555555555556) image_info.get_raster_stats() stat_dct = {1: [-991.0, 996.0, 536.20172830189938, 250.75913591790697]} datapixelcount_dct = {1: 1203262} for i in range(len(image_info.stat_dct[1])): self.assertAlmostEqual(image_info.stat_dct[1][i], stat_dct[1][i]) self.assertEqual(image_info.datapixelcount_dct, datapixelcount_dct)
def test_filter_images(self): image_list = glob.glob(os.path.join(self.srcdir, '*.tif')) imginfo_list = [mosaic.ImageInfo(image, "IMAGE") for image in image_list] filter_list = [iinfo.srcfn for iinfo in imginfo_list] self.assertIn('WV02_20110901210434_103001000B41DC00_11SEP01210434-M1BS-052730735130_01_P007_u08rf3413.tif', filter_list) self.assertIn('GE01_20130728161916_1050410002608900_13JUL28161916-P1BS-054448357040_01_P002_u16rf3413.tif', filter_list) self.assertIn('WV02_20131123162834_10300100293C3400_13NOV23162834-P1BS-500408660030_01_P005_u08mr3413.tif', filter_list) mosaic_args = MosaicArgs() mosaic_args.extent = [-820000.0, -800000.0, -2420000.0, -2400000.0] mosaic_args.tilesize = [20000, 20000] mosaic_args.bands = 1 mosaic_params = mosaic.getMosaicParameters(imginfo_list[0], mosaic_args) imginfo_list2 = mosaic.filterMatchingImages(imginfo_list, mosaic_params) filter_list = [iinfo.srcfn for iinfo in imginfo_list2] self.assertEqual(len(imginfo_list2), 8) self.assertNotIn('WV02_20110901210434_103001000B41DC00_11SEP01210434-M1BS-052730735130_01_P007_u08rf3413.tif', filter_list) self.assertNotIn('GE01_20130728161916_1050410002608900_13JUL28161916-P1BS-054448357040_01_P002_u16rf3413.tif', filter_list) imginfo_list3 = mosaic.filter_images_by_geometry(imginfo_list2, mosaic_params) filter_list = [iinfo.srcfn for iinfo in imginfo_list3] self.assertEqual(len(imginfo_list3), 7) self.assertNotIn('WV02_20131123162834_10300100293C3400_13NOV23162834-P1BS-500408660030_01_P005_u08mr3413.tif', filter_list)
def test_image_info_wv01(self): image = 'WV01_20080807153945_1020010003A5AC00_08AUG07153945-P1BS-052060421010_01_P011_u08mr3413.tif' image_info = mosaic.ImageInfo(os.path.join(self.srcdir,image), 'IMAGE') self.assertEqual(image_info.xres, 16.0) self.assertEqual(image_info.yres, 16.0) self.assertEqual(image_info.proj, 'PROJCS["unnamed",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433],AUTHORITY["EPSG","4326"]],PROJECTION["Polar_Stereographic"],PARAMETER["latitude_of_origin",70],PARAMETER["central_meridian",-45],PARAMETER["scale_factor",1],PARAMETER["false_easting",0],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]]]') self.assertEqual(image_info.bands, 1) self.assertEqual(image_info.datatype, 1) mosaic_args = MosaicArgs() mosaic_params = mosaic.getMosaicParameters(image_info, mosaic_args) image_info.getScore(mosaic_params) self.assertEqual(image_info.sensor, 'WV01') self.assertEqual(image_info.sunel, 39.0) self.assertEqual(image_info.ona, 18.5) self.assertEqual(image_info.cloudcover, 0.0) self.assertEqual(image_info.tdi, 16.0) self.assertEqual(image_info.panfactor ,1) #self.assertEqual(image_info.exposure_factor, 0) self.assertEqual(image_info.date_diff, -9999) self.assertAlmostEqual(image_info.score, 79.2) image_info.get_raster_stats() stat_dct = {1: [24.0, 192.0, 60.0042506228806, 18.321626067645923]} datapixelcount_dct = {1: 1403559} self.assertEqual(image_info.stat_dct, stat_dct) self.assertEqual(image_info.datapixelcount_dct, datapixelcount_dct)
def test_image_info_multispectral_dg_ge01(self): image = 'GE01_20130728161916_1050410002608900_13JUL28161916-M1BS-054448357040_01_P002_u08mr3413.tif' image_info = mosaic.ImageInfo(os.path.join(self.srcdir,image), 'IMAGE') self.maxDiff = None self.assertEqual(image_info.xres, 32.0) self.assertEqual(image_info.yres, 32.0) self.assertEqual(image_info.proj, 'PROJCS["unnamed",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433],AUTHORITY["EPSG","4326"]],PROJECTION["Polar_Stereographic"],PARAMETER["latitude_of_origin",70],PARAMETER["central_meridian",-45],PARAMETER["scale_factor",1],PARAMETER["false_easting",0],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]]]') self.assertEqual(image_info.bands, 4) self.assertEqual(image_info.datatype, 1) mosaic_args = MosaicArgs() mosaic_params = mosaic.getMosaicParameters(image_info, mosaic_args) image_info.getScore(mosaic_params) self.assertEqual(image_info.sensor, 'GE01') self.assertEqual(image_info.sunel, 42.2) self.assertEqual(image_info.ona, 25.0) self.assertEqual(image_info.cloudcover, 0.0) self.assertEqual(image_info.tdi, 6.0) self.assertEqual(image_info.panfactor ,1) #self.assertEqual(image_info.exposure_factor, 0) self.assertEqual(image_info.date_diff, -9999) self.assertAlmostEqual(image_info.score, 78.462222222) image_info.get_raster_stats() stat_dct = { 1: [44.0, 180.0, 73.05224947061919, 13.760346025453206], 2: [28.0, 182.0, 62.26321535738713, 16.410250286247617], 3: [9.0, 187.0, 51.73902037892776, 17.01731873722769], 4: [7.0, 178.0, 57.128591347040505, 20.162025784223044] } datapixelcount_dct = {1: 287601, 2: 287601, 3: 287601, 4: 287601} self.assertEqual(image_info.stat_dct, stat_dct) self.assertEqual(image_info.datapixelcount_dct, datapixelcount_dct)
def test_image_info_multispectral_dg_ge01(self): image = 'GE01_20130728161916_1050410002608900_13JUL28161916-M1BS-054448357040_01_P002_u08mr3413.tif' image_info = mosaic.ImageInfo(os.path.join(self.srcdir, image), 'IMAGE') self.maxDiff = None self.assertEqual(image_info.xres, 32.0) self.assertEqual(image_info.yres, 32.0) self.assertEqual( image_info.proj, 'PROJCS["unnamed",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433],AUTHORITY["EPSG","4326"]],PROJECTION["Polar_Stereographic"],PARAMETER["latitude_of_origin",70],PARAMETER["central_meridian",-45],PARAMETER["scale_factor",1],PARAMETER["false_easting",0],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]]]' ) self.assertEqual(image_info.bands, 4) self.assertEqual(image_info.datatype, 1) mosaic_args = MosaicArgs() mosaic_params = mosaic.getMosaicParameters(image_info, mosaic_args) image_info.getScore(mosaic_params) self.assertEqual(image_info.sensor, 'GE01') self.assertEqual(image_info.sunel, 42.2) self.assertEqual(image_info.ona, 25.0) self.assertEqual(image_info.cloudcover, 0.0) self.assertEqual(image_info.tdi, 6.0) self.assertEqual(image_info.panfactor, 1) #self.assertEqual(image_info.exposure_factor, 0) self.assertEqual(image_info.date_diff, -9999) self.assertEqual(image_info.year_diff, -9999) self.assertAlmostEqual(image_info.score, 78.462222222) image_info.get_raster_stats() #print image_info.stat_dct stat_dct = { 1: [44.0, 180.0, 73.05224947061919, 13.760346025453206], 2: [28.0, 182.0, 62.26321535738713, 16.410250286247617], 3: [9.0, 187.0, 51.73902037892776, 17.01731873722769], 4: [7.0, 178.0, 57.128591347040505, 20.162025784223044] } datapixelcount_dct = {1: 287601, 2: 287601, 3: 287601, 4: 287601} for i in range(len(image_info.stat_dct[1])): self.assertAlmostEqual(image_info.stat_dct[1][i], stat_dct[1][i]) self.assertEqual(image_info.datapixelcount_dct, datapixelcount_dct)
def test_pansh_info_wv02(self): image = 'WV02_20110901210502_103001000D52C800_11SEP01210502-M1BS-052560788010_01_P008_u08rf3413_pansh.tif' image_info = mosaic.ImageInfo(os.path.join(self.srcdir, image), 'IMAGE') self.assertEqual(image_info.xres, 0.564193804791) self.assertEqual(image_info.yres, 0.560335413717) self.assertEqual( image_info.proj, 'PROJCS["unnamed",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433],AUTHORITY["EPSG","4326"]],PROJECTION["Polar_Stereographic"],PARAMETER["latitude_of_origin",70],PARAMETER["central_meridian",-45],PARAMETER["scale_factor",1],PARAMETER["false_easting",0],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]]]' ) self.assertEqual(image_info.bands, 4) self.assertEqual(image_info.datatype, 1) mosaic_args = MosaicArgs() mosaic_params = mosaic.getMosaicParameters(image_info, mosaic_args) image_info.getScore(mosaic_params) self.assertEqual(image_info.sensor, 'WV02') self.assertEqual(image_info.sunel, 37.8) self.assertEqual(image_info.ona, 23.5) self.assertEqual(image_info.cloudcover, 0.003) self.assertEqual(image_info.tdi, 18.0) self.assertEqual(image_info.panfactor, 1) self.assertEqual(image_info.date_diff, -9999) self.assertEqual(image_info.year_diff, -9999) self.assertAlmostEqual(image_info.score, 77.34933333333333) image_info.get_raster_stats() stat_dct = {1: [3.0, 160.0, 24.244377057512704, 7.0315102573397938]} datapixelcount_dct = { 1: 976247314, 2: 976247314, 3: 976247314, 4: 976247314 } for i in range(len(image_info.stat_dct[1])): self.assertAlmostEqual(image_info.stat_dct[1][i], stat_dct[1][i]) self.assertEqual(image_info.datapixelcount_dct, datapixelcount_dct)
def run_mosaic(tile_builder_script, inpath, mosaicname, mosaic_dir, args, pos_arg_keys): if os.path.isfile(inpath): bTextfile = True elif os.path.isdir(inpath): bTextfile = False if not os.path.isdir(mosaic_dir): os.makedirs(mosaic_dir) ## TODO: verify logger woks for both interactive and hpc jobs #### Configure Logger if args.log is not None: logfile = os.path.abspath(args.log) else: logfile = os.path.join(mosaic_dir, default_logfile) lfh = logging.FileHandler(logfile) lfh.setLevel(logging.DEBUG) formatter = logging.Formatter('%(asctime)s %(levelname)s- %(message)s', '%m-%d-%Y %H:%M:%S') lfh.setFormatter(formatter) logger.addHandler(lfh) lsh = logging.StreamHandler() lsh.setLevel(logging.INFO) formatter = logging.Formatter('%(asctime)s %(levelname)s- %(message)s', '%m-%d-%Y %H:%M:%S') lsh.setFormatter(formatter) logger.addHandler(lsh) #### Get exclude list if specified if args.exclude is not None: if not os.path.isfile(args.exclude): logger.error("Value for option --exclude-list is not a valid file") f = open(args.exclude, 'r') exclude_list = set([line.rstrip() for line in f.readlines()]) else: exclude_list = set() #### Get Images #logger.info("Reading input images") xs = [] ys = [] image_list = utils.find_images_with_exclude_list(inpath, bTextfile, mosaic.EXTS, exclude_list) if len(image_list) == 0: raise RuntimeError( "No images found in input file or directory: {}".format(inpath)) # remove duplicate images image_list_unique = list(set(image_list)) dupes = [x for n, x in enumerate(image_list) if x in image_list[:n]] if len(dupes) > 0: logger.info("Removed %i duplicate image paths", len(dupes)) logger.debug("Dupes: %s", dupes) image_list = image_list_unique logger.info("%i existing images found", len(image_list)) #### gather image info list logger.info("Getting image info") imginfo_list = [mosaic.ImageInfo(image, "IMAGE") for image in image_list] #### Get mosaic parameters logger.info("Setting mosaic parameters") params = mosaic.getMosaicParameters(imginfo_list[0], args) logger.info("Mosaic parameters: band count=%i, datatype=%s", params.bands, params.datatype) logger.info("Mosaic parameters: projection=%s", params.proj) #### Remove images that do not match ref logger.info("Applying attribute filter") imginfo_list2 = mosaic.filterMatchingImages(imginfo_list, params) if len(imginfo_list2) == 0: raise RuntimeError( "No valid images found. Check input filter parameters.") logger.info("%i of %i images match filter", len(imginfo_list2), len(image_list)) #### if extent is specified, build tile params and compare extent to input image geom if args.extent: imginfo_list3 = mosaic.filter_images_by_geometry(imginfo_list2, params) #### else set extent after image geoms computed else: #### Get geom for each image imginfo_list3 = [] for iinfo in imginfo_list2: if iinfo.geom is not None: xs = xs + iinfo.xs ys = ys + iinfo.ys imginfo_list3.append(iinfo) else: # remove from list if no geom logger.debug("Null geometry for image: %s", iinfo.srcfn) params.xmin = min(xs) params.xmax = max(xs) params.ymin = min(ys) params.ymax = max(ys) poly_wkt = 'POLYGON (( {} {}, {} {}, {} {}, {} {}, {} {} ))'.format( params.xmin, params.ymin, params.xmin, params.ymax, params.xmax, params.ymax, params.xmax, params.ymin, params.xmin, params.ymin) params.extent_geom = ogr.CreateGeometryFromWkt(poly_wkt) if len(imginfo_list3) == 0: raise RuntimeError("No images found that intersect mosaic extent") logger.info( "Mosaic parameters: resolution %f x %f, tilesize %f x %f, extent %f %f %f %f", params.xres, params.yres, params.xtilesize, params.ytilesize, params.xmin, params.xmax, params.ymin, params.ymax) logger.info("%d of %d input images intersect mosaic extent", len(imginfo_list3), len(imginfo_list2)) ## Sort images by score logger.info("Reading image metadata and determining sort order") for iinfo in imginfo_list3: iinfo.getScore(params) if not args.nosort: imginfo_list3.sort(key=lambda x: x.score) logger.info("Getting Exact Image geometry") imginfo_list4 = [] all_valid = True for iinfo in imginfo_list3: if iinfo.score > 0 or args.nosort: simplify_tolerance = 2.0 * ( (params.xres + params.yres) / 2.0 ) ## 2 * avg(xres, yres), should be 1 for panchromatic mosaics where res = 0.5m geom, xs1, ys1 = mosaic.GetExactTrimmedGeom( iinfo.srcfp, step=args.cutline_step, tolerance=simplify_tolerance) if geom is None: logger.warning( "%s: geometry could not be determined, verify image is valid", iinfo.srcfn) all_valid = False elif geom.IsEmpty(): logger.warning("%s: geometry is empty", iinfo.srcfn) all_valid = False else: iinfo.geom = geom tm = datetime.today() imginfo_list4.append(iinfo) centroid = geom.Centroid() logger.info("%s: geometry acquired - centroid: %f, %f", iinfo.srcfn, centroid.GetX(), centroid.GetY()) #print(geom) else: logger.debug("Image has an invalid score: %s --> %i", iinfo.srcfp, iinfo.score) if not all_valid: if not args.allow_invalid_geom: raise RuntimeError( "Some source images do not have valid geometries. Cannot proceeed" ) else: logger.info( "--allow-invalid-geom used; mosaic will be created using %i valid images (%i invalid \ images not used.)".format( len(imginfo_list4), len(imginfo_list3) - len(imginfo_list4))) # Get stats if needed logger.info("Getting image metadata") for iinfo in imginfo_list4: logger.info(iinfo.srcfn) if args.calc_stats or args.median_remove: iinfo.get_raster_stats(args.calc_stats, args.median_remove) # Build componenet index if args.component_shp: if args.mode == "ALL" or args.mode == "SHP": contribs = [(iinfo, iinfo.geom) for iinfo in imginfo_list4] logger.info("Number of contributors: %d", len(contribs)) logger.info("Building component index") comp_shp = mosaicname + "_components.shp" if len(contribs) > 0: if os.path.isfile(comp_shp): logger.info("Components shapefile already exists: %s", comp_shp) else: build_shp(contribs, comp_shp, args, params) else: logger.error("No contributing images") # Build cutlines index #### Overlay geoms and remove non-contributors logger.info("Overlaying images to determine contribution geom") contribs = mosaic.determine_contributors(imginfo_list4, params.extent_geom, args.min_contribution_area) logger.info("Number of contributors: %d", len(contribs)) if args.mode == "ALL" or args.mode == "SHP": logger.info("Building cutlines index") shp = mosaicname + "_cutlines.shp" if len(contribs) > 0: if os.path.isfile(shp): logger.info("Cutlines shapefile already exists: %s", shp) else: build_shp(contribs, shp, args, params) else: logger.error("No contributing images") ## Create tile objects tiles = [] xtiledim = math.ceil((params.xmax - params.xmin) / params.xtilesize) ytiledim = math.ceil((params.ymax - params.ymin) / params.ytilesize) logger.info("Tiles: %d rows, %d columns", ytiledim, xtiledim) xtdb = len(str(int(xtiledim))) ytdb = len(str(int(ytiledim))) i = 1 for x in mosaic.drange(params.xmin, params.xmax, params.xtilesize): # Columns if x + params.xtilesize > params.xmax: x2 = params.xmax else: x2 = x + params.xtilesize j = 1 for y in mosaic.drange(params.ymin, params.ymax, params.ytilesize): # Rows if y + params.ytilesize > params.ymax: y2 = params.ymax else: y2 = y + params.ytilesize tilename = "{}_{}_{}.tif".format(mosaicname, mosaic.buffernum(j, ytdb), mosaic.buffernum(i, xtdb)) tile = mosaic.TileParams(x, x2, y, y2, j, i, tilename) tiles.append(tile) j += 1 i += 1 #### Write shapefile of tiles if len(tiles) == 0: raise RuntimeError("No tile objects created") if args.mode == "ALL" or args.mode == "SHP": build_tiles_shp(mosaicname, tiles, params) ## Build tile tasks task_queue = [] #### Create task for each tile arg_keys_to_remove = ('l', 'qsubscript', 'parallel_processes', 'log', 'mode', 'extent', 'resolution', 'bands', 'max_cc', 'exclude', 'nosort', 'component_shp', 'cutline_step', 'min_contribution_area', 'calc_stats', 'pbs', 'slurm', 'tday', 'tyear', 'allow_invalid_geom') tile_arg_str = taskhandler.convert_optional_args_to_string( args, pos_arg_keys, arg_keys_to_remove) logger.debug("Identifying components of %i subtiles", len(tiles)) i = 0 for t in tiles: logger.debug("Identifying components of tile %i of %i: %s", i, len(tiles), os.path.basename(t.name)) #### determine which images in each tile - create geom and query image geoms logger.debug("Running intersect with imagery") intersects = [] for iinfo, contrib_geom in contribs: if contrib_geom.Intersects(t.geom): if args.median_remove: ## parse median dct into text median_string = ";".join([ "{}:{}".format(k, v) for k, v in iinfo.median.items() ]) intersects.append("{},{}".format(iinfo.srcfp, median_string)) else: intersects.append(iinfo.srcfp) #### If any images are in the tile, mosaic them if len(intersects) > 0: tile_basename = os.path.basename(os.path.splitext(t.name)[0]) logger.info("Number of contributors to subtile %s: %i", tile_basename, len(intersects)) itpath = os.path.join(mosaic_dir, tile_basename + "_intersects.txt") it = open(itpath, "w") it.write("\n".join(intersects)) it.close() #### Submit QSUB job logger.debug("Building mosaicking job for tile: %s", os.path.basename(t.name)) if not os.path.isfile(t.name): cmd = r'{} {} -e {} {} {} {} -r {} {} -b {} {} {}'.format( tile_builder_script, tile_arg_str, t.xmin, t.xmax, t.ymin, t.ymax, params.xres, params.yres, params.bands, t.name, itpath) task = taskhandler.Task( 'Tile {0}'.format(os.path.basename(t.name)), 'Mos{:04g}'.format(i), 'python', cmd) if args.mode == "ALL" or args.mode == "MOSAIC": logger.debug(cmd) task_queue.append(task) else: logger.info("Tile already exists: %s", os.path.basename(t.name)) i += 1 if args.mode == "ALL" or args.mode == "MOSAIC": logger.info("Submitting Tasks") #logger.info(task_queue) if len(task_queue) > 0: try: task_handler = taskhandler.ParallelTaskHandler( args.parallel_processes) except RuntimeError as e: logger.error(e) else: if task_handler.num_processes > 1: logger.info("Number of child processes to spawn: %i", task_handler.num_processes) task_handler.run_tasks(task_queue) logger.info("Done") else: logger.info("No tasks to process")
def HandleTile(t, src, dstdir, csvpath, args, exclude_list): otxtpath = os.path.join( dstdir, "{}_{}_orig.txt".format(os.path.basename(csvpath)[:-4], t.name)) mtxtpath = os.path.join( dstdir, "{}_{}_ortho.txt".format(os.path.basename(csvpath)[:-4], t.name)) if os.path.isfile(otxtpath) and os.path.isfile( mtxtpath) and args.overwrite is False: logger.info("Tile %s processing files already exist", t.name) else: logger.info("Tile %s", t.name) t_srs = osr.SpatialReference() t_srs.ImportFromEPSG(t.epsg) #### Open mfp dsp, lyrn = utils.get_source_names(src) ds = ogr.Open(dsp) if ds is None: logger.error("Open failed") else: lyr = ds.GetLayerByName(lyrn) if not lyr: raise RuntimeError( "Layer {} does not exist in dataset {}".format(lyrn, dsp)) else: s_srs = lyr.GetSpatialRef() #logger.debug(str(s_srs)) #logger.debug(str(t.geom)) tile_geom_in_s_srs = t.geom.Clone() if not t_srs.IsSame(s_srs): ict = osr.CoordinateTransformation(t_srs, s_srs) ct = osr.CoordinateTransformation(s_srs, t_srs) tile_geom_in_s_srs.Transform(ict) # if the geometry crosses meridian, split it into multipolygon (else this breaks SetSpatialFilter) if utils.doesCross180(tile_geom_in_s_srs): logger.debug( "tile_geom_in_s_srs crosses 180 meridian; splitting to multiple polygons..." ) tile_geom_in_s_srs = utils.getWrappedGeometry( tile_geom_in_s_srs) lyr.ResetReading() lyr.SetSpatialFilter(tile_geom_in_s_srs) feat = lyr.GetNextFeature() imginfo_list1 = [] while feat: iinfo = mosaic.ImageInfo(feat, "RECORD", srs=s_srs) if iinfo.geom is not None and iinfo.geom.GetGeometryType( ) in (ogr.wkbPolygon, ogr.wkbMultiPolygon): if not t_srs.IsSame(s_srs): iinfo.geom.Transform(ct) ## fix self-intersection errors caused by reprojecting over 180 temp = iinfo.geom.Buffer( 0.1 ) # assumes a projected coordinate system with meters or feet as units iinfo.geom = temp if iinfo.geom.Intersects(t.geom): if iinfo.scene_id in exclude_list: logger.debug( "Scene in exclude list, excluding: %s", iinfo.srcfp) elif not os.path.isfile(iinfo.srcfp): logger.warning( "Scene path is invalid, excluding %s (path = %s)", iinfo.scene_id, iinfo.srcfp) elif args.require_pan: srcfp = iinfo.srcfp srcdir, mul_name = os.path.split(srcfp) if iinfo.sensor in ["WV02", "WV03", "QB02"]: pan_name = mul_name.replace("-M", "-P") elif iinfo.sensor == "GE01": if "_5V" in mul_name: pan_name_base = srcfp[:-24].replace( "M0", "P0") candidates = glob.glob(pan_name_base + "*") candidates2 = [ f for f in candidates if f.endswith(('.ntf', '.NTF', '.tif', '.TIF')) ] if len(candidates2) == 0: pan_name = '' elif len(candidates2) == 1: pan_name = os.path.basename( candidates2[0]) else: pan_name = '' logger.error( '%i panchromatic images match the multispectral image name ' '%s', len(candidates2), mul_name) else: pan_name = mul_name.replace("-M", "-P") elif iinfo.sensor == "IK01": pan_name = mul_name.replace("blu", "pan") pan_name = mul_name.replace("msi", "pan") pan_name = mul_name.replace("bgrn", "pan") pan_srcfp = os.path.join(srcdir, pan_name) if not os.path.isfile(pan_srcfp): logger.debug( "Image does not have a panchromatic component, excluding: %s", iinfo.srcfp) else: logger.debug("Intersect %s, %s: %s", iinfo.scene_id, iinfo.srcfp, str(iinfo.geom)) imginfo_list1.append(iinfo) else: logger.debug("Intersect %s, %s: %s", iinfo.scene_id, iinfo.srcfp, str(iinfo.geom)) imginfo_list1.append(iinfo) feat = lyr.GetNextFeature() ds = None logger.info("Number of intersects in tile %s: %i", t.name, len(imginfo_list1)) if len(imginfo_list1) > 0: #### Get mosaic parameters logger.debug("Getting mosaic parameters") params = mosaic.getMosaicParameters(imginfo_list1[0], args) #### Remove images that do not match ref logger.debug("Setting image pattern filter") imginfo_list2 = mosaic.filterMatchingImages( imginfo_list1, params) logger.info("Number of images matching filter: %i", len(imginfo_list2)) if args.nosort is False: #### Sort by quality logger.debug("Sorting images by quality") imginfo_list3 = [] for iinfo in imginfo_list2: iinfo.getScore(params) if iinfo.score > 0: imginfo_list3.append(iinfo) # sort so highest score is last imginfo_list3.sort(key=lambda x: x.score) else: imginfo_list3 = list(imginfo_list2) #### Overlay geoms and remove non-contributors logger.debug("Overlaying images to determine contributors") contribs = mosaic.determine_contributors( imginfo_list3, t.geom, args.min_contribution_area) logger.info("Number of contributing images: %i", len(contribs)) if len(contribs) > 0: if args.build_shp: ####################################################### #### Create Shp shp = os.path.join( dstdir, "{}_{}_imagery.shp".format(args.mosaic, t.name)) logger.debug("Creating shapefile of geoms: %s", shp) fields = [("IMAGENAME", ogr.OFTString, 100), ("SCORE", ogr.OFTReal, 0)] OGR_DRIVER = "ESRI Shapefile" ogrDriver = ogr.GetDriverByName(OGR_DRIVER) if ogrDriver is None: logger.debug("OGR: Driver %s is not available", OGR_DRIVER) sys.exit(-1) if os.path.isfile(shp): ogrDriver.DeleteDataSource(shp) vds = ogrDriver.CreateDataSource(shp) if vds is None: logger.debug("Could not create shp") sys.exit(-1) shpd, shpn = os.path.split(shp) shpbn, shpe = os.path.splitext(shpn) lyr = vds.CreateLayer(shpbn, t_srs, ogr.wkbPolygon) if lyr is None: logger.debug("ERROR: Failed to create layer: %s", shpbn) sys.exit(-1) for fld, fdef, flen in fields: field_defn = ogr.FieldDefn(fld, fdef) if fdef == ogr.OFTString: field_defn.SetWidth(flen) if lyr.CreateField(field_defn) != 0: logger.debug( "ERROR: Failed to create field: %s", fld) for iinfo, geom in contribs: logger.debug("Image: %s", iinfo.srcfn) feat = ogr.Feature(lyr.GetLayerDefn()) feat.SetField("IMAGENAME", iinfo.srcfn) feat.SetField("SCORE", iinfo.score) feat.SetGeometry(geom) if lyr.CreateFeature(feat) != 0: logger.debug( "ERROR: Could not create feature for image %s", iinfo.srcfn) else: logger.debug("Created feature for image: %s", iinfo.srcfn) feat.Destroy() #### Write textfiles if not os.path.isdir(dstdir): os.makedirs(dstdir) otxtpath = os.path.join( dstdir, "{}_{}_orig.txt".format(args.mosaic, t.name)) mtxtpath = os.path.join( dstdir, "{}_{}_ortho.txt".format(args.mosaic, t.name)) otxt = open(otxtpath, 'w') mtxt = open(mtxtpath, 'w') for iinfo, geom in contribs: if not os.path.isfile(iinfo.srcfp): logger.warning("Image does not exist: %s", iinfo.srcfp) otxt.write("{}\n".format(iinfo.srcfp)) m_fn = "{0}_u08{1}{2}.tif".format( os.path.splitext(iinfo.srcfn)[0], args.stretch, t.epsg) mtxt.write( os.path.join(dstdir, 'ortho', t.name, m_fn) + "\n") otxt.close()
def HandleTile(t, src, dstdir, csvpath, args, exclude_list): otxtpath = os.path.join(dstdir, "{}_{}_orig.txt".format(os.path.basename(csvpath)[:-4], t.name)) mtxtpath = os.path.join(dstdir, "{}_{}_ortho.txt".format(os.path.basename(csvpath)[:-4], t.name)) if os.path.isfile(otxtpath) and os.path.isfile(mtxtpath) and args.overwrite is False: logger.info("Tile %s processing files already exist", t.name) else: logger.info("Tile %s", t.name) t_srs = utils.osr_srs_preserve_axis_order(osr.SpatialReference()) t_srs.ImportFromEPSG(t.epsg) #### Open mfp dsp, lyrn = utils.get_source_names(src) ds = ogr.Open(dsp) if ds is None: logger.error("Open failed") else: lyr = ds.GetLayerByName(lyrn) if not lyr: raise RuntimeError("Layer {} does not exist in dataset {}".format(lyrn, dsp)) else: s_srs = lyr.GetSpatialRef() #logger.debug(str(s_srs)) #logger.debug(str(t.geom)) tile_geom_in_s_srs = t.geom.Clone() if not t_srs.IsSame(s_srs): ict = osr.CoordinateTransformation(t_srs, s_srs) ct = osr.CoordinateTransformation(s_srs, t_srs) tile_geom_in_s_srs.Transform(ict) # if the geometry crosses meridian, split it into multipolygon (else this breaks SetSpatialFilter) if utils.doesCross180(tile_geom_in_s_srs): logger.debug("tile_geom_in_s_srs crosses 180 meridian; splitting to multiple polygons...") tile_geom_in_s_srs = utils.getWrappedGeometry(tile_geom_in_s_srs) lyr.ResetReading() lyr.SetSpatialFilter(tile_geom_in_s_srs) feat = lyr.GetNextFeature() imginfo_list1 = [] while feat: iinfo = mosaic.ImageInfo(feat, "RECORD", srs=s_srs) if iinfo.geom is not None and iinfo.geom.GetGeometryType() in (ogr.wkbPolygon, ogr.wkbMultiPolygon): if not t_srs.IsSame(s_srs): iinfo.geom.Transform(ct) ## fix self-intersection errors caused by reprojecting over 180 temp = iinfo.geom.Buffer(0.1) # assumes a projected coordinate system with meters or feet as units iinfo.geom = temp if iinfo.geom.Intersects(t.geom): if iinfo.scene_id in exclude_list: logger.debug("Scene in exclude list, excluding: %s", iinfo.srcfp) elif not os.path.isfile(iinfo.srcfp) and iinfo.status != "tape": #logger.info("iinfo.status != tape: {0}".format(iinfo.status != "tape")) logger.warning("Scene path is invalid, excluding %s (path = %s) (status = %s)", iinfo.scene_id, iinfo.srcfp, iinfo.status) elif args.require_pan: srcfp = iinfo.srcfp srcdir, mul_name = os.path.split(srcfp) if iinfo.sensor in ["WV02", "WV03", "QB02"]: pan_name = mul_name.replace("-M", "-P") elif iinfo.sensor == "GE01": if "_5V" in mul_name: pan_name_base = srcfp[:-24].replace("M0", "P0") candidates = glob.glob(pan_name_base + "*") candidates2 = [f for f in candidates if f.endswith(('.ntf', '.NTF', '.tif', '.TIF'))] if len(candidates2) == 0: pan_name = '' elif len(candidates2) == 1: pan_name = os.path.basename(candidates2[0]) else: pan_name = '' logger.error('%i panchromatic images match the multispectral image name ' '%s', len(candidates2), mul_name) else: pan_name = mul_name.replace("-M", "-P") elif iinfo.sensor == "IK01": pan_name = mul_name.replace("blu", "pan") pan_name = mul_name.replace("msi", "pan") pan_name = mul_name.replace("bgrn", "pan") pan_srcfp = os.path.join(srcdir, pan_name) if not os.path.isfile(pan_srcfp): logger.debug("Image does not have a panchromatic component, excluding: %s", iinfo.srcfp) else: logger.debug("Intersect %s, %s: %s", iinfo.scene_id, iinfo.srcfp, str(iinfo.geom)) imginfo_list1.append(iinfo) else: logger.debug("Intersect %s, %s: %s", iinfo.scene_id, iinfo.srcfp, str(iinfo.geom)) imginfo_list1.append(iinfo) feat = lyr.GetNextFeature() ds = None logger.info("Number of intersects in tile %s: %i", t.name, len(imginfo_list1)) if len(imginfo_list1) > 0: #### Get mosaic parameters logger.debug("Getting mosaic parameters") params = mosaic.getMosaicParameters(imginfo_list1[0], args) #### Remove images that do not match ref logger.debug("Setting image pattern filter") imginfo_list2 = mosaic.filterMatchingImages(imginfo_list1, params) logger.info("Number of images matching filter: %i", len(imginfo_list2)) if args.nosort is False: #### Sort by quality logger.debug("Sorting images by quality") imginfo_list3 = [] for iinfo in imginfo_list2: iinfo.getScore(params) if iinfo.score > 0: imginfo_list3.append(iinfo) # sort so highest score is last imginfo_list3.sort(key=lambda x: x.score) else: imginfo_list3 = list(imginfo_list2) #### Overlay geoms and remove non-contributors logger.debug("Overlaying images to determine contributors") contribs = mosaic.determine_contributors(imginfo_list3, t.geom, args.min_contribution_area) logger.info("Number of contributing images: %i", len(contribs)) if len(contribs) > 0: if args.build_shp: ####################################################### #### Create Shp shp = os.path.join(dstdir, "{}_{}_imagery.shp".format(args.mosaic, t.name)) logger.debug("Creating shapefile of geoms: %s", shp) fields = [("IMAGENAME", ogr.OFTString, 100), ("SCORE", ogr.OFTReal, 0)] OGR_DRIVER = "ESRI Shapefile" ogrDriver = ogr.GetDriverByName(OGR_DRIVER) if ogrDriver is None: logger.debug("OGR: Driver %s is not available", OGR_DRIVER) sys.exit(-1) if os.path.isfile(shp): ogrDriver.DeleteDataSource(shp) vds = ogrDriver.CreateDataSource(shp) if vds is None: logger.debug("Could not create shp") sys.exit(-1) shpd, shpn = os.path.split(shp) shpbn, shpe = os.path.splitext(shpn) lyr = vds.CreateLayer(shpbn, t_srs, ogr.wkbPolygon) if lyr is None: logger.debug("ERROR: Failed to create layer: %s", shpbn) sys.exit(-1) for fld, fdef, flen in fields: field_defn = ogr.FieldDefn(fld, fdef) if fdef == ogr.OFTString: field_defn.SetWidth(flen) if lyr.CreateField(field_defn) != 0: logger.debug("ERROR: Failed to create field: %s", fld) for iinfo, geom in contribs: logger.debug("Image: %s", iinfo.srcfn) feat = ogr.Feature(lyr.GetLayerDefn()) feat.SetField("IMAGENAME", iinfo.srcfn) feat.SetField("SCORE", iinfo.score) feat.SetGeometry(geom) if lyr.CreateFeature(feat) != 0: logger.debug("ERROR: Could not create feature for image %s", iinfo.srcfn) else: logger.debug("Created feature for image: %s", iinfo.srcfn) feat.Destroy() #### Write textfiles if not os.path.isdir(dstdir): os.makedirs(dstdir) otxtpath = os.path.join(dstdir, "{}_{}_orig.txt".format(args.mosaic, t.name)) otxtpath_ontape = os.path.join(dstdir, "{}_{}_orig_ontape.csv".format(args.mosaic, t.name)) mtxtpath = os.path.join(dstdir, "{}_{}_ortho.txt".format(args.mosaic, t.name)) rn_fromtape_basedir = os.path.join(dstdir, "renamed_fromtape") rn_fromtape_path = os.path.join(rn_fromtape_basedir, t.name) otxt = open(otxtpath, 'w') ttxt = open(otxtpath_ontape, 'w') mtxt = open(mtxtpath, 'w') # write header ttxt.write("{0},{1},{2}\n".format("SCENE_ID", "S_FILEPATH", "STATUS")) tape_ct = 0 for iinfo, geom in contribs: if not os.path.isfile(iinfo.srcfp) and iinfo.status != "tape": logger.warning("Image does not exist: %s", iinfo.srcfp) if iinfo.status == "tape": tape_ct += 1 ttxt.write("{0},{1},{2}\n".format(iinfo.scene_id, iinfo.srcfp, iinfo.status)) # get srcfp with file extension srcfp_file = os.path.basename(iinfo.srcfp) otxt.write("{}\n".format(os.path.join(rn_fromtape_path, srcfp_file))) else: otxt.write("{}\n".format(iinfo.srcfp)) m_fn = "{0}_u08{1}{2}.tif".format( os.path.splitext(iinfo.srcfn)[0], args.stretch, t.epsg ) mtxt.write(os.path.join(dstdir, 'ortho', t.name, m_fn) + "\n") otxt.close() if tape_ct == 0: logger.debug("No files need to be pulled from tape.") os.remove(otxtpath_ontape) else: # make output dirs from tape if not os.path.isdir(rn_fromtape_basedir): os.mkdir(rn_fromtape_basedir) if not os.path.isdir(rn_fromtape_path): os.mkdir(rn_fromtape_path) tape_tmp = os.path.join(dstdir, "{0}_{1}_tmp".format(args.mosaic, t.name)) if not os.path.isdir(tape_tmp): os.mkdir(tape_tmp) logger.warning("{0} scenes are not accessible, as they are on tape. Please use ir.py to pull " "scenes using file '{1}'. They must be put in directory '{2}', as file '{3}' " "contains hard-coded paths to said files (necessary to perform " "orthorectification). Please set a --tmp path (use '{4}').\n" "Note that if some (or all) scenes have already been pulled from tape, ir.py " "will not pull them again.\n". format(tape_ct, otxtpath_ontape, rn_fromtape_path, otxtpath, tape_tmp)) tape_log = "{0}_{1}_ir_log_{2}.log".format(args.mosaic, t.name, datetime.today().strftime("%Y%m%d%H%M%S")) root_pgclib_path = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "pgclib", "") logger.info("Suggested ir.py command:\n\n" "" "python {}ir.py -i {} -o {} --tmp {} -tm link 2>&1 | tee {}" .format(root_pgclib_path, otxtpath_ontape, rn_fromtape_path, tape_tmp, os.path.join(dstdir, tape_log)))