def _calc_geospatial_point_center(self, site):

        siteTypes = [RT.Site, RT.Subsite, RT.Observatory, RT.PlatformSite, RT.InstrumentSite]
        if site and site.type_ in siteTypes:
            # if the geospatial_bounds is set then calculate the geospatial_point_center
            for constraint in site.constraint_list:
                if constraint.type_ == OT.GeospatialBounds:
                    site.geospatial_point_center = GeoUtils.calc_geospatial_point_center(constraint)
 def _geodp(self, x1, y1, x2=None, y2=None, z1=0.0, z2=None, t1="", t2=None):
     if x2 is None: x2 = x1
     if y2 is None: y2 = y1
     if z2 is None: z2 = z1
     if t2 is None: t2 = t1
     bounds = self._geobb(x1, y1, x2, y2, z1, z2)
     attrs = dict(location=GeoUtils.calc_geospatial_point_center(bounds, return_location=True),
                  geospatial_bounds=bounds,
                  temporal_bounds=self._temprng(t1, t2))
     return attrs
Exemplo n.º 3
0
 def _geodp(self, x1, y1, x2=None, y2=None, z1=0.0, z2=None, t1="", t2=None):
     if x2 is None: x2 = x1
     if y2 is None: y2 = y1
     if z2 is None: z2 = z1
     if t2 is None: t2 = t1
     bounds = self._geobb(x1, y1, x2, y2, z1, z2)
     attrs = dict(geospatial_point_center=GeoUtils.calc_geospatial_point_center(bounds),
                  geospatial_bounds=bounds,
                  nominal_datetime=self._temprng(t1, t2))
     return attrs
Exemplo n.º 4
0
def get_obj_geospatial_point(doc, calculate=True):
    """Extracts a geospatial point (lat, lon, elev) from given object dict, by looking for an attribute with
    GeospatialIndex or GeospatialPoint or GeospatialLocation type or computing the center from a bounds
    """
    geo_center = None
    # TODO: Be more flexible about finding attributes with the right types
    if "location" in doc:
        geo_center = doc["location"]
    if "geospatial_point_center" in doc:
        geo_center = doc["geospatial_point_center"]
    if "details" in doc and type(
            doc["details"]) is dict and "location" in doc["details"]:
        geo_center = doc["details"]["location"]
    if not geo_center and calculate:
        # Try to calculate center point from bounds
        present, geo_bounds = get_obj_geospatial_bounds(doc,
                                                        calculate=False,
                                                        return_geo_bounds=True)
        if present:
            try:
                from ion.util.geo_utils import GeoUtils
                geo_bounds_obj = DotDict(**geo_bounds)
                geo_center = GeoUtils.calc_geospatial_point_center(
                    geo_bounds_obj)
            except Exception:
                log.exception("Could not calculate geospatial center point")
    if geo_center and isinstance(geo_center, dict):
        if "lat" in geo_center and "lon" in geo_center:
            lat, lon = geo_center.get("lat", 0), geo_center.get("lon", 0)
            if lat or lon:
                return True, (lat, lon, 0)
        elif "latitude" in geo_center and "longitude" in geo_center:
            lat, lon = geo_center.get("latitude",
                                      0), geo_center.get("longitude", 0)
            elev = geo_center.get("elevation", 0)
            if lat or lon or elev:
                return True, (lat, lon, elev)
        elif "geospatial_latitude" in geo_center and "geospatial_longitude" in geo_center:
            lat, lon = geo_center.get("geospatial_latitude",
                                      0), geo_center.get(
                                          "geospatial_longitude", 0)
            elev = geo_center.get("geospatial_vertical_location", 0)
            if lat or lon:
                return True, (lat, lon, elev)
    return False, (0, 0, 0)
