Understanding regions/geopolygon for geopoint queries in Sanity

3 replies
Last updated: Feb 1, 2022
After reading the docs I am not sure I fully understand regions for geopoint queries. The placeholder name is geopolygon, so are we just doing four points that are themselves sets of lat/long?
AI Update

Yes, you're on the right track! The geopolygon placeholder name refers to a polygon defined by multiple coordinate points (sets of lat/long), but it's not limited to just four points—it can be any number of points that define a closed shape.

How geopoint regions work

The geo functions in Sanity use GeoJSON format under the hood. When you see geopolygon in the docs, it's referring to a geographic polygon that can be:

  1. Created from a GeoJSON object with a type property set to "Polygon" (or other geometry types like "MultiPolygon")
  2. Automatically coerced from objects with lat and lng (or lon) properties for point-based queries

The geo::contains() function

The function signature is geo::contains(geoPolygon, geo), which means:

  • First parameter: A polygon region (your boundary/area)
  • Second parameter: A geo point or shape to test if it's inside that boundary

Here's a practical example from the docs:

// For a given $currentLocation geopoint and deliveryZone area
// Return stores that deliver to a user's location
*[
  _type == "storefront" &&
  geo::contains(deliveryZone, $currentLocation)
]

The polygon itself is an array of coordinate pairs (each being a lat/long set). In GeoJSON format, the first and last coordinates should be identical to "close" the polygon.

Other useful geo functions

// Example: Find stores within 10 miles of a location
*[
  _type == 'storefront' &&
  geo::distance(geoPoint, $currentLocation) < 16093.4
]

Note that these geo functions require API version v2021-03-25 or later.

Show original thread
3 replies
Hi User. The polygon type comes from the GeoJSON spec. For example, here is a very crudely drawn polygon around London:

{
  "type": "Polygon",
  "coordinates": [
    [
      [
        -0.479747,
        51.652658
      ],
      [
        0.441217,
        51.698629
      ],
      [
        0.309875,
        51.337763
      ],
      [
        -0.5435,
        51.366871
      ],
      [
        -0.479747,
        51.652658
      ]
    ]
  ]
}
In GROQ, you can wrap this in the
geo()
function to construct a polygon Sanity understands.
Here is an example GROQ query to find places in the London polygon:


*[_type == "place" && geo::contains(
  geo({
    "type": "Polygon",
    "coordinates": [
      [
        [
          -0.479747,
          51.652658
        ],
        [
          0.441217,
          51.698629
        ],
        [
          0.309875,
          51.337763
        ],
        [
          -0.5435,
          51.366871
        ],
        [
          -0.479747,
          51.652658
        ]
      ]
    ]
  }),
  geo::latLng(lat, lng)
)]{
  name
}
You can try this out in the Sanity Vision plugin with test data, like this:


[
  {
    "_type": "place",
    "name": "Tate Modern",
    "lat": 51.507621,
    "lng": -0.098852
  },
  {
    "_type": "place",
    "name": "Louvre",
    "lat": 48.861598,
    "lng": 2.335093
  }
][_type == "place" && geo::contains(
  geo({
    "type": "Polygon",
    "coordinates": [
      [
        [
          -0.479747,
          51.652658
        ],
        [
          0.441217,
          51.698629
        ],
        [
          0.309875,
          51.337763
        ],
        [
          -0.5435,
          51.366871
        ],
        [
          -0.479747,
          51.652658
        ]
      ]
    ]
  }),
  geo::latLng(lat, lng)
)]{
  name
}
Here are two examples showing queries for places in London, and
not in London:
user E
Ah, I whiffed on connecting the dots to a spec like that in my head. That's so completely awesome. Sanity is like doing an Easter egg hunt at the plastic Easter egg factory. I really appreciate the thorough examples! (That goes for everyone here, actually)
No problem! The docs are a little lacking on the geo functions; I had to go hunting myself to find useful info. We should expand the docs, and something geo-related content would also be awesome to blog about/publish on Exchange .

Sanity – Build the way you think, not the way your CMS thinks

Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.

Was this answer helpful?