projection_information = metadata_api.projection_information(projection="UTM", datum="WGS84", units="meters") corner_point = metadata_api.corner_point(location="UL", x="423000.000000", y="5207700.000000") projection_information.add_corner_point(corner_point) corner_point = metadata_api.corner_point(location="LR", x="661500.000000", y="4988100.000000") projection_information.add_corner_point(corner_point) projection_information.set_grid_origin('CENTER') utm_proj_params = metadata_api.utm_proj_params() utm_proj_params.set_zone_code(10) projection_information.set_utm_proj_params(utm_proj_params) del projection_information.utm_proj_params projection_information.utm_proj_params = None global_metadata.set_projection_information(projection_information) # --- global_metadata.set_orientation_angle(0) # Add the global metadata to the top-level object xml.set_global_metadata(global_metadata) # Create bands object bands = metadata_api.bandsType()
def update_espa_xml(parms, xml, xml_filename): logger = EspaLogging.get_logger(settings.PROCESSING_LOGGER) try: # Default the datum to WGS84 datum = settings.WGS84 if parms['datum'] is not None: datum = parms['datum'] bands = xml.get_bands() for band in bands.band: img_filename = band.get_file_name() logger.info("Updating XML for %s" % img_filename) ds = gdal.Open(img_filename) if ds is None: msg = "GDAL failed to open (%s)" % img_filename raise RuntimeError(msg) try: ds_band = ds.GetRasterBand(1) ds_transform = ds.GetGeoTransform() ds_srs = osr.SpatialReference() ds_srs.ImportFromWkt(ds.GetProjection()) except Exception as excep: raise ee.ESPAException(ee.ErrorCodes.warping, str(excep)), None, sys.exc_info()[2] projection_name = ds_srs.GetAttrValue('PROJECTION') number_of_lines = float(ds_band.YSize) number_of_samples = float(ds_band.XSize) # Need to abs these because they are coming from the transform, # which may becorrect for the transform, # but not how us humans understand it x_pixel_size = abs(ds_transform[1]) y_pixel_size = abs(ds_transform[5]) del ds_band del ds # Update the band information in the XML file band.set_nlines(number_of_lines) band.set_nsamps(number_of_samples) band_pixel_size = band.get_pixel_size() band_pixel_size.set_x(x_pixel_size) band_pixel_size.set_y(y_pixel_size) # For sanity report the resample method applied to the data resample_method = band.get_resample_method() logger.info("RESAMPLE METHOD [%s]" % resample_method) # We only support one unit type for each projection if projection_name is not None: if projection_name.lower().startswith('transverse_mercator'): band_pixel_size.set_units('meters') elif projection_name.lower().startswith('polar'): band_pixel_size.set_units('meters') elif projection_name.lower().startswith('albers'): band_pixel_size.set_units('meters') elif projection_name.lower().startswith('sinusoidal'): band_pixel_size.set_units('meters') else: # Must be Geographic Projection band_pixel_size.set_units('degrees') ###################################################################### # Fix the projection information for the warped data ###################################################################### gm = xml.get_global_metadata() # If the image extents were changed, then the scene center time is # meaningless so just remove it # We don't have any way to calculate a new one if parms['image_extents']: del gm.scene_center_time gm.scene_center_time = None # Remove the projection parameter object from the structure so that it # can be replaced with the new one # Geographic doesn't have one if gm.projection_information.utm_proj_params is not None: del gm.projection_information.utm_proj_params gm.projection_information.utm_proj_params = None if gm.projection_information.ps_proj_params is not None: del gm.projection_information.ps_proj_params gm.projection_information.ps_proj_params = None if gm.projection_information.albers_proj_params is not None: del gm.projection_information.albers_proj_params gm.projection_information.albers_proj_params = None if gm.projection_information.sin_proj_params is not None: del gm.projection_information.sin_proj_params gm.projection_information.sin_proj_params = None # Rebuild the projection parameters projection_name = ds_srs.GetAttrValue('PROJECTION') if projection_name is not None: # ---------------------------------------------------------------- if projection_name.lower().startswith('transverse_mercator'): logger.info("---- Updating UTM Parameters") # Get the parameter values zone = int(ds_srs.GetUTMZone()) # Get a new UTM projection parameter object and populate it utm_projection = metadata_api.utm_proj_params() utm_projection.set_zone_code(zone) # Add the object to the projection information gm.projection_information.set_utm_proj_params(utm_projection) # Update the attribute values gm.projection_information.set_projection("UTM") gm.projection_information.set_datum(settings.WGS84) # ---------------------------------------------------------------- elif projection_name.lower().startswith('polar'): logger.info("---- Updating Polar Stereographic Parameters") # Get the parameter values latitude_true_scale = ds_srs.GetProjParm('latitude_of_origin') longitude_pole = ds_srs.GetProjParm('central_meridian') false_easting = ds_srs.GetProjParm('false_easting') false_northing = ds_srs.GetProjParm('false_northing') # Get a new PS projection parameter object and populate it ps_projection = metadata_api.ps_proj_params() ps_projection.set_latitude_true_scale(latitude_true_scale) ps_projection.set_longitude_pole(longitude_pole) ps_projection.set_false_easting(false_easting) ps_projection.set_false_northing(false_northing) # Add the object to the projection information gm.projection_information.set_ps_proj_params(ps_projection) # Update the attribute values gm.projection_information.set_projection("PS") gm.projection_information.set_datum(settings.WGS84) # ---------------------------------------------------------------- elif projection_name.lower().startswith('albers'): logger.info("---- Updating Albers Equal Area Parameters") # Get the parameter values standard_parallel1 = ds_srs.GetProjParm('standard_parallel_1') standard_parallel2 = ds_srs.GetProjParm('standard_parallel_2') origin_latitude = ds_srs.GetProjParm('latitude_of_center') central_meridian = ds_srs.GetProjParm('longitude_of_center') false_easting = ds_srs.GetProjParm('false_easting') false_northing = ds_srs.GetProjParm('false_northing') # Get a new ALBERS projection parameter object and populate it albers_projection = metadata_api.albers_proj_params() albers_projection.set_standard_parallel1(standard_parallel1) albers_projection.set_standard_parallel2(standard_parallel2) albers_projection.set_origin_latitude(origin_latitude) albers_projection.set_central_meridian(central_meridian) albers_projection.set_false_easting(false_easting) albers_projection.set_false_northing(false_northing) # Add the object to the projection information gm.projection_information. \ set_albers_proj_params(albers_projection) # Update the attribute values gm.projection_information.set_projection("ALBERS") # This projection can have different datums, so use the datum # requested by the user gm.projection_information.set_datum(datum) # ---------------------------------------------------------------- elif projection_name.lower().startswith('sinusoidal'): logger.info("---- Updating Sinusoidal Parameters") # Get the parameter values central_meridian = ds_srs.GetProjParm('longitude_of_center') false_easting = ds_srs.GetProjParm('false_easting') false_northing = ds_srs.GetProjParm('false_northing') # Get a new SIN projection parameter object and populate it sin_projection = metadata_api.sin_proj_params() sin_projection.set_sphere_radius( settings.SINUSOIDAL_SPHERE_RADIUS) sin_projection.set_central_meridian(central_meridian) sin_projection.set_false_easting(false_easting) sin_projection.set_false_northing(false_northing) # Add the object to the projection information gm.projection_information.set_sin_proj_params(sin_projection) # Update the attribute values gm.projection_information.set_projection("SIN") # This projection doesn't have a datum del gm.projection_information.datum gm.projection_information.datum = None else: # ---------------------------------------------------------------- # Must be Geographic Projection logger.info("---- Updating Geographic Parameters") gm.projection_information.set_projection('GEO') gm.projection_information.set_datum(settings.WGS84) # WGS84 only gm.projection_information.set_units('degrees') # always degrees # Fix the UL and LR center of pixel map coordinates (map_ul_x, map_ul_y) = convert_imageXY_to_mapXY(0.5, 0.5, ds_transform) (map_lr_x, map_lr_y) = convert_imageXY_to_mapXY( number_of_samples - 0.5, number_of_lines - 0.5, ds_transform) for cp in gm.projection_information.corner_point: if cp.location == 'UL': cp.set_x(map_ul_x) cp.set_y(map_ul_y) if cp.location == 'LR': cp.set_x(map_lr_x) cp.set_y(map_lr_y) # Fix the UL and LR center of pixel latitude and longitude coordinates srs_lat_lon = ds_srs.CloneGeogCS() coord_tf = osr.CoordinateTransformation(ds_srs, srs_lat_lon) for corner in gm.corner: if corner.location == 'UL': (lon, lat, height) = \ coord_tf.TransformPoint(map_ul_x, map_ul_y) corner.set_longitude(lon) corner.set_latitude(lat) if corner.location == 'LR': (lon, lat, height) = \ coord_tf.TransformPoint(map_lr_x, map_lr_y) corner.set_longitude(lon) corner.set_latitude(lat) # Determine the bounding coordinates # Initialize using the UL and LR, then walk the edges of the image, # because some projections may not have the values in the corners of # the image # UL (map_x, map_y) = convert_imageXY_to_mapXY(0.0, 0.0, ds_transform) (ul_lon, ul_lat, height) = coord_tf.TransformPoint(map_x, map_y) # LR (map_x, map_y) = convert_imageXY_to_mapXY(number_of_samples, number_of_lines, ds_transform) (lr_lon, lr_lat, height) = coord_tf.TransformPoint(map_x, map_y) # Set the initial values west_lon = min(ul_lon, lr_lon) east_lon = max(ul_lon, lr_lon) north_lat = max(ul_lat, lr_lat) south_lat = min(ul_lat, lr_lat) # Walk across the top and bottom of the image for sample in range(0, int(number_of_samples)+1): (map_x, map_y) = \ convert_imageXY_to_mapXY(sample, 0.0, ds_transform) (top_lon, top_lat, height) = coord_tf.TransformPoint(map_x, map_y) (map_x, map_y) = \ convert_imageXY_to_mapXY(sample, number_of_lines, ds_transform) (bottom_lon, bottom_lat, height) = \ coord_tf.TransformPoint(map_x, map_y) west_lon = min(top_lon, bottom_lon, west_lon) east_lon = max(top_lon, bottom_lon, east_lon) north_lat = max(top_lat, bottom_lat, north_lat) south_lat = min(top_lat, bottom_lat, south_lat) # Walk down the left and right of the image for line in range(0, int(number_of_lines)+1): (map_x, map_y) = \ convert_imageXY_to_mapXY(0.0, line, ds_transform) (left_lon, left_lat, height) = \ coord_tf.TransformPoint(map_x, map_y) (map_x, map_y) = \ convert_imageXY_to_mapXY(number_of_samples, line, ds_transform) (right_lon, right_lat, height) = \ coord_tf.TransformPoint(map_x, map_y) west_lon = min(left_lon, right_lon, west_lon) east_lon = max(left_lon, right_lon, east_lon) north_lat = max(left_lat, right_lat, north_lat) south_lat = min(left_lat, right_lat, south_lat) # Update the bounding coordinates in the XML bounding_coords = gm.get_bounding_coordinates() bounding_coords.set_west(west_lon) bounding_coords.set_east(east_lon) bounding_coords.set_north(north_lat) bounding_coords.set_south(south_lat) del ds_transform del ds_srs # Write out a new XML file after validation logger.info("---- Validating XML Modifications and" " Creating Temp Output File") tmp_xml_filename = 'tmp-%s' % xml_filename with open(tmp_xml_filename, 'w') as tmp_fd: # Call the export with validation metadata_api.export(tmp_fd, xml) # Remove the original if os.path.exists(xml_filename): os.unlink(xml_filename) # Rename the temp file back to the original name os.rename(tmp_xml_filename, xml_filename) except Exception as excep: raise ee.ESPAException(ee.ErrorCodes.warping, str(excep)), None, sys.exc_info()[2]
bounding_coordinates.set_north (47.022955) bounding_coordinates.set_south (45.027814) global_metadata.set_bounding_coordinates (bounding_coordinates) # --- #projection_information = metadata_api.projection_information (projection="UTM", datum="WGS84", units="meters") projection_information = metadata_api.projection_information (projection="UTM", datum="WGS84", units="meters") corner_point = metadata_api.corner_point(location="UL", x="423000.000000", y="5207700.000000") projection_information.add_corner_point (corner_point) corner_point = metadata_api.corner_point(location="LR", x="661500.000000", y="4988100.000000") projection_information.add_corner_point (corner_point) projection_information.set_grid_origin ('CENTER') utm_proj_params = metadata_api.utm_proj_params() utm_proj_params.set_zone_code (10) projection_information.set_utm_proj_params (utm_proj_params) del projection_information.utm_proj_params projection_information.utm_proj_params = None global_metadata.set_projection_information (projection_information) # --- global_metadata.set_orientation_angle (0) # Add the global metadata to the top-level object xml.set_global_metadata (global_metadata) # Create bands object