Example #1
0
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()
Example #2
0
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