1

The Situation

I have a global multiband-raster of 10x10 km resolution at the equator. I need to turn this raster into a GeoDataframe for further processing (where every band would become one column of values). This GeoDataframe is a global grid, also 10x10 km resolution at the equator. I calculate the centroid of every cell/geometry of the GeoDataframe and retrieve the underlying value of the raster with the point_query function from shapely.

The Problem

The global raster is in the geographic coordinate system EPSG:4326. Employing the shapely centroid function is imprecise when used with a geographic coordinate system, mostly close to the poles (if I understood correctly). For the imprecision, I am referring to the following UserWarning raised by GeoPandas:

UserWarning: Geometry is in a geographic CRS. Results from 'centroid' are likely incorrect. Use 'GeoSeries.to_crs()' to re-project geometries to a projected CRS before this operation.

The Question

Is there a way to assign the correct projected coordinate reference system (e.g., UTM) globally to every "group" of grid cells, and therefore not get the GeoPandas UserWarning raised?

What I have tried

The code below retrieves the centroid of every country in latitude and longitude (could also be any arbitrary grid, e.g. of 10x10 degrees), and generates a UTM code. The problem is, that the calculation of this centroid is already imprecise.

        # Take the UTM coordinate system to correctly calculate the area, since epsg4326 is not a planar crs. See https://gis.stackexchange.com/questions/365584/convert-utm-zone-into-epsg-code
        # set coordinate system for area calculation for points
        country_center_x = TM_border.get_borders().centroid.iloc[
            0].x  # get the x coordinate of the center of the country
        country_center_y = TM_border.get_borders().centroid.iloc[
            0].y  # get the y coordinate of the center of country
        specific_utm = utm.from_latlon(latitude=country_center_y,
                                       longitude=country_center_x)
        if country_center_y < 0:  # if point lies south of equator
            self.crs_dict = {'proj': 'utm', 'zone': specific_utm[2], 'south': True}
        else:  # if point lies north of equator
            self.crs_dict = {'proj': 'utm', 'zone': specific_utm[2]}

To Consider

I do not have a feeling for how much off the calculation of the centroids are close to the poles. Mabye it is negligible if the centroid is calculated on a country or 10x10 degree tile base.

5
  • How can the assignment of a centroid of a rectangle be imprecise?
    – Vince
    Mar 15 at 11:15
  • Your definition of "correct" is vague. There is of course a way to do this, though it seems as if you need to do it to meet your criteria. Similarly, it seems you need to measure whether the centroidss are "off". This seems an open-ended discussion topic, not a problem that can be solved.
    – Vince
    Mar 15 at 11:28
  • Hi @Vince, thanks for you comment. I am referring the definition of incorrect to the warning of GeoPandas: "UserWarning: Geometry is in a geographic CRS. Results from 'centroid' are likely incorrect. Use 'GeoSeries.to_crs()' to re-project geometries to a projected CRS before this operation." What would be a way to bypass that warning?
    – Thierry
    Mar 16 at 8:11
  • If you don't measure it, you don't know the significance, and therefore if the warning should be ignored. If you try to treat a coarse global raster as if it were precise local data, you may be introducing more problems than just a warning message.
    – Vince
    Mar 16 at 11:31
  • Thanks for your elaboration @Vince. How would you suggest to measure this?
    – Thierry
    Mar 22 at 13:51

1 Answer 1

1

It sounds like you're looking for an equal-area projection, rather than a conformal one like UTM. There are a number of equal-area projections that can be seen here, many of which are supported by PROJ - the de facto library for reprojections. So your course of action would be to project your raster to your projection of choice, iterate over every data pixel, and store the coordinates and bands for each in the DataFrame.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.