def rectifyRaster(src, dst_filename, dst_proj, gcps, tmp_filename='tmpfile_remove.tif', resampling_type='near',\ data_type='Float32', output_format='GTiff', dst_options=['COMPRESS=LZW']): """ Takes GCPs created using gdal api, adds them to the not rectified image, and rectifies it. * resampling_type keywords are: 'near','bilinear', 'cubic', 'cubicspline', 'lanczos' * data_type keywords are: 'Byte', 'Float32', 'Float64', 'UInt16' , 'UInt32', 'Int16', 'Int32' """ # legacy: dictionary of possible settings for resampling_type # resTypes = { 'near':'GRA_NearestNeighbour', 'bilinear':'GRA_Bilinear', 'cubic':'GRA_Cubic', \ # 'cubicspline':'GRA_CubicSpline','lanczos':'GRA_Lanczos' } driver = gdal.GetDriverByName(output_format) # dst = driver.Create(dst_filename, src.RasterXSize, src.RasterYSize, src.RasterCount, \ # gdal.GetDataTypeByName(data_type), dst_options) dst = driver.CreateCopy(tmp_filename, src, 1, dst_options) dst.SetGCPs(gcps, src.GetProjection()) dst.SetGeoTransform(gdal.GCPsToGeoTransform(gcps)) dst.SetProjection(dst_proj) del dst, src # flush # @FIX find a way to transform the data with Python bindings #'-srcnodata','0', '-dstnodata','None', subprocess.call([ 'gdalwarp', '-r', resampling_type, '-ot', data_type, '-co', 'COMPRESS=LZW', '-q', tmp_filename, dst_filename ]) os.unlink(tmp_filename) # remove the tmp file created during execution
def convert(self): options=self.map.options if options.after_name: name_patt=self.name elif options.after_map: name_patt=self.map.file else: name_patt=self.img_file base = dst_path(name_patt, options.dst_dir) if options.long_name: base += ' - ' + "".join([c for c in self.name if c .isalpha() or c.isdigit() or c in '-_.() ']) dst_dir=os.path.split(base)[0] out_format='VRT' ext='.'+out_format.lower() try: start_dir=os.getcwd() if dst_dir: os.chdir(dst_dir) dst_file = os.path.abspath(os.path.basename(base+ext)) # output file dst_drv = gdal.GetDriverByName(out_format) dst_ds = dst_drv.CreateCopy( dst_file.encode(locale.getpreferredencoding()), self.raster_ds, 0 ) dst_ds.SetProjection(self.srs) #double x = 0.0, double y = 0.0, double z = 0.0, double pixel = 0.0, #double line = 0.0, char info = "", char id = "" gcps=[gdal.GCP(c[0],c[1],0,p[0],p[1],'',i) for i,p,c in self.refs] dst_ds.SetGCPs(gcps,self.refs.srs()) dst_geotr=gdal.GCPsToGeoTransform(gcps) # if len(gcps) < 5 else (0.0, 1.0, 0.0, 0.0, 0.0, 1.0) dst_ds.SetGeoTransform(dst_geotr) poly,gmt_data=self.cut_poly(dst_ds) if poly: dst_ds.SetMetadataItem('CUTLINE',poly) if self.name: dst_ds.SetMetadataItem('DESCRIPTION',self.name.encode('utf-8')) dst_ds = None # close dataset # re_sub_file(dst_file, [ # ('^.*<GeoTransform>.*\n',''), # ('^.*<SRS>.*\n','') # ]) finally: self.raster_ds = None os.chdir(start_dir) if options.get_cutline: # print cutline then return print poly return if gmt_data and options.cut_file: # create shapefile with a cut polygon with open(base+'.gmt','w+') as f: f.write(gmt_data) return dst_file
def SetGCPsToGeoTransform(cornerPointUL, cornerPointUR, cornerPointLR, cornerPointLL, frameCenterLon, frameCenterLat): ''' Make Geotranform from pixel to lon lat coordinates ''' gcps = [] global gcornerPointUL gcornerPointUL = cornerPointUL global gcornerPointUR gcornerPointUR = cornerPointUR global gcornerPointLR gcornerPointLR = cornerPointLR global gcornerPointLL gcornerPointLL = cornerPointLL global gframeCenterLat gframeCenterLat = frameCenterLat global gframeCenterLon gframeCenterLon = frameCenterLon global geotransform geotransform = gdal.GCPsToGeoTransform(gcps) src = np.float64( np.array([[0.0, 0.0], [xSize, 0.0], [xSize, ySize], [0.0, ySize]])) dst = np.float64( np.array([cornerPointUL, cornerPointUR, cornerPointLR, cornerPointLL])) geotransform = from_points(src, dst) if geotransform is None: qgsu.showUserAndLogMessage(QCoreApplication.translate( "QgsFmvUtils", 'Unable to extract a geotransform.'), onlyLog=True) return
def test_gcps2gt_1(): gt = gdal.GCPsToGeoTransform( _list2gcps([(0.0, 0.0, 400000, 370000), (100.0, 0.0, 410000, 370000), (100.0, 200.0, 410000, 368000)])) assert gdaltest.geotransform_equals( gt, (400000.0, 100.0, 0.0, 370000.0, 0.0, -10.0), 0.000001)
def print_layer_list(names, sds): print "----- Accessible layers: -----" out_names = [s.rsplit(':', 1)[1] for s in names] for ind, name in enumerate(out_names): geotrans = gdal.GCPsToGeoTransform(sds[ind].GetGCPs()) if geotrans: print "%s. %s" % (ind, name)
def main(argv): if len(argv) < 2: print("Usage: gcps2wld.py source_file") return 1 filename = argv[1] dataset = gdal.Open(filename) if dataset is None: print('Unable to open %s' % filename) return 1 gcps = dataset.GetGCPs() if gcps is None or not gcps: print('No GCPs found on file ' + filename) return 1 geotransform = gdal.GCPsToGeoTransform(gcps) if geotransform is None: print('Unable to extract a geotransform.') return 1 print(geotransform[1]) print(geotransform[4]) print(geotransform[2]) print(geotransform[5]) print(geotransform[0] + 0.5 * geotransform[1] + 0.5 * geotransform[2]) print(geotransform[3] + 0.5 * geotransform[4] + 0.5 * geotransform[5])
def test_gcps2gt_3(): approx_ok = 0 gt = gdal.GCPsToGeoTransform( _list2gcps([(0.0, 0.0, 400000, 370000), (100.0, 0.0, 410000, 370000), (100.0, 200.0, 410000, 368000), (0.0, 200.0, 400000, 360000)]), approx_ok) assert gt is None, 'Expected failure when no good solution.'
def test_gcps2gt_2(): gt = gdal.GCPsToGeoTransform( _list2gcps([(0.0, 0.0, 400000, 370000), (100.0, 0.0, 410000, 370000), (100.0, 200.0, 410000, 368000), (0.0, 200.0, 400000, 368000.01)])) assert gdaltest.geotransform_equals( gt, (400000.0, 100.0, 0.0, 370000.0025, -5e-05, -9.999975), 0.000001)
def SetGCPsToGeoTransform(cornerPointUL, cornerPointUR, cornerPointLR, cornerPointLL, frameCenterLon, frameCenterLat, ele): ''' Make Geotranform from pixel to lon lat coordinates ''' gcps = [] global gcornerPointUL, gcornerPointUR, gcornerPointLR, gcornerPointLL, gframeCenterLat, gframeCenterLon, geotransform_affine, geotransform # TEMP FIX : If have elevation the geotransform is wrong if ele: del cornerPointUL[-1] del cornerPointUR[-1] del cornerPointLR[-1] del cornerPointLL[-1] gcornerPointUL = cornerPointUL gcornerPointUR = cornerPointUR gcornerPointLR = cornerPointLR gcornerPointLL = cornerPointLL gframeCenterLat = frameCenterLat gframeCenterLon = frameCenterLon Height = GetFrameCenter()[2] gcp = gdal.GCP(cornerPointUL[1], cornerPointUL[0], Height, 0, 0, "Corner Upper Left", "1") gcps.append(gcp) gcp = gdal.GCP(cornerPointUR[1], cornerPointUR[0], Height, xSize, 0, "Corner Upper Right", "2") gcps.append(gcp) gcp = gdal.GCP(cornerPointLR[1], cornerPointLR[0], Height, xSize, ySize, "Corner Lower Right", "3") gcps.append(gcp) gcp = gdal.GCP(cornerPointLL[1], cornerPointLL[0], Height, 0, ySize, "Corner Lower Left", "4") gcps.append(gcp) gcp = gdal.GCP(frameCenterLon, frameCenterLat, Height, xSize / 2, ySize / 2, "Center", "5") gcps.append(gcp) geotransform_affine = gdal.GCPsToGeoTransform(gcps) src = np.float64( np.array([[0.0, 0.0], [xSize, 0.0], [xSize, ySize], [0.0, ySize]])) dst = np.float64( np.array([cornerPointUL, cornerPointUR, cornerPointLR, cornerPointLL])) try: geotransform = from_points(src, dst) except Exception: pass if geotransform is None: qgsu.showUserAndLogMessage("", "Unable to extract a geotransform.", onlyLog=True) return
def __init__(self, dataset): super(CoordinateMapper, self).__init__() projection = '' self._geotransform = None if dataset.GetGCPCount(): try: projection = dataset.GetGCPProjection() gcps = dataset.GetGCPs() gcps = _fixedGCPs(gcps) # @TODO: remove self._geotransform = gdal.GCPsToGeoTransform(gcps) except Exception: _log.warning( 'unable to retrieve geo-transform and ' 'projection from GCPs for %s', dataset) if not self._geotransform: projection = dataset.GetProjection() if not projection: projection = dataset.GetProjectionRef() self._geotransform = dataset.GetGeoTransform() if not projection: raise InvalidProjection('unable to get a valid projection') #sref = osr.SpatialReference(projection) # do not work for Pymod API sref = osr.SpatialReference() sref.ImportFromWkt(projection) if not sref.IsGeographic(): sref_target = osr.SpatialReference() sref_target.SetWellKnownGeogCS(self.geogCS) self._srTransform = osr.CoordinateTransformation(sref, sref_target) else: self._srTransform = None # Xgeo = GT(0) + Xpixel*GT(1) + Yline*GT(2) # Ygeo = GT(3) + Xpixel*GT(4) + Yline*GT(5) # # -- -- -- -- -- -- -- -- # | Xgeo | | m11 m12 | | Xpixel | | xoffset | # | | = | | * | | + | | # | Ygeo | | m21 m22 | | Yline | | yoffset | # -- -- -- -- -- -- -- -- xoffset, m11, m12, yoffset, m21, m22 = self._geotransform _log.debug('geotransform = %s', self._geotransform) # Direct transform M = np.array(((m11, m12), (m21, m22))) C = np.array(([xoffset], [yoffset])) self._direct_transform = (M, C) # Invrse transform M = np.linalg.inv(M) C = -np.dot(M, C) self._inverse_transform = (M, C)
def process(self, annotation_files, grid_pts=100, writeback=False): """ entry point into class functionality """ # read annotation xml into dictionary for f in annotation_files: doc = self.readAnnotationFile(f) if doc is not None: # get scene image dimensions print('Densifying geolocation grid in annotation file: {}'. format(f)) dims = self.getDimensions(doc) # extract tie points from annotation schema and reproject to mercator gcps = {'latlon': self.getTiePoints(doc)} gcps['mercator'] = self.reprojectTiePoints( gcps['latlon'], { 'source': self._proj['latlon'], 'target': self._proj['mercator'] }) # create denser tie point grid x_grid, y_grid = self.getDenseGrid(dims, grid_pts) dense_grid = { 'pixel': x_grid.flatten(), 'line': y_grid.flatten() } # interpolate parameter values onto dense grid dense_grid.update( self.interpolateFields( doc, (gcps['latlon']['pixel'], gcps['latlon']['line']), (x_grid, y_grid))) # interpolate gcps onto dense grid geo_transform = gdal.GCPsToGeoTransform(gcps['mercator']) print('{}: Mean sum of squares: {} m '.format( os.path.basename(f), self.computeError(gcps['mercator'], geo_transform))) dense_grid['gcps'] = self.interpolateTiePoints( geo_transform, dense_grid['pixel'], dense_grid['line']) # optionally visualize dense grid map coordinates if writeback: self.plotDenseGrid(dense_grid, grid_pts) # write denser tie point grid to updated annotation file and geotiff self.writeAnnotationFile(doc, dense_grid) # self.writeImageFile( doc, dense_grid ) print('... OK!') return
def SetGCPsToGeoTransform(cornerPointUL, cornerPointUR, cornerPointLR, cornerPointLL, frameCenterLon, frameCenterLat, ele): ''' Make Geotranform from pixel to lon lat coordinates ''' gcps = [] gv.setCornerUL(cornerPointUL) gv.setCornerUR(cornerPointUR) gv.setCornerLR(cornerPointLR) gv.setCornerLL(cornerPointLL) gv.setFrameCenter(frameCenterLat, frameCenterLon) xSize = gv.getXSize() ySize = gv.getYSize() Height = GetFrameCenter()[2] gcp = gdal.GCP(cornerPointUL[1], cornerPointUL[0], Height, 0, 0, "Corner Upper Left", "1") gcps.append(gcp) gcp = gdal.GCP(cornerPointUR[1], cornerPointUR[0], Height, xSize, 0, "Corner Upper Right", "2") gcps.append(gcp) gcp = gdal.GCP(cornerPointLR[1], cornerPointLR[0], Height, xSize, ySize, "Corner Lower Right", "3") gcps.append(gcp) gcp = gdal.GCP(cornerPointLL[1], cornerPointLL[0], Height, 0, ySize, "Corner Lower Left", "4") gcps.append(gcp) gcp = gdal.GCP(frameCenterLon, frameCenterLat, Height, xSize / 2, ySize / 2, "Center", "5") gcps.append(gcp) at = gdal.GCPsToGeoTransform(gcps) gv.setAffineTransform(at) src = np.float64( np.array([[0.0, 0.0], [xSize, 0.0], [xSize, ySize], [0.0, ySize], [xSize / 2.0, ySize / 2.0]])) dst = np.float64( np.array([[cornerPointUL[0], cornerPointUL[1]], [cornerPointUR[0], cornerPointUR[1]], [cornerPointLR[0], cornerPointLR[1]], [cornerPointLL[0], cornerPointLL[1]], [frameCenterLat, frameCenterLon]])) try: geotransform, _ = findHomography(src, dst) gv.setTransform(geotransform) except Exception: pass if geotransform is None: qgsu.showUserAndLogMessage("", "Unable to extract a geotransform.", onlyLog=True) return
def gcps2gt_4(): gt = gdal.GCPsToGeoTransform(_list2gcps([ (0.0, 0.0, 400000, 370000), ])) if gt is not None: gdaltest.post_reason('Expected failure for single GCP.') return 'failure' return 'success'
def gcps2gt_1(): gt = gdal.GCPsToGeoTransform( _list2gcps([(0.0, 0.0, 400000, 370000), (100.0, 0.0, 410000, 370000), (100.0, 200.0, 410000, 368000)])) if not gdaltest.geotransform_equals( gt, (400000.0, 100.0, 0.0, 370000.0, 0.0, -10.0), 0.000001): return 'failure' return 'success'
def do_rgs(data_time_value, rgs_file_path): """ 配准 :param data_time_value: dict 原始图像的信息-GCJ02 { "time" : "", #时间 "timestamp" : "", #时间戳 "url" : "", #下载链接 "extent" : "", #范围 "req_pnt" : "", #该瓦片请求的点坐标 "file_path" : "" #文件的path } :param rgs_file_path: str 配准后保存的路径 :return: rgs_data_item: dict/None { "extent" : "", #范围-WGS84 "file_path" : "", #该文件的路径 } """ # 将tiff保存到配准文件夹 origin_file_path = data_time_value["file_path"] im = Image.open(origin_file_path) im.save(rgs_file_path) # 转换extent extent_gcj02 = data_time_value[ "extent_gcj02"] #[21.532796186275732, 115.14559029127062, 25.66504821372427, 119.65495970872936] extent_wgs84 = gcj02towgs84_extent( extent_gcj02 ) #[21.53519080438208, 115.14078044126353, 25.66805217057752, 119.65050502755392] x1, y1, x2, y2 = extent_wgs84 # 用extent_wgs84对rgs_file_path文件进行配准 ds = gdal.Open(rgs_file_path, gdal.GA_Update) #打开影像 if not ds: return None # 创建坐标系 srs = osr.SpatialReference() srs.SetWellKnownGeogCS('WGS84') # 相关信息 rows = ds.RasterYSize # 行数 cols = ds.RasterXSize # 列数 # 创建地面控制点:经度、纬度、z,照片列数,照片行数 gcps = [ gdal.GCP(y1, x2, 0, 0, 0), # 左上 gdal.GCP(y2, x2, 0, cols - 1, 0), # 右上 gdal.GCP(y1, x1, 0, 0, rows - 1), # 左下 gdal.GCP(y2, x1, 0, cols - 1, rows - 1) # 右下 ] ds.SetGCPs(gcps, srs.ExportToWkt()) ds.SetProjection(srs.ExportToWkt()) ds.SetGeoTransform(gdal.GCPsToGeoTransform(gcps)) del ds return {"extent": extent_wgs84, "file_path": rgs_file_path}
def gcps2gt_2(): gt = gdal.GCPsToGeoTransform( _list2gcps([(0.0, 0.0, 400000, 370000), (100.0, 0.0, 410000, 370000), (100.0, 200.0, 410000, 368000), (0.0, 200.0, 400000, 368000.01)])) if not gdaltest.geotransform_equals( gt, (400000.0, 100.0, 0.0, 370000.0025, -5e-05, -9.999975), 0.000001): return 'fail' return 'success'
def gcps2gt_3(): approx_ok = 0 gt = gdal.GCPsToGeoTransform( _list2gcps([(0.0, 0.0, 400000, 370000), (100.0, 0.0, 410000, 370000), (100.0, 200.0, 410000, 368000), (0.0, 200.0, 400000, 360000)]), approx_ok) if gt is not None: gdaltest.post_reason('Expected failure when no good solution.') return 'failure' return 'success'
def geographic_info(ds, srsout=None): # Read geotransform matrix and source reference system srs = osr.SpatialReference() if ds.GetGCPCount(): gcps = ds.GetGCPs() srs.ImportFromWkt(ds.GetGCPProjection()) geomatrix = gdal.GCPsToGeoTransform(gcps) else: gcps = [] if not ds.GetProjection(): raise ValueError('no geographic info in "%s"' % ds.GetDescription()) srs.ImportFromWkt(ds.GetProjection()) geomatrix = ds.GetGeoTransform() if geomatrix == (0.0, 1.0, 0.0, 0.0, 0.0, 1.0): raise ValueError('no geographic info in "%s"' % ds.GetDescription()) # Set the target reference system srsout = makesrs(srsout) # Instantiate the coordinate transformer transformer = osr.CoordinateTransformation(srs, srsout) # dataset corners setup corners = [] for id_, (pixel, line) in enumerate(( (0, 0), (0, ds.RasterYSize - 1), (ds.RasterXSize - 1, ds.RasterYSize - 1), (ds.RasterXSize - 1, 0))): X = geomatrix[0] + geomatrix[1] * pixel + geomatrix[2] * line Y = geomatrix[3] + geomatrix[4] * pixel + geomatrix[5] * line # Shift to the center of the pixel X += geomatrix[1] / 2.0 Y += geomatrix[5] / 2.0 Z = 0. (x, y, z) = transformer.TransformPoint(X, Y, Z) gcp = gdal.GCP(x, y, z, pixel, line, '', str(id_ + 1)) corners.append(gcp) # convert GCPs to the targer srs outgcps = [] for gcp in gcps: (x, y, z) = transformer.TransformPoint(gcp.GCPX, gcp.GCPY, gcp.GCPZ) gcp = gdal.GCP(x, y, z, gcp.GCPPixel, gcp.GCPLine, gcp.Info, gcp.Id) outgcps.append(gcp) return corners, outgcps
def SetGCPsToGeoTransform(cornerPointUL, cornerPointUR, cornerPointLR, cornerPointLL, frameCenterLon, frameCenterLat): ''' Make Geotranform from pixel to lon lat coordinates ''' gcps = [] global gcornerPointUL gcornerPointUL = cornerPointUL global gcornerPointUR gcornerPointUR = cornerPointUR global gcornerPointLR gcornerPointLR = cornerPointLR global gcornerPointLL gcornerPointLL = cornerPointLL global gframeCenterLat gframeCenterLat = frameCenterLat global gframeCenterLon gframeCenterLon = frameCenterLon global geotransform global geotransform_affine Height = GetFrameCenter()[2] gcp = gdal.GCP(cornerPointUL[1], cornerPointUL[0], Height, 0, 0, "Corner Upper Left", "1") gcps.append(gcp) gcp = gdal.GCP(cornerPointUR[1], cornerPointUR[0], Height, xSize, 0, "Corner Upper Right", "2") gcps.append(gcp) gcp = gdal.GCP(cornerPointLR[1], cornerPointLR[0], Height, xSize, ySize, "Corner Lower Right", "3") gcps.append(gcp) gcp = gdal.GCP(cornerPointLL[1], cornerPointLL[0], Height, 0, ySize, "Corner Lower Left", "4") gcps.append(gcp) gcp = gdal.GCP(frameCenterLon, frameCenterLat, Height, xSize / 2, ySize / 2, "Center", "5") gcps.append(gcp) geotransform_affine = gdal.GCPsToGeoTransform(gcps) src = np.float64( np.array([[0.0, 0.0], [xSize, 0.0], [xSize, ySize], [0.0, ySize]])) dst = np.float64( np.array([cornerPointUL, cornerPointUR, cornerPointLR, cornerPointLL])) geotransform = from_points(src, dst) if geotransform is None: qgsu.showUserAndLogMessage("", "Unable to extract a geotransform.", onlyLog=True) return
def test_gcps2gt_8(): gt = gdal.GCPsToGeoTransform(_list2gcps([ (0.01, 0.04, -87.05528672907, 39.22759504228), (0.01, 2688.02, -86.97079900719, 39.27075713986), (4031.99, 2688.04, -87.05960736744, 39.37569137000), (1988.16, 1540.80, -87.055069186699924, 39.304963106777514), (1477.41, 2400.83, -87.013419295885001, 39.304705030894979), (1466.02, 2376.92, -87.013906298363295, 39.304056190007913), ])) gt_expected = (-87.056612873288, -2.232795668658e-05, 3.178617809303e-05, 39.227856615716, 2.6091510188921e-05, 1.596921026218e-05) assert gdaltest.geotransform_equals(gt, gt_expected, 0.00001)
def gcps2gt_7(): gt = gdal.GCPsToGeoTransform(_list2gcps([ (400000, 370000, 400000, 370000), (410000, 368000, 410000, 368000), (410000, 370000, 410000, 370000), (400000, 368000, 400000, 368000), ])) if not gdaltest.geotransform_equals( gt, (0.0, 1.0, 0.0, 0.0, 0.0, 1.0), 0.000001): return 'fail' return 'success'
def SetGCPsToGeoTransform(cornerPointUL, cornerPointUR, cornerPointLR, cornerPointLL, frameCenterLon, frameCenterLat): ''' Make Geotranform from pixel to lon lat coordinates ''' gcps = [] global gcornerPointUL gcornerPointUL = cornerPointUL global gcornerPointUR gcornerPointUR = cornerPointUR global gcornerPointLR gcornerPointLR = cornerPointLR global gcornerPointLL gcornerPointLL = cornerPointLL global gframeCenterLat gframeCenterLat = frameCenterLat global gframeCenterLon gframeCenterLon = frameCenterLon Height = 0 gcp = gdal.GCP(cornerPointUL[1], cornerPointUL[0], Height, 0, 0, "Corner Upper Left", "1") gcps.append(gcp) gcp = gdal.GCP(cornerPointUR[1], cornerPointUR[0], Height, xSize, 0, "Corner Upper Right", "2") gcps.append(gcp) gcp = gdal.GCP(cornerPointLR[1], cornerPointLR[0], Height, xSize, ySize, "Corner Lower Right", "3") gcps.append(gcp) gcp = gdal.GCP(cornerPointLL[1], cornerPointLL[0], Height, 0, ySize, "Corner Lower Left", "4") gcps.append(gcp) gcp = gdal.GCP(frameCenterLon, frameCenterLat, Height, xSize / 2, ySize / 2, "Center", "5") gcps.append(gcp) global geotransform geotransform = gdal.GCPsToGeoTransform(gcps) if geotransform is None: qgsu.showUserAndLogMessage(QCoreApplication.translate( "QgsFmvUtils", 'Unable to extract a geotransform.'), onlyLog=True) return
def copy_and_transform(file_name, sds): format = "GTiff" print "Format: GTiff" driver = gdal.GetDriverByName(format) file_name += '.tif' print "File name: %s" % file_name driver = gdal.GetDriverByName(format) dst_ds = driver.CreateCopy(file_name, sds, 1) print "Status: Created" geotrans = gdal.GCPsToGeoTransform(sds.GetGCPs()) print "Geotrans: ", geotrans if geotrans: # geotrans = (20.776085394125101, 0.061360126841990, 0, 65.899963721633995, 0, -0.061360126841990) dst_ds.SetGeoTransform(geotrans) print "Status: Transformed"
def georef(input_file, reference_file, output_file, feature_name, flann, transform_type, gcp_output_shp, gcp_output_txt, tile, offset, ratio=0.75, convert=False): """Georeference the input using the training image and save the result in outputFile. A ratio can be given to select more or less matches (defaults to 0.75).""" detector, norm = init_feature(feature_name) train, kp_train, des_train = getImageKeyPointsAndDescriptors( reference_file, detector, tile, offset, convert) query, kp_query, des_query = getImageKeyPointsAndDescriptors( input_file, detector, tile, offset, convert) two_sides_matches = match(norm, flann, des_train, des_query, ratio) MIN_MATCH_COUNT = 3 affine = True if len(two_sides_matches) > MIN_MATCH_COUNT: src_pts = np.float32([ kp_train[m.queryIdx].pt for m in two_sides_matches ]).reshape(-1, 1, 2) dst_pts = np.float32([ kp_query[m.trainIdx].pt for m in two_sides_matches ]).reshape(-1, 1, 2) if affine: M, mask = cv.estimateAffine2D(src_pts, dst_pts) else: M, mask = cv.findHomography(src_pts, dst_pts, cv.RANSAC) matchesMask = mask.ravel().tolist() ds = gdal.Open(reference_file) x_offset, px_w, rot1, y_offset, px_h, rot2 = ds.GetGeoTransform() logging.debug("%s : Transform: %f, %f, %f, %f, %f, %f", datetime.datetime.now(), x_offset, px_w, rot1, y_offset, px_h, rot2) gcp_list = [] geo_t = ds.GetGeoTransform() # gcp_string = '' logging.debug("%s : %d matches", datetime.datetime.now(), len(matchesMask)) for i, good_match in enumerate(matchesMask): if good_match == 1: p1 = kp_train[two_sides_matches[i].queryIdx].pt p2 = kp_query[two_sides_matches[i].trainIdx].pt pp = gdal.ApplyGeoTransform(geo_t, p1[0], p1[1]) logging.debug(f"GCP geot = (%f,%f) -> (%f,%f)", p1[0], p1[1], pp[0], pp[1]) logging.debug(f"Matched with (%f,%f)", p2[0], p2[1]) z = 0 # info = "GCP from pixel %f, %f" % (p1[0], p1[1]) gcp = gdal.GCP(pp[0], pp[1], z, p2[0], p2[1]) # , info, i) # print ("GCP = (" + str(p2[0]) +","+ str(p2[1]) + ") -> (" + str(pp[0]) +","+ str(pp[1]) + ")") # gcp_string += ' -gcp '+" ".join([str(p2[0]),str(p2[1]),str(pp[0]), str(pp[1])]) gcp_list.append(gcp) logging.debug("%s : %d GCPs", datetime.datetime.now(), len(gcp_list)) translate_t = gdal.GCPsToGeoTransform(gcp_list) translate_inv_t = gdal.InvGeoTransform(translate_t) logging.debug(len(translate_t)) logging.debug("geotransform = %s", translate_t) logging.debug(len(translate_inv_t)) logging.debug("invgeotransform = %s", translate_inv_t) # trans_gcp_list = [] dst_gcp_list = [] mapResiduals = 0.0 geoResiduals = 0.0 for gcp in gcp_list: # Inverse geotransform to get the corresponding pixel pix = gdal.ApplyGeoTransform(translate_inv_t, gcp.GCPX, gcp.GCPY) logging.debug("GCP = (%d,%d) -> (%d,%d)", gcp.GCPPixel, gcp.GCPLine, gcp.GCPX, gcp.GCPY) logging.debug(" => (%d,%d)", pix[0], pix[1]) map_dX = gcp.GCPPixel - pix[0] map_dY = gcp.GCPLine - pix[1] map_residual = map_dX * map_dX + map_dY * map_dY mapResiduals = mapResiduals + map_residual # trans_gcp_list.append(pix) # Apply the transform to get the GCP location in the output SRS pp = gdal.ApplyGeoTransform(translate_t, gcp.GCPPixel, gcp.GCPLine) z = 0 out_gcp = gdal.GCP(pp[0], pp[1], z, gcp.GCPPixel, gcp.GCPLine) logging.debug("GCP = (%d,%d) -> (%d,%d)", out_gcp.GCPPixel, out_gcp.GCPLine, pp[0], pp[1]) # gcp_string += ' -gcp '+" ".join([str(p2[0]),str(p2[1]),str(pp[0]), str(pp[1])]) dX = gcp.GCPX - pp[0] dY = gcp.GCPY - pp[1] residual = dX * dX + dY * dY geoResiduals = geoResiduals + residual logging.debug("map residual = %f, %f = %f", map_dX, map_dY, map_residual) logging.debug("residual = %f, %f = %f", dX, dY, residual) dst_gcp_list.append(out_gcp) logging.debug(f"map residuals %s", mapResiduals) logging.debug(f"geo residuals %s", geoResiduals) # print (gcp_string) # h,w = train.shape # pts = np.float32([ [0,0],[0,h-1],[w-1,h-1],[w-1,0] ]).reshape(-1,1,2) # dst = cv.perspectiveTransform(pts,M) # img2 = cv.polylines(query,[np.int32(dst)],True,255,3, cv.LINE_AA) src_ds = gdal.Open(input_file) # translate and warp the inputFile using GCPs and polynomial of order 1 dst_ds = gdal.Translate('', src_ds, outputSRS=ds.GetProjection(), GCPs=gcp_list, format='MEM') tps = False if transform_type == 'poly1': polynomialOrder = 1 gdal.Warp(output_file, dst_ds, tps=tps, polynomialOrder=polynomialOrder, dstNodata=1) elif transform_type == 'poly2': polynomialOrder = 2 gdal.Warp(output_file, dst_ds, tps=tps, polynomialOrder=polynomialOrder, dstNodata=1) elif transform_type == 'poly3': polynomialOrder = 3 gdal.Warp(output_file, dst_ds, tps=tps, polynomialOrder=polynomialOrder, dstNodata=1) elif transform_type == 'tps': tps = True gdal.Warp(output_file, dst_ds, tps=tps, dstNodata=1) else: polynomialOrder = 1 gdal.Warp(output_file, dst_ds, tps=tps, polynomialOrder=polynomialOrder, dstNodata=1) if gcp_output_shp is not None: saveGCPsAsShapefile(dst_gcp_list, osr.SpatialReference(ds.GetProjection()), gcp_output_shp) saveGCPsAsText(dst_gcp_list, gcp_output_txt) draw_params = dict( matchColor=(0, 255, 0), # draw matches in green color singlePointColor=None, matchesMask=matchesMask, # draw only inliers flags=2) img3 = cv.drawMatches(train, kp_train, query, kp_query, two_sides_matches, None, **draw_params) return img3 else: logging.error("Not enough matches are found - %d/%d", len(two_sides_matches), MIN_MATCH_COUNT)
def __getmetadata__(self, f=None): '''Populate the metadata''' if not f: f = self.fileinfo['filepath'] self._gdaldataset = geometry.OpenDataset(f) led = glob.glob(os.path.dirname(f) + '/[Ll][Ee][Aa][Dd]*')[0] #volume file meta = open(led, 'rb').read() ''' metadata has 4 records, each is 4320 (LS) or 6120 (SPOT) bytes long: File descriptor record; Scene header record; Map projection (scene-related) ancillary record; Radiometric transformation ancillary record. ''' #Record 2 - Scene header record record = 2 recordlength = 4320 #LS 5 satellite = utilities.readbinary(meta, (record - 1) * recordlength, 309, 324) #Scene ID, path/row & image date/time start, stop = 37, 52 sceneid = utilities.readbinary(meta, (record - 1) * recordlength, start, stop) start, stop = 165, 180 pathrow = utilities.readbinary(meta, (record - 1) * recordlength, start, stop)[1:] start, stop = 117, 148 imgdate = utilities.readbinary(meta, (record - 1) * recordlength, start, stop) self.metadata['imgdate'] = time.strftime( utilities.datetimeformat, time.strptime(imgdate[0:14], '%Y%m%d%H%M%S')) #ISO 8601 #Ascending/descending flag start, stop = 357, 372 if utilities.readbinary(meta, (record - 1) * recordlength, start, stop) == 'D': self.metadata['orbit'] = 'Descending' else: self.metadata['orbit'] = 'Ascending' #Processing level start, stop = 1573, 1588 self.metadata['level'] = utilities.readbinary( meta, (record - 1) * recordlength, start, stop) #Bands start, stop = 1653, 1659 bands = [] actbands = utilities.readbinary(meta, (record - 1) * recordlength, start, stop) for i in range(0, 7): #Loop thru the 7 LS 5 bands if actbands[i] == '1': bands.append(str(i + 1)) self._gdaldataset.GetRasterBand(i + 1).SetNoDataValue(0) #Record 3 - Map projection (scene-related) ancillary record record = 3 #Bands, rows & columns and rotation nbands = int(self._gdaldataset.RasterCount) start, stop = 333, 348 ncols = float( utilities.readbinary(meta, (record - 1) * recordlength, start, stop)) start, stop = 349, 364 nrows = float( utilities.readbinary(meta, (record - 1) * recordlength, start, stop)) start, stop = 445, 460 self.metadata['rotation'] = float( utilities.readbinary(meta, (record - 1) * recordlength, start, stop)) if abs(self.metadata['rotation']) < 1: self.metadata['orientation'] = 'Map oriented' self.metadata['rotation'] = 0.0 else: self.metadata['orientation'] = 'Path oriented' #Sun elevation and azimuth start, stop = 605, 620 self.metadata['sunelevation'] = float( utilities.readbinary(meta, (record - 1) * recordlength, start, stop)) start, stop = 621, 636 self.metadata['sunazimuth'] = float( utilities.readbinary(meta, (record - 1) * recordlength, start, stop)) #geometry.CellSizes start, stop = 365, 396 (cellx, celly) = map( float, utilities.readbinary(meta, (record - 1) * recordlength, start, stop).split()) start, stop = 397, 412 projection = utilities.readbinary(meta, (record - 1) * recordlength, start, stop).split() datum = projection[0] zone = projection[1] # lat/lons start, stop = 765, 892 coords = utilities.readbinary(meta, (record - 1) * recordlength, start, stop).split() uly, ulx, ury, urx, lry, lrx, lly, llx = map(float, coords) ext = [[ulx, uly], [urx, ury], [lrx, lry], [llx, lly], [ulx, uly]] if int(zone) != 0: # UTM type = 'UTM' units = 'm' #start,stop = 637,764 #coords = utilities.readbinary(meta,(record-1)*recordlength,start,stop).split() #uly,ulx,ury,urx,lry,lrx,lly,llx = map(float, coords) #ext=[[ulx,uly],[urx,ury],[lrx,lry],[llx,lly],[ulx,uly]] if datum == 'GDA94': epsg = int('283' + zone) elif datum == 'AGD66': epsg = int('202' + zone) elif datum == 'WGS84': epsg = int('327' + zone) else: #Assume type = 'GEO' units = 'deg' if datum == 'GDA94': epsg = 4283 else: epsg = 4326 #Assume WGS84 gcps = [] i = 0 lr = [[0, 0], [ncols, 0], [ncols, nrows], [0, nrows]] while i < len(ext) - 1: #don't need the last xy pair gcp = gdal.GCP() gcp.GCPPixel, gcp.GCPLine = lr[i] gcp.GCPX, gcp.GCPY = ext[i] gcp.Id = str(i) gcps.append(gcp) i += 1 geotransform = gdal.GCPsToGeoTransform(gcps) cellx, celly = geometry.CellSize(geotransform) rotation = geometry.Rotation(geotransform) srs = osr.SpatialReference() srs.ImportFromEPSG(epsg) srs = srs.ExportToWkt() self.metadata['satellite'] = satellite if satellite == 'LANDSAT-5': self.metadata['sensor'] = 'TM' self.metadata['filetype'] = 'CEOS/Landsat CCRS Format' else: self.metadata['sensor'] = 'HRV' self.metadata['filetype'] = 'CEOS/SPOT CCRS Format' self.metadata['filesize'] = sum( [os.path.getsize(file) for file in self.filelist]) self.metadata['srs'] = srs self.metadata['epsg'] = epsg self.metadata['units'] = units self.metadata['cols'] = ncols self.metadata['rows'] = nrows self.metadata['nbands'] = nbands self.metadata['bands'] = ','.join(bands) self.metadata['nbits'] = 8 self.metadata['datatype'] = 'Byte' self.metadata['nodata'] = 0 self.metadata['cellx'], self.metadata['celly'] = map( float, [cellx, celly]) self.metadata['UL'] = '%s,%s' % tuple(ext[0]) self.metadata['UR'] = '%s,%s' % tuple(ext[1]) self.metadata['LR'] = '%s,%s' % tuple(ext[2]) self.metadata['LL'] = '%s,%s' % tuple(ext[3]) metadata = self._gdaldataset.GetMetadata() self.metadata['metadata'] = '\n'.join( ['%s: %s' % (m, hdf_self.metadata[m]) for m in metadata]) self.metadata['compressionratio'] = 0 self.metadata['compressiontype'] = 'None' self.extent = ext
def __getmetadata__(self, f=None): '''Read Metadata for ASTER HDF images as GDAL doesn't.''' if not f: f = self.fileinfo['filepath'] hdf_sd = self._gdaldataset.GetSubDatasets() hdf_sd = [sd for sd, sz in hdf_sd if 'ImageData' in sd] hdf_md = self._hdf_md #sd,sz = hdf_sd[0] sd = hdf_sd[0] sd = geometry.OpenDataset(sd) nbands = len(hdf_sd) ncols = [] nrows = [] nbits = [] bands = [] datatypes = [] cellxy = [] for i in range(0, len(hdf_md['PROCESSEDBANDS']), 2): band = hdf_md['PROCESSEDBANDS'][i:i + 2] if i / 2 + 1 <= 4: bands.append('VNIR' + band) cellxy.append('15') elif i / 2 + 1 <= 10: bands.append('SWIR' + band) cellxy.append('30') else: bands.append('TIR' + band) cellxy.append('90') if band.isdigit(): band = str(int(band)) #Get rid of leading zero cols, rows, bytes = map( int, hdf_md['IMAGEDATAINFORMATION%s' % band].split(',')) if bytes == 1: datatypes.append('Byte') elif bytes == 2: datatypes.append('UInt16') ncols.append(str(cols)) nrows.append(str(rows)) nbits.append(str(bytes * 8)) ncols = ','.join(ncols) nrows = ','.join(nrows) nbits = ','.join(nbits) bands = ','.join(bands) datatypes = ','.join(datatypes) cellxy = ','.join(cellxy) uly, ulx = [float(xy) for xy in hdf_md['UPPERLEFT'].split(',')] ury, urx = [float(xy) for xy in hdf_md['UPPERRIGHT'].split(',')] lry, lrx = [float(xy) for xy in hdf_md['LOWERRIGHT'].split(',')] lly, llx = [float(xy) for xy in hdf_md['LOWERLEFT'].split(',')] ext = [[ulx, uly], [urx, ury], [lrx, lry], [llx, lly], [ulx, uly]] #SRS reported by GDAL is slightly dodgy, GDA94 is not recognised and doesn't set the North/South properly #Get it anyway so we can work out if it's GDA94 based on the spheroid srs = sd.GetGCPProjection() src_srs = osr.SpatialReference(srs) tgt_srs = osr.SpatialReference() geogcs = osr.SpatialReference() if src_srs.GetAttrValue('SPHEROID') == 'GRS 1980': geogcs.ImportFromEPSG(4283) #Assume 'GDA94' else: geogcs.ImportFromEPSG(4326) #Assume 'WGS84' tgt_srs.CopyGeogCSFrom(geogcs) if hdf_md['PROCESSINGLEVELID'].upper() == '1A': units = 'deg' else: #projparams=map(float, hdf_md['PROJECTIONPARAMETERS1'].split(',')) if hdf_md['MPMETHOD1'] == 'UTM': #Universal Transverse Mercator if uly < 0: bNorth = False #GDAL doesn't set the North/South properly else: bNorth = True nZone = int(hdf_md['UTMZONECODE1']) tgt_srs.SetUTM(nZone, bNorth) units = 'm' #Other projections not (yet?) implemented... #elif hdf_md['MPMETHOD1'] == 'PS':#Polar Stereographic # #dfCenterLon = ? GTCP projection params don't list cenlon/lat for PS # dfCenterLat = ? # dfScale = ? # tgt_srs.SetPS(dfCenterLat,dfCenterLon,dfScale,0.0,0.0) #elif hdf_md['MPMETHOD1'] == 'LAMCC':#Lambert Conformal Conic # dfCenterLon = ? # dfCenterLat = ? # dfStdP1 = ? # dfStdP2 = ? # tgt_srs.SetLCC(dfStdP1,dfStdP2,dfCenterLat,dfCenterLon,0,0) #elif hdf_md['MPMETHOD1'] == 'SOM':#Space Oblique Mercator # dfCenterLon = ? # dfCenterLat = ? # srs.SetMercator(dfCenterLat,dfCenterLon,0,0,0) #elif hdf_md['MPMETHOD1'] == 'EQRECT':#Equi-Rectangular # dfCenterLon = ? # dfCenterLat = ? # tgt_srs.SetMercator(dfCenterLat,dfCenterLon,0,0,0) else: #Assume Geog units = 'deg' srs = tgt_srs.ExportToWkt() self.metadata['UL'] = '%s,%s' % tuple(ext[0]) self.metadata['UR'] = '%s,%s' % tuple(ext[1]) self.metadata['LR'] = '%s,%s' % tuple(ext[2]) self.metadata['LL'] = '%s,%s' % tuple(ext[3]) self.metadata['metadata'] = '\n'.join( ['%s: %s' % (m, hdf_md[m]) for m in hdf_md]) self.metadata['satellite'] = 'Terra' self.metadata['sensor'] = 'ASTER' self.metadata['filetype'] = self._gdaldataset.GetDriver( ).ShortName + '/' + self._gdaldataset.GetDriver().LongName + ' (ASTER)' self.metadata['sceneid'] = hdf_md['ASTERSCENEID'] self.metadata['level'] = hdf_md['PROCESSINGLEVELID'] if '-' in hdf_md['CALENDARDATE']: imgdate = hdf_md['CALENDARDATE'] else: imgdate = time.strftime(utilities.dateformat, time.strptime(hdf_md['CALENDARDATE'], '%Y%m%d')) #ISO 8601 imgtime = hdf_md.get('TIMEOFDAY') if imgtime: self.metadata['imgdate'] = time.strftime( utilities.datetimeformat, time.strptime(imgdate + imgtime[0:6], '%Y-%m-%d%H%M%S')) #ISO 8601 else: self.metadata['imgdate'] = imgdate #self.metadata['imgdate'] = hdf_md['CALENDARDATE'] self.metadata['cloudcover'] = float(hdf_md['SCENECLOUDCOVERAGE']) if hdf_md['FLYINGDIRECTION'] == 'DE': self.metadata['orbit'] = 'Descending' else: self.metadata['orbit'] = 'Ascending' self.metadata['rotation'] = float( hdf_md.get('MAPORIENTATIONANGLE', hdf_md.get('SCENEORIENTATIONANGLE'))) if abs(self.metadata['rotation']) < 1.0: self.metadata['orientation'] = 'Map oriented' else: self.metadata['orientation'] = 'Path oriented' self.metadata['sunazimuth'], self.metadata['sunelevation'] = map( float, hdf_md['SOLARDIRECTION'].split(',')) self.metadata['viewangle'] = float(hdf_md['POINTINGANGLE']) self.metadata['cols'] = ncols self.metadata['rows'] = nrows self.metadata['nbands'] = nbands self.metadata['datatype'] = datatypes self.metadata['nbits'] = nbits self.metadata['nodata'] = ','.join(['0' for i in range(0, nbands)]) self.metadata['bands'] = bands self.metadata['resampling'] = hdf_md.get( 'RESMETHOD1') #Assume same for all... self.metadata['srs'] = srs self.metadata['epsg'] = spatialreferences.IdentifyAusEPSG(srs) self.metadata['units'] = units self.metadata['cellx'], self.metadata['celly'] = cellxy, cellxy #Geotransform ext = [[ulx, uly], [urx, ury], [lrx, lry], [llx, lly], [ulx, uly]] ncols = map(int, str(ncols).split(',')) nrows = map(int, str(nrows).split(',')) cellx, celly = [], [] j = 0 while j < len(ncols): gcps = [] i = 0 lr = [[0, 0], [ncols[j], 0], [ncols[j], nrows[j]], [0, nrows[j]]] while i < len(ext) - 1: #don't need the last xy pair gcp = gdal.GCP() gcp.GCPPixel, gcp.GCPLine = lr[i] gcp.GCPX, gcp.GCPY = ext[i] gcp.Id = str(i) gcps.append(gcp) i += 1 j += 1 geotransform = gdal.GCPsToGeoTransform(gcps) x, y = geometry.CellSize(geotransform) cellx.append(str(x)) celly.append(str(abs(y))) self.metadata['cellx'] = ','.join(cellx) self.metadata['celly'] = ','.join(celly) srs = osr.SpatialReference() srs.ImportFromEPSG(4326) self.metadata['srs'] = srs.ExportToWkt() self.metadata['UL'] = '%s,%s' % tuple(ext[0]) self.metadata['UR'] = '%s,%s' % tuple(ext[1]) self.metadata['LR'] = '%s,%s' % tuple(ext[2]) self.metadata['LL'] = '%s,%s' % tuple(ext[3]) self.metadata['metadata'] = '\n'.join( ['%s: %s' % (m, hdf_md[m]) for m in hdf_md]) self.metadata['filesize'] = sum( [os.path.getsize(file) for file in self.filelist]) self.metadata['compressionratio'] = 0 self.metadata['compressiontype'] = 'None' self.extent = ext #Build gdaldataset object for overviews vrtcols = ncols[0] vrtrows = nrows[0] #vrtbands=[sd for sd,sn in hdf_sd[0:4]]#The 4 VNIR bands vrtbands = hdf_sd[0:4] #The 4 VNIR bands vrt = geometry.CreateSimpleVRT(vrtbands, vrtcols, vrtrows, datatypes.split(',')[0]) self._gdaldataset = geometry.OpenDataset(vrt) for i in range(1, 5): self._gdaldataset.GetRasterBand(i).SetNoDataValue(0)
def test_gcps2gt_4(): gt = gdal.GCPsToGeoTransform(_list2gcps([ (0.0, 0.0, 400000, 370000), ])) assert gt is None, 'Expected failure for single GCP.'
def getGCP(reference_file, kp_query, kp_train, two_sides_matches, min_matches=3): if len(two_sides_matches) > min_matches: src_pts = np.float32([ kp_train[m.queryIdx].pt for m in two_sides_matches ]).reshape(-1, 1, 2) dst_pts = np.float32([ kp_query[m.trainIdx].pt for m in two_sides_matches ]).reshape(-1, 1, 2) M, mask = cv.findHomography(src_pts, dst_pts, cv.RANSAC) matchesMask = mask.ravel().tolist() ds = gdal.Open(reference_file) x_offset, px_w, rot1, y_offset, px_h, rot2 = ds.GetGeoTransform() logging.debug("%s : Transform: %f, %f, %f, %f, %f, %f", datetime.datetime.now(), x_offset, px_w, rot1, y_offset, px_h, rot2) gcp_list = [] geo_t = ds.GetGeoTransform() # gcp_string = '' logging.debug("%s : %d matches", datetime.datetime.now(), len(matchesMask)) for i, good_match in enumerate(matchesMask): if good_match == 1: p1 = kp_train[two_sides_matches[i].queryIdx].pt p2 = kp_query[two_sides_matches[i].trainIdx].pt pp = gdal.ApplyGeoTransform(geo_t, p1[0], p1[1]) logging.debug(f"GCP geot = (%f,%f) -> (%f,%f)", p1[0], p1[1], pp[0], pp[1]) logging.debug(f"Matched with (%f,%f)", p2[0], p2[1]) z = 0 # info = "GCP from pixel %f, %f" % (p1[0], p1[1]) gcp = gdal.GCP(pp[0], pp[1], z, p2[0], p2[1]) # , info, i) # print ("GCP = (" + str(p2[0]) +","+ str(p2[1]) + ") -> (" + str(pp[0]) +","+ str(pp[1]) + ")") # gcp_string += ' -gcp '+" ".join([str(p2[0]),str(p2[1]),str(pp[0]), str(pp[1])]) gcp_list.append(gcp) logging.debug("%s : %d GCPs", datetime.datetime.now(), len(gcp_list)) translate_t = gdal.GCPsToGeoTransform(gcp_list) translate_inv_t = gdal.InvGeoTransform(translate_t) logging.debug(len(translate_t)) logging.debug("geotransform = %s", translate_t) logging.debug(len(translate_inv_t)) logging.debug("invgeotransform = %s", translate_inv_t) # trans_gcp_list = [] dst_gcp_list = [] mapResiduals = 0.0 geo_residuals = 0.0 for gcp in gcp_list: # Inverse geotransform to get the corresponding pixel pix = gdal.ApplyGeoTransform(translate_inv_t, gcp.GCPX, gcp.GCPY) logging.debug("GCP = (%d,%d) -> (%d,%d)", gcp.GCPPixel, gcp.GCPLine, gcp.GCPX, gcp.GCPY) logging.debug(" => (%d,%d)", pix[0], pix[1]) map_dX = gcp.GCPPixel - pix[0] map_dY = gcp.GCPLine - pix[1] map_residual = map_dX * map_dX + map_dY * map_dY mapResiduals = mapResiduals + map_residual # Apply the transform to get the GCP location in the output SRS pp = gdal.ApplyGeoTransform(translate_t, gcp.GCPPixel, gcp.GCPLine) z = 0 out_gcp = gdal.GCP(pp[0], pp[1], z, gcp.GCPPixel, gcp.GCPLine) logging.debug("GCP = (%d,%d) -> (%d,%d)", out_gcp.GCPPixel, out_gcp.GCPLine, pp[0], pp[1]) dX = gcp.GCPX - pp[0] dY = gcp.GCPY - pp[1] residual = dX * dX + dY * dY geo_residuals = geo_residuals + residual logging.debug("map residual = %f, %f = %f", map_dX, map_dY, map_residual) logging.debug("residual = %f, %f = %f", dX, dY, residual) dst_gcp_list.append(out_gcp) logging.debug(f"map residuals %s", mapResiduals) logging.debug(f"geo residuals %s", geo_residuals) return ds.GetProjection(), gcp_list, dst_gcp_list else: logging.error("Not enough matches are found - %d/%d", len(two_sides_matches), min_matches) return None, None, None
from osgeo import gdal if len(sys.argv) < 2: print("Usage: gcps2wld.py source_file") sys.exit(1) filename = sys.argv[1] dataset = gdal.Open(filename) if dataset is None: print('Unable to open %s' % filename) sys.exit(1) gcps = dataset.GetGCPs() if gcps is None or not gcps: print('No GCPs found on file ' + filename) sys.exit(1) geotransform = gdal.GCPsToGeoTransform(gcps) if geotransform is None: print('Unable to extract a geotransform.') sys.exit(1) print(geotransform[1]) print(geotransform[4]) print(geotransform[2]) print(geotransform[5]) print(geotransform[0] + 0.5 * geotransform[1] + 0.5 * geotransform[2]) print(geotransform[3] + 0.5 * geotransform[4] + 0.5 * geotransform[5])
def modify_src_raster(self): 'convert to RGB(A) if required' #---------------------------- override_srs = self.options.srs src_bands = self.src_ds.RasterCount band1 = self.src_ds.GetRasterBand(1) if src_bands == 1 and band1.GetColorInterpretation( ) == GCI_PaletteIndex: # source is a paletted raster transparency = None if self.base_resampling == 'NearestNeighbour' and self.resampling == Image.NEAREST: # check if src can be rendered in paletted mode color_table = band1.GetColorTable() ncolors = color_table.GetCount() palette = [ color_table.GetColorEntry(i) for i in range(ncolors) ] r, g, b, a = zip(*palette) pil_palette = flatten(zip( r, g, b)) # PIL doesn't support RGBA palettes if self.options.dst_nodata is not None: transparency = int(self.options.dst_nodata.split(',')[0]) elif min(a) == 0: transparency = a.index(0) elif ncolors < 256: pil_palette += [0, 0, 0 ] # the last color index is a transparency transparency = len(pil_palette) / 3 - 1 ld('transparency', transparency) if transparency is not None: # render in paletted mode self.transparency = transparency self.palette = pil_palette ld('self.palette', self.palette) else: # convert src to rgb VRT src_geotr = self.src_ds.GetGeoTransform() src_proj = txt2proj4(self.src_ds.GetProjection()) gcps = self.src_ds.GetGCPs() if gcps: ld('src GCPsToGeoTransform', gdal.GCPsToGeoTransform(gcps)) if not src_proj and gcps: src_proj = txt2proj4(self.src_ds.GetGCPProjection()) if override_srs is not None: src_proj = txt2proj4(override_srs) override_srs = None ld('src_proj', src_proj, 'src geotr', src_geotr) assert src_proj, 'The source does not have a spatial reference system assigned' if not src_geotr or src_geotr == (0.0, 1.0, 0.0, 0.0, 0.0, 1.0): geotr_txt = '' else: geotr_txt = geotr_templ % src_geotr gcplst_txt = '' if gcps: gcp_lst = '\n'.join( (gcp_templ % (g.Id, g.GCPPixel, g.GCPLine, g.GCPX, g.GCPY, g.GCPZ) for g in gcps)) gcp_proj = txt2proj4(self.src_ds.GetGCPProjection( )) if override_srs is None else src_proj gcplst_txt = gcplst_templ % (gcp_proj, gcp_lst) metadata = self.src_ds.GetMetadata() ld('metadata', metadata) if metadata: mtd_lst = [ xml_txt('MDI', metadata[mdkey], 4, key=mdkey) for mdkey in metadata ] meta_txt = meta_templ % '\n'.join(mtd_lst) else: meta_txt = '' xsize, ysize = (self.src_ds.RasterXSize, self.src_ds.RasterYSize) blxsize, blysize = band1.GetBlockSize() band_lst = ''.join( (band_templ % { 'band': band, 'color': color, 'src': cgi.escape(self.src_path, quote=True), 'srcband': 1, 'xsize': xsize, 'ysize': ysize, 'blxsize': blxsize, 'blysize': blysize, } for band, color in ((1, 'Red'), (2, 'Green'), (3, 'Blue')))) vrt_txt = vrt_templ % { 'xsize': xsize, 'ysize': ysize, 'metadata': meta_txt, 'srs': (srs_templ % src_proj) if src_proj else '', 'geotr': geotr_txt, 'gcp_list': gcplst_txt, 'band_list': band_lst, } src_vrt = os.path.abspath( os.path.join(self.dest, self.base + '.src.vrt')) # auxilary VRT file self.temp_files.append(src_vrt) self.src_path = src_vrt with open(src_vrt, 'w') as f: f.write(vrt_txt.encode('utf-8')) self.src_ds = gdal.Open(src_vrt, GA_ReadOnly) # finished with a paletted raster if override_srs is not None: # src SRS needs to be relpaced src_vrt = os.path.join(self.dest, self.base + '.src.vrt') # auxilary VRT file self.temp_files.append(src_vrt) self.src_path = src_vrt vrt_drv = gdal.GetDriverByName('VRT') self.src_ds = vrt_drv.CreateCopy(src_vrt, src_ds) # replace src dataset ld('override_srs', override_srs, 'txt2wkt(override_srs)', txt2wkt(override_srs)) self.src_ds.SetProjection( txt2wkt(override_srs)) # replace source SRS gcps = self.src_ds.GetGCPs() if gcps: self.src_ds.SetGCPs(gcps, txt2wkt(override_srs))