Exemplo n.º 5
0
def get_obj_geospatial_point(doc, calculate=True):
    """Extracts a geospatial point (lat, lon, elev) from given object dict, by looking for an attribute with
    GeospatialIndex or GeospatialPoint or GeospatialLocation type or computing the center from a bounds
    """
    geo_center = None
    # TODO: Be more flexible about finding attributes with the right types
    if "location" in doc:
        geo_center = doc["location"]
    if "geospatial_point_center" in doc:
        geo_center = doc["geospatial_point_center"]
    if "details" in doc and type(
            doc["details"]) is dict and "location" in doc["details"]:
        geo_center = doc["details"]["location"]
    if not geo_center and calculate:
        # Try to calculate center point from bounds
        present, geo_bounds = get_obj_geospatial_bounds(
            doc, calculate=False, return_geo_bounds=True)
        if present:
            try:
                from ion.util.geo_utils import GeoUtils
                geo_bounds_obj = DotDict(**geo_bounds)
                geo_center = GeoUtils.calc_geospatial_point_center(
                    geo_bounds_obj)
            except Exception:
                log.exception("Could not calculate geospatial center point")
    if geo_center and isinstance(geo_center, dict):
        if "lat" in geo_center and "lon" in geo_center:
            lat, lon = geo_center.get("lat", 0), geo_center.get("lon", 0)
            if lat or lon:
                return True, (lat, lon, 0)
        elif "latitude" in geo_center and "longitude" in geo_center:
            lat, lon = geo_center.get("latitude", 0), geo_center.get(
                "longitude", 0)
            elev = geo_center.get("elevation", 0)
            if lat or lon or elev:
                return True, (lat, lon, elev)
        elif "geospatial_latitude" in geo_center and "geospatial_longitude" in geo_center:
            lat, lon = geo_center.get("geospatial_latitude",
                                      0), geo_center.get(
                                          "geospatial_longitude", 0)
            elev = geo_center.get("geospatial_vertical_location", 0)
            if lat or lon:
                return True, (lat, lon, elev)
    return False, (0, 0, 0)
 def _geodp(self,
            x1,
            y1,
            x2=None,
            y2=None,
            z1=0.0,
            z2=None,
            t1="",
            t2=None):
     if x2 is None: x2 = x1
     if y2 is None: y2 = y1
     if z2 is None: z2 = z1
     if t2 is None: t2 = t1
     bounds = self._geobb(x1, y1, x2, y2, z1, z2)
     attrs = dict(location=GeoUtils.calc_geospatial_point_center(
         bounds, return_location=True),
                  geospatial_bounds=bounds,
                  temporal_bounds=self._temprng(t1, t2))
     return attrs
