Repository: sunpy/sunpy

Issue:
Add a contains coordinate method to maputils
This would provide a quick way to see if a world coordinate is contained within the array bounds of a Map


Discussion:
Whoever implements this might as well fix the craziness of `maputils.contains_solar_center()` at the same time (see https://github.com/sunpy/sunpy/pull/4463#discussion_r492832186), since that would just be a special case of a more general function.
Cannot agree more
I am new to open source, want to start from this please can anyone provide me some more information regarding this issue. Like which file to be modified and what to be checked?
Thanks for the interest! Essentially we would like a new function in `sunpy/map/maputils.py` called `contains_coordinate(smap, coord)` (or similar), which returns `True` if the `coord` is within the coordinate bounds of `smap`, and `False` otherwise.

Resolving patch:
diff --git a/sunpy/map/maputils.py b/sunpy/map/maputils.py
--- a/sunpy/map/maputils.py
+++ b/sunpy/map/maputils.py
@@ -15,7 +15,8 @@
            'map_edges', 'solar_angular_radius', 'sample_at_coords',
            'contains_full_disk', 'is_all_off_disk', 'is_all_on_disk',
            'contains_limb', 'coordinate_is_on_solar_disk',
-           'on_disk_bounding_coordinates']
+           'on_disk_bounding_coordinates',
+           'contains_coordinate']
 
 
 def all_pixel_indices_from_map(smap):
@@ -387,3 +388,32 @@ def on_disk_bounding_coordinates(smap):
     return SkyCoord([np.nanmin(tx), np.nanmax(tx)] * u.arcsec,
                     [np.nanmin(ty), np.nanmax(ty)] * u.arcsec,
                     frame=smap.coordinate_frame)
+
+
+def contains_coordinate(smap, coordinates):
+    """
+    Checks whether a coordinate falls within the bounds of a map.
+
+    Parameters
+    ----------
+    smap : `~sunpy.map.GenericMap`
+        The input map.
+    coordinates : `~astropy.coordinates.SkyCoord`
+        The input coordinate.
+
+    Returns
+    -------
+    bool
+        `True` if ``coordinates`` falls within the bounds of ``smap``.
+        This includes the edges of the map. If multiple coordinates are input,
+        returns a boolean arrary.
+    """
+    # Dimensions of smap
+    xs, ys = smap.dimensions
+    # Converting coordinates to pixels
+    xc, yc = smap.world_to_pixel(coordinates)
+    point5pix = 0.5 * u.pix
+    return ((xc >= -point5pix) &
+            (xc <= xs - point5pix) &
+            (yc >= -point5pix) &
+            (yc <= ys - point5pix))


Test patch:
diff --git a/sunpy/map/tests/test_maputils.py b/sunpy/map/tests/test_maputils.py
--- a/sunpy/map/tests/test_maputils.py
+++ b/sunpy/map/tests/test_maputils.py
@@ -13,6 +13,7 @@
     all_coordinates_from_map,
     all_corner_coords_from_map,
     all_pixel_indices_from_map,
+    contains_coordinate,
     contains_full_disk,
     contains_limb,
     contains_solar_center,
@@ -239,3 +240,18 @@ def test_functions_raise_non_frame_map(non_helioprojective_map):
         contains_limb(non_helioprojective_map)
     with pytest.raises(ValueError, match=r"HeliographicCarrington, .* Helioprojective"):
         on_disk_bounding_coordinates(non_helioprojective_map)
+
+
+def test_contains_coord(aia171_test_map):
+    smap = aia171_test_map
+    for coord in [smap.bottom_left_coord,
+                  smap.top_right_coord,
+                  SkyCoord(0*u.deg, 0*u.deg, frame=smap.coordinate_frame)]:
+        assert contains_coordinate(smap, coord)
+
+    assert not contains_coordinate(smap, SkyCoord(2000*u.arcsec, 2000*u.arcsec,
+                                                  frame=smap.coordinate_frame))
+
+    multi_coord = SkyCoord([0, 2000]*u.arcsec, [0, 2000]*u.arcsec,
+                           frame=smap.coordinate_frame)
+    assert (contains_coordinate(smap, multi_coord) == [True, False]).all()