Exemplo n.º 7
0
    def test_midpoint(self):
        geospatial_bounds = IonObject("GeospatialBounds")
        geospatial_bounds.geospatial_latitude_limit_north = 10
        geospatial_bounds.geospatial_latitude_limit_south = -10
        geospatial_bounds.geospatial_longitude_limit_east = 10
        geospatial_bounds.geospatial_longitude_limit_west = -10

        # Basic test
        #TODO. do we really want calc_geospatial_point_center() to return string?
        mid_point = GeoUtils.calc_geospatial_point_center(geospatial_bounds)
        self.assertAlmostEqual(mid_point.lat, 0.0)
        self.assertAlmostEqual(mid_point.lon, 0.0)

        mid_point = GeoUtils.calc_geospatial_point_center(
            geospatial_bounds, distance=GeoUtils.DISTANCE_SHORTEST)
        self.assertAlmostEqual(mid_point.lat, 0.0)
        self.assertAlmostEqual(mid_point.lon, 0.0)

        mid_point = GeoUtils.calc_geospatial_point_center(
            geospatial_bounds, distance=GeoUtils.DISTANCE_LONGEST)
        self.assertAlmostEqual(mid_point.lat, 0.0)
        self.assertAlmostEqual(mid_point.lon, -180)

        geospatial_bounds.geospatial_latitude_limit_north = 10
        geospatial_bounds.geospatial_latitude_limit_south = -10
        geospatial_bounds.geospatial_longitude_limit_east = 179
        geospatial_bounds.geospatial_longitude_limit_west = -179

        mid_point = GeoUtils.calc_geospatial_point_center(geospatial_bounds)
        self.assertAlmostEqual(mid_point.lat, 0.0)
        self.assertAlmostEqual(mid_point.lon, 0.0)
        mid_point = GeoUtils.calc_geospatial_point_center(
            geospatial_bounds, distance=GeoUtils.DISTANCE_SHORTEST)
        self.assertAlmostEqual(mid_point.lat, 0.0)
        self.assertAlmostEqual(mid_point.lon, -180.0)
        mid_point = GeoUtils.calc_geospatial_point_center(
            geospatial_bounds, distance=GeoUtils.DISTANCE_LONGEST)
        self.assertAlmostEqual(mid_point.lat, 0.0)
        self.assertAlmostEqual(mid_point.lon, 0.0)
        geospatial_bounds.geospatial_longitude_limit_east = -179
        geospatial_bounds.geospatial_longitude_limit_west = 179
        mid_point = GeoUtils.calc_geospatial_point_center(geospatial_bounds)
        self.assertAlmostEqual(mid_point.lon, -180.0)

        geospatial_bounds.geospatial_latitude_limit_north = 90
        geospatial_bounds.geospatial_latitude_limit_south = -90
        geospatial_bounds.geospatial_longitude_limit_east = 0
        geospatial_bounds.geospatial_longitude_limit_west = 0
        mid_point = GeoUtils.calc_geospatial_point_center(geospatial_bounds)
        self.assertAlmostEqual(mid_point.lat, 0.0)
        self.assertAlmostEqual(mid_point.lon, 0.0)
        # MM: changed this: if the same values are given, we expect a point not the full globe
        #self.assertAlmostEqual(mid_point.lon, -180.0)

        geospatial_bounds.geospatial_latitude_limit_north = 40
        geospatial_bounds.geospatial_latitude_limit_south = 50
        geospatial_bounds.geospatial_longitude_limit_east = -75
        geospatial_bounds.geospatial_longitude_limit_west = -125
        mid_point = GeoUtils.calc_geospatial_point_center(geospatial_bounds)
        self.assertAlmostEqual(mid_point.lat, 47.801397, 6)
        self.assertAlmostEqual(mid_point.lon, -102.328727, 6)
        mid_point = GeoUtils.calc_geospatial_point_center(
            geospatial_bounds, distance=GeoUtils.DISTANCE_SHORTEST)
        self.assertAlmostEqual(mid_point.lat, 47.801397, 6)
        self.assertAlmostEqual(mid_point.lon, -102.328727, 6)

        mid_point = GeoUtils.calc_geospatial_point_center(
            geospatial_bounds, distance=GeoUtils.DISTANCE_LONGEST)
        self.assertAlmostEqual(mid_point.lat, 47.801397, 6)
        self.assertAlmostEqual(mid_point.lon, 77.671273, 6)

        geospatial_bounds.geospatial_longitude_limit_west = 165
        geospatial_bounds.geospatial_latitude_limit_north = 5
        geospatial_bounds.geospatial_longitude_limit_east = -170
        geospatial_bounds.geospatial_latitude_limit_south = 5
        mid_point = GeoUtils.calc_geospatial_point_center(geospatial_bounds)
        self.assertAlmostEqual(mid_point.lat, 5.121583, 6)
        self.assertAlmostEqual(mid_point.lon, 177.5, 6)

        geospatial_bounds.geospatial_longitude_limit_west = 65
        geospatial_bounds.geospatial_latitude_limit_north = 0
        geospatial_bounds.geospatial_longitude_limit_east = 165
        geospatial_bounds.geospatial_latitude_limit_south = 0
        mid_point = GeoUtils.calc_geospatial_point_center(geospatial_bounds)
        self.assertAlmostEqual(mid_point.lat, 0.0, 6)
        self.assertAlmostEqual(mid_point.lon, 115.0, 6)

        geospatial_bounds.geospatial_longitude_limit_west = 10.0
        geospatial_bounds.geospatial_latitude_limit_north = 0
        geospatial_bounds.geospatial_longitude_limit_east = -150
        geospatial_bounds.geospatial_latitude_limit_south = 0
        mid_point = GeoUtils.calc_geospatial_point_center(geospatial_bounds)
        self.assertAlmostEqual(mid_point.lat, 0.0, 6)
        self.assertAlmostEqual(mid_point.lon, 110.0, 6)

        geospatial_bounds.geospatial_longitude_limit_west = -150
        geospatial_bounds.geospatial_latitude_limit_north = 0
        geospatial_bounds.geospatial_longitude_limit_east = 170
        geospatial_bounds.geospatial_latitude_limit_south = 0
        mid_point = GeoUtils.calc_geospatial_point_center(geospatial_bounds)
        self.assertAlmostEqual(mid_point.lat, 0.0, 6)
        self.assertAlmostEqual(mid_point.lon, 10.0, 6)

        geospatial_bounds.geospatial_longitude_limit_west = 30
        geospatial_bounds.geospatial_latitude_limit_north = 0
        geospatial_bounds.geospatial_longitude_limit_east = 10
        geospatial_bounds.geospatial_latitude_limit_south = 0
        mid_point = GeoUtils.calc_geospatial_point_center(geospatial_bounds)
        self.assertAlmostEqual(mid_point.lat, 0.0, 6)
        self.assertAlmostEqual(mid_point.lon, -160.0, 6)

        geospatial_bounds.geospatial_longitude_limit_west = 10
        geospatial_bounds.geospatial_latitude_limit_north = 0
        geospatial_bounds.geospatial_longitude_limit_east = 50
        geospatial_bounds.geospatial_latitude_limit_south = 0
        mid_point = GeoUtils.calc_geospatial_point_center(geospatial_bounds)
        self.assertAlmostEqual(mid_point.lat, 0.0, 6)
        self.assertAlmostEqual(mid_point.lon, 30.0, 6)

        geospatial_bounds.geospatial_longitude_limit_west = -170
        geospatial_bounds.geospatial_latitude_limit_north = 0
        geospatial_bounds.geospatial_longitude_limit_east = -10
        geospatial_bounds.geospatial_latitude_limit_south = 0
        mid_point = GeoUtils.calc_geospatial_point_center(geospatial_bounds)
        self.assertAlmostEqual(mid_point.lat, 0.0, 6)
        self.assertAlmostEqual(mid_point.lon, -90.0, 6)

        # Bad requests
        with self.assertRaises(BadRequest):
            GeoUtils.calc_geospatial_point_center(geospatial_bounds,
                                                  distance="spacetime")
        geospatial_bounds.geospatial_latitude_limit_north = 10
        geospatial_bounds.geospatial_latitude_limit_south = -10
        geospatial_bounds.geospatial_longitude_limit_east = 10
        geospatial_bounds.geospatial_longitude_limit_west = -181
        with self.assertRaises(BadRequest):
            GeoUtils.calc_geospatial_point_center(geospatial_bounds)

        geospatial_bounds.geospatial_latitude_limit_north = 10
        geospatial_bounds.geospatial_latitude_limit_south = -10
        geospatial_bounds.geospatial_longitude_limit_east = 181
        geospatial_bounds.geospatial_longitude_limit_west = -10
        with self.assertRaises(BadRequest):
            GeoUtils.calc_geospatial_point_center(geospatial_bounds)

        geospatial_bounds.geospatial_latitude_limit_north = 10
        geospatial_bounds.geospatial_latitude_limit_south = -91
        geospatial_bounds.geospatial_longitude_limit_east = 181
        geospatial_bounds.geospatial_longitude_limit_west = -10
        with self.assertRaises(BadRequest):
            GeoUtils.calc_geospatial_point_center(geospatial_bounds)

        geospatial_bounds.geospatial_latitude_limit_north = 91
        geospatial_bounds.geospatial_latitude_limit_south = -10
        geospatial_bounds.geospatial_longitude_limit_east = 0
        geospatial_bounds.geospatial_longitude_limit_west = -10
        with self.assertRaises(BadRequest):
            GeoUtils.calc_geospatial_point_center(geospatial_bounds)
Exemplo n.º 8
0
    def test_midpoint(self):
        geospatial_bounds = IonObject("GeospatialBounds")
        geospatial_bounds.geospatial_latitude_limit_north = 10
        geospatial_bounds.geospatial_latitude_limit_south = -10
        geospatial_bounds.geospatial_longitude_limit_east = 10
        geospatial_bounds.geospatial_longitude_limit_west = -10

        # Basic test
        #TODO. do we really want calc_geospatial_point_center() to return string?
        mid_point = GeoUtils.calc_geospatial_point_center(geospatial_bounds)
        self.assertAlmostEqual(mid_point.lat, 0.0)
        self.assertAlmostEqual(mid_point.lon, 0.0)

        mid_point = GeoUtils.calc_geospatial_point_center(geospatial_bounds, distance=GeoUtils.DISTANCE_SHORTEST)
        self.assertAlmostEqual(mid_point.lat, 0.0)
        self.assertAlmostEqual(mid_point.lon, 0.0)

        mid_point = GeoUtils.calc_geospatial_point_center(geospatial_bounds, distance=GeoUtils.DISTANCE_LONGEST)
        self.assertAlmostEqual(mid_point.lat, 0.0)
        self.assertAlmostEqual(mid_point.lon, -180)


        geospatial_bounds.geospatial_latitude_limit_north = 10
        geospatial_bounds.geospatial_latitude_limit_south = -10
        geospatial_bounds.geospatial_longitude_limit_east = 179
        geospatial_bounds.geospatial_longitude_limit_west = -179

        mid_point = GeoUtils.calc_geospatial_point_center(geospatial_bounds)
        self.assertAlmostEqual(mid_point.lat, 0.0)
        self.assertAlmostEqual(mid_point.lon, 0.0)
        mid_point = GeoUtils.calc_geospatial_point_center(geospatial_bounds, distance=GeoUtils.DISTANCE_SHORTEST)
        self.assertAlmostEqual(mid_point.lat, 0.0)
        self.assertAlmostEqual(mid_point.lon, -180.0)
        mid_point = GeoUtils.calc_geospatial_point_center(geospatial_bounds, distance=GeoUtils.DISTANCE_LONGEST)
        self.assertAlmostEqual(mid_point.lat, 0.0)
        self.assertAlmostEqual(mid_point.lon, 0.0)
        geospatial_bounds.geospatial_longitude_limit_east = -179
        geospatial_bounds.geospatial_longitude_limit_west = 179
        mid_point = GeoUtils.calc_geospatial_point_center(geospatial_bounds)
        self.assertAlmostEqual(mid_point.lon, -180.0)


        geospatial_bounds.geospatial_latitude_limit_north = 90
        geospatial_bounds.geospatial_latitude_limit_south = -90
        geospatial_bounds.geospatial_longitude_limit_east = 0
        geospatial_bounds.geospatial_longitude_limit_west = 0
        mid_point = GeoUtils.calc_geospatial_point_center(geospatial_bounds)
        self.assertAlmostEqual(mid_point.lat, 0.0)
        self.assertAlmostEqual(mid_point.lon, 0.0)
        # MM: changed this: if the same values are given, we expect a point not the full globe
        #self.assertAlmostEqual(mid_point.lon, -180.0)

        geospatial_bounds.geospatial_latitude_limit_north = 40
        geospatial_bounds.geospatial_latitude_limit_south = 50
        geospatial_bounds.geospatial_longitude_limit_east = -75
        geospatial_bounds.geospatial_longitude_limit_west = -125
        mid_point = GeoUtils.calc_geospatial_point_center(geospatial_bounds)
        self.assertAlmostEqual(mid_point.lat, 47.801397, 6)
        self.assertAlmostEqual(mid_point.lon, -102.328727, 6)
        mid_point = GeoUtils.calc_geospatial_point_center(geospatial_bounds, distance=GeoUtils.DISTANCE_SHORTEST)
        self.assertAlmostEqual(mid_point.lat, 47.801397, 6)
        self.assertAlmostEqual(mid_point.lon, -102.328727, 6)

        mid_point = GeoUtils.calc_geospatial_point_center(geospatial_bounds, distance=GeoUtils.DISTANCE_LONGEST)
        self.assertAlmostEqual(mid_point.lat, 47.801397, 6)
        self.assertAlmostEqual(mid_point.lon, 77.671273, 6)

        geospatial_bounds.geospatial_longitude_limit_west = 165
        geospatial_bounds.geospatial_latitude_limit_north = 5
        geospatial_bounds.geospatial_longitude_limit_east = -170
        geospatial_bounds.geospatial_latitude_limit_south = 5
        mid_point = GeoUtils.calc_geospatial_point_center(geospatial_bounds)
        self.assertAlmostEqual(mid_point.lat, 5.121583, 6)
        self.assertAlmostEqual(mid_point.lon, 177.5, 6)

        geospatial_bounds.geospatial_longitude_limit_west = 65
        geospatial_bounds.geospatial_latitude_limit_north = 0
        geospatial_bounds.geospatial_longitude_limit_east = 165
        geospatial_bounds.geospatial_latitude_limit_south = 0
        mid_point = GeoUtils.calc_geospatial_point_center(geospatial_bounds)
        self.assertAlmostEqual(mid_point.lat, 0.0, 6)
        self.assertAlmostEqual(mid_point.lon, 115.0, 6)

        geospatial_bounds.geospatial_longitude_limit_west = 10.0
        geospatial_bounds.geospatial_latitude_limit_north = 0
        geospatial_bounds.geospatial_longitude_limit_east = -150
        geospatial_bounds.geospatial_latitude_limit_south = 0
        mid_point = GeoUtils.calc_geospatial_point_center(geospatial_bounds)
        self.assertAlmostEqual(mid_point.lat, 0.0, 6)
        self.assertAlmostEqual(mid_point.lon, 110.0, 6)

        geospatial_bounds.geospatial_longitude_limit_west = -150
        geospatial_bounds.geospatial_latitude_limit_north = 0
        geospatial_bounds.geospatial_longitude_limit_east = 170
        geospatial_bounds.geospatial_latitude_limit_south = 0
        mid_point = GeoUtils.calc_geospatial_point_center(geospatial_bounds)
        self.assertAlmostEqual(mid_point.lat, 0.0, 6)
        self.assertAlmostEqual(mid_point.lon, 10.0, 6)

        geospatial_bounds.geospatial_longitude_limit_west = 30
        geospatial_bounds.geospatial_latitude_limit_north = 0
        geospatial_bounds.geospatial_longitude_limit_east = 10
        geospatial_bounds.geospatial_latitude_limit_south = 0
        mid_point = GeoUtils.calc_geospatial_point_center(geospatial_bounds)
        self.assertAlmostEqual(mid_point.lat, 0.0, 6)
        self.assertAlmostEqual(mid_point.lon, -160.0, 6)

        geospatial_bounds.geospatial_longitude_limit_west = 10
        geospatial_bounds.geospatial_latitude_limit_north = 0
        geospatial_bounds.geospatial_longitude_limit_east = 50
        geospatial_bounds.geospatial_latitude_limit_south = 0
        mid_point = GeoUtils.calc_geospatial_point_center(geospatial_bounds)
        self.assertAlmostEqual(mid_point.lat, 0.0, 6)
        self.assertAlmostEqual(mid_point.lon, 30.0, 6)

        geospatial_bounds.geospatial_longitude_limit_west = -170
        geospatial_bounds.geospatial_latitude_limit_north = 0
        geospatial_bounds.geospatial_longitude_limit_east = -10
        geospatial_bounds.geospatial_latitude_limit_south = 0
        mid_point = GeoUtils.calc_geospatial_point_center(geospatial_bounds)
        self.assertAlmostEqual(mid_point.lat, 0.0, 6)
        self.assertAlmostEqual(mid_point.lon, -90.0, 6)

        # Bad requests
        with self.assertRaises(BadRequest):
            GeoUtils.calc_geospatial_point_center(geospatial_bounds, distance="spacetime")
        geospatial_bounds.geospatial_latitude_limit_north = 10
        geospatial_bounds.geospatial_latitude_limit_south = -10
        geospatial_bounds.geospatial_longitude_limit_east = 10
        geospatial_bounds.geospatial_longitude_limit_west = -181
        with self.assertRaises(BadRequest):
            GeoUtils.calc_geospatial_point_center(geospatial_bounds)

        geospatial_bounds.geospatial_latitude_limit_north = 10
        geospatial_bounds.geospatial_latitude_limit_south = -10
        geospatial_bounds.geospatial_longitude_limit_east = 181
        geospatial_bounds.geospatial_longitude_limit_west = -10
        with self.assertRaises(BadRequest):
            GeoUtils.calc_geospatial_point_center(geospatial_bounds)

        geospatial_bounds.geospatial_latitude_limit_north = 10
        geospatial_bounds.geospatial_latitude_limit_south = -91
        geospatial_bounds.geospatial_longitude_limit_east = 181
        geospatial_bounds.geospatial_longitude_limit_west = -10
        with self.assertRaises(BadRequest):
            GeoUtils.calc_geospatial_point_center(geospatial_bounds)

        geospatial_bounds.geospatial_latitude_limit_north = 91
        geospatial_bounds.geospatial_latitude_limit_south = -10
        geospatial_bounds.geospatial_longitude_limit_east = 0
        geospatial_bounds.geospatial_longitude_limit_west = -10
        with self.assertRaises(BadRequest):
            GeoUtils.calc_geospatial_point_center(geospatial_bounds)