Google Sheets formulas for maps, addresses and routes

36 free Google Sheets formulas that geocode, clean, measure, route, publish and report — straight from your spreadsheet. They work like native formulas: type one, fill a whole column.

Cheat sheet

One line each. Ranges everywhere an address goes: =GEOCODE(A2:A50) fills fifty rows.

Geocode & clean

=GEOCODE(address)Latitude and longitude for an address, a range, or Plus Codes.
=CLEAN_ADDRESS(address)The standardised, geocoder-verified version of a messy address.
=REVERSE_GEOCODE(lat, lng)The nearest street address for coordinates.
=COORD_CONVERT(coords, to?)Convert coordinates between decimal and degrees/minutes/seconds.
=GEOCODE_IP(ip)City, country and coordinates for an IP address (or range of them).

Fill address columns

=POSTCODE(address)The postcode / ZIP. Aliases: =ZIP, =ZIPCODE.
=CITY(address)The city or town. Alias: =TOWN.
=COUNTY(address)The county / district.
=STATE(address)The state / region. Alias: =REGION.
=COUNTRY(address)The country.

Distances & questions

=DISTANCE(from, to, unit?, mode?)Road distance between two places: the miles a car drives. Add "straight" for as the crow flies.
=TRAVEL_TIME(from, to, mode?)Real road travel time between two places, in minutes.
=DISTANCE_MATRIX(origins, destinations, mode?, unit?)Every-to-every road distances (or times): origins down, destinations across.
=CLOSEST_TO(anchor, candidates, n?)The nearest location(s) to an anchor, from a list.
=WITHIN_RADIUS(anchor, candidates, radius, unit?)Everything from a list inside a radius, sorted nearest-first.
=SORT_BY_DISTANCE(range, anchor, unit?)Your rows re-sorted nearest-first, with a distance column added.

What's around it (UK)

=NEARBY(anchor, category, n?, radius?)The places of a category around one point: name, distance and address, nearest first.
=COUNT_NEARBY(range, category, radius?, unit?)How many places of a category sit within a radius of every row — competitor density, amenity scores, site scorecards.
=NEAREST(range, kind, unit?)The nearest place of a kind to every row, with the distance — nearest station, car park, hospital, motorway junction.

Risk at each address

=CRIME(range, kind?)Recorded crime around every address — for underwriting, site selection and security planning.
=FLOOD(range)The official flood zone at every address, and whether it is high, medium or low risk.
=HAZARD(range, hazard?)FEMA natural-hazard risk at every US address — hurricane, wildfire, tornado, hail, earthquake and more.

Run the day

=GEOCODE_WORKFLOW(stops, start?, end?)The whole route day in one formula: coordinates, best visiting order, and one Google Maps route link.
=VISIT_ORDER(stops, start?, end?)The best visiting order (1, 2, 3…) aligned to your rows — on real routes this cuts 20–50% of the miles.
=ROUTE_LINK(stops, mode?)One Google Maps link for the whole run — up to 100 stops (10x Google's usual 10).
=WAZE_LINK(address)A tap-to-navigate Waze link per row.
=TERRITORY(addresses, reps, balanceBy?)Splits a list into balanced geographic territories, one per rep.
=LOGBOOK(mapLink, limit?, refresh?, override?)The full visit journal, newest first: every check-off ever, like a bank statement. Answers "what happened, in order?"
=VISIT_STATUS(range, mapLink, refresh?, override?)One row per customer, aligned with YOUR list: their current status only, like an account balance. Answers "where does each customer stand?"

Publish & share

=INSTAMAP(range, title?)A hosted, live, shareable map from your rows — the URL lands in the cell.
=EMBED_MAP(range, siteName)A white-label embed link for your website: no branding, light theme, your name on the loading screen.
=STREETVIEW_LINK(address)A Google Street View link per row — tap to look at the building.

Full reference

Geocode & clean

=GEOCODE(address)

The workhorse: coordinates for anything address-shaped. Handles street addresses, postcodes, landmarks, and Plus Codes — both full (772CH947+CV) and short with a locality (H963+HV Maracaibo).

ArgumentWhat it takes
addressAn address, or a range of addresses (=GEOCODE(A2:A50) fills every row).
=GEOCODE(A2)
=GEOCODE(A2:A50)

Ranges above 400 rows: use Extensions → InstaMaps → Add coordinates to this sheet (no formula time limits).

=CLEAN_ADDRESS(address)

The standardised, geocoder-verified version of a messy address.

ArgumentWhat it takes
addressAn address, or a range of addresses (=GEOCODE(A2:A50) fills every row).
=CLEAN_ADDRESS(A2:A50)
=REVERSE_GEOCODE(lat, lng)

The nearest street address for coordinates.

ArgumentWhat it takes
latLatitude — or a single "lat,lng" string as the only argument.
lngLongitude.
=REVERSE_GEOCODE(51.5007, -0.1246)
=REVERSE_GEOCODE(A2)
=COORD_CONVERT(coords, to?)

Convert coordinates between decimal and degrees/minutes/seconds.

ArgumentWhat it takes
coordsThe coordinates to convert (either format).
toOptional target: "dms" (default) or "decimal".
=COORD_CONVERT("51.5007, -0.1246")
=COORD_CONVERT(A2, "decimal")
=GEOCODE_IP(ip)

City, country and coordinates for an IP address (or range of them).

ArgumentWhat it takes
ipAn IP address, or a range of IPs.
=GEOCODE_IP(A2:A50)

Fill address columns

=POSTCODE(address)

The postcode / ZIP. Aliases: =ZIP, =ZIPCODE.

ArgumentWhat it takes
addressAn address, or a range of addresses (=GEOCODE(A2:A50) fills every row).
=POSTCODE(A2:A50)
=CITY(address)

The city or town. Alias: =TOWN.

ArgumentWhat it takes
addressAn address, or a range of addresses (=GEOCODE(A2:A50) fills every row).
=CITY(A2:A50)
=COUNTY(address)

The county / district.

ArgumentWhat it takes
addressAn address, or a range of addresses (=GEOCODE(A2:A50) fills every row).
=COUNTY(A2:A50)
=STATE(address)

The state / region. Alias: =REGION.

ArgumentWhat it takes
addressAn address, or a range of addresses (=GEOCODE(A2:A50) fills every row).
=STATE(A2:A50)
=COUNTRY(address)

The country.

ArgumentWhat it takes
addressAn address, or a range of addresses (=GEOCODE(A2:A50) fills every row).
=COUNTRY(A2:A50)

Distances & questions

=DISTANCE(from, to, unit?, mode?)

Road distance between two places: the miles a car drives. Add "straight" for as the crow flies.

ArgumentWhat it takes
fromAn address or "lat,lng".
toAn address or "lat,lng".
unitOptional: "km" (default) or "mi".
modeOptional: "straight" for straight-line distance instead of road.
=DISTANCE(A2, B2, "mi")
=DISTANCE(A2, B2, "mi", "straight")
=TRAVEL_TIME(from, to, mode?)

Real road travel time between two places, in minutes.

ArgumentWhat it takes
fromAn address or "lat,lng".
toAn address or "lat,lng".
modeOptional: driving (default), walking, cycling.
=TRAVEL_TIME(A2, B2)
=TRAVEL_TIME(A2, B2, "walking")
=DISTANCE_MATRIX(origins, destinations, mode?, unit?)

Every-to-every road distances (or times): origins down, destinations across.

ArgumentWhat it takes
originsAddresses down the side (up to 25).
destinationsAddresses across the top (up to 25).
modeOptional: driving (default), walking, cycling.
unitOptional: "km" (default), "mi", or "min" for travel time.
=DISTANCE_MATRIX(A2:A10, C2:C6, "driving", "min")
=CLOSEST_TO(anchor, candidates, n?)

The nearest location(s) to an anchor, from a list.

ArgumentWhat it takes
anchorThe reference address (or "lat,lng").
candidatesThe list to search (e.g. A2:A200).
nOptional: how many nearest to return (default 1).
=CLOSEST_TO(B1, A2:A200)
=CLOSEST_TO(B1, A2:A200, 5)
=WITHIN_RADIUS(anchor, candidates, radius, unit?)

Everything from a list inside a radius, sorted nearest-first.

ArgumentWhat it takes
anchorThe centre address (or "lat,lng").
candidatesThe list to search.
radiusThe radius number.
unitOptional: "km" (default) or "mi".
=WITHIN_RADIUS(B1, A2:A200, 25, "mi")
=SORT_BY_DISTANCE(range, anchor, unit?)

Your rows re-sorted nearest-first, with a distance column added.

ArgumentWhat it takes
rangeThe rows to sort (address in any column).
anchorThe reference address (or "lat,lng").
unitOptional: "km" (default) or "mi".
=SORT_BY_DISTANCE(A2:C50, "Manchester")

What's around it (UK)

=NEARBY(anchor, category, n?, radius?)

The places of a category around one point: name, distance and address, nearest first.

ArgumentWhat it takes
anchorThe point: an address or "lat,lng".
categoryWhat to look for: "pharmacy", "station", "supermarket", "school", "GP", "pub", "car park", "petrol station", "EV charging", "estate agent", "industrial estate" and more.
nOptional: how many to return (default 10, max 50).
radiusOptional: search radius in km (default 2, max 25).
=NEARBY(B1, "pharmacy")
=NEARBY(B1, "station", 3, 5)
=COUNT_NEARBY(range, category, radius?, unit?)

How many places of a category sit within a radius of every row — competitor density, amenity scores, site scorecards.

ArgumentWhat it takes
rangeAddresses or "lat,lng" cells, one per row (up to 500).
categoryWhat to count, e.g. "school", "supermarket", "pub".
radiusOptional: radius number (default 2 km, max 25 km).
unitOptional: "km" (default) or "mi".
=COUNT_NEARBY(A2:A200, "school", 1)
=COUNT_NEARBY(A2:A200, "supermarket", 0.5, "mi")
=NEAREST(range, kind, unit?)

The nearest place of a kind to every row, with the distance — nearest station, car park, hospital, motorway junction.

ArgumentWhat it takes
rangeAddresses or "lat,lng" cells, one per row (up to 500).
kindWhat to find, e.g. "station", "school", "car park", "GP".
unitOptional: "km" (default) or "mi".
=NEAREST(A2:A200, "station")
=NEAREST(A2:A200, "car park", "mi")

Risk at each address

=CRIME(range, kind?)

Crimes recorded within about 250 m of each UK address in the latest published month (police.uk), optionally one type. UK only for now.

ArgumentWhat it takes
rangeAddresses or "lat,lng" cells, one per row (up to 300).
kindOptional: "vehicle", "burglary", "violent", "theft", "shoplifting", "anti-social", "robbery", "drugs", "criminal damage" or "bike" (default: all crime).
=CRIME(A2:A200)
=CRIME(A2:A200, "vehicle")
=FLOOD(range)

England: Environment Agency Flood Map for Planning (Zone 3 high, Zone 2 medium, Zone 1 low). US: FEMA flood zone (A and V zones are high-risk Special Flood Hazard Areas).

ArgumentWhat it takes
rangeAddresses or "lat,lng" cells, one per row (up to 300).
=FLOOD(A2:A200)
=HAZARD(range, hazard?)

The FEMA National Risk Index rating for the census tract each address sits in: Very Low, Relatively Low, Relatively Moderate, Relatively High or Very High. US only.

ArgumentWhat it takes
rangeUS addresses or "lat,lng" cells, one per row (up to 300).
hazardOptional: "overall" (default), "hurricane", "wildfire", "tornado", "hail", "earthquake", "inland flood", "coastal flood", "heat wave", "winter weather", "strong wind", "lightning", "landslide" or "drought".
=HAZARD(A2:A200)
=HAZARD(A2:A200, "hurricane")

Run the day

=GEOCODE_WORKFLOW(stops, start?, end?)

The three-formula chain as a single spill: per row you get Lat, Lng and Visit order; the first row also carries the Route link for the whole run in visiting order (up to 100 stops).

ArgumentWhat it takes
stopsYour stops (2–100), e.g. A2:A101. Plus Codes work.
startOptional starting address (default: the first row).
endOptional end point: the run finishes at the row nearest this address, or gets a final leg back to it (your depot). Same address for start and end = a round trip.
=GEOCODE_WORKFLOW(A2:A26)
=GEOCODE_WORKFLOW(A2:A26, "The depot, Salford")
=VISIT_ORDER(stops, start?, end?)

The best visiting order (1, 2, 3…) aligned to your rows — on real routes this cuts 20–50% of the miles.

ArgumentWhat it takes
stopsThe stops to order.
startOptional starting address (default: the first row).
endOptional end point: the run finishes at the row nearest this address, or gets a final leg back to it (your depot). Same address for start and end = a round trip.
=VISIT_ORDER(B2:B26)
=VISIT_ORDER(B2:B26, "The depot, Salford")
=TERRITORY(addresses, reps, balanceBy?)

Splits a list into balanced geographic territories, one per rep.

ArgumentWhat it takes
addressesThe addresses to split.
repsA number of territories, or a range of rep names.
balanceByOptional value column to balance by (e.g. revenue).
=TERRITORY(A2:A500, 4)
=TERRITORY(A2:A500, D2:D5, C2:C500)
=LOGBOOK(mapLink, limit?, refresh?, override?)

Pairs with the map's Logbook page: your crew checks off stops on their phones, this formula pulls the dated history back into the sheet — every event, repeat visits included, on its own tab. For "where does each customer stand right now?", use =VISIT_STATUS instead: same data, one current row per customer.

ArgumentWhat it takes
mapLinkYour map link from =INSTAMAP, or the map id.
limitOptional: number of entries (default 200, max 500).
refreshOptional: point at a refresh cell — any change to it refetches. "Set up visit tracking" wires this automatically (and bumps it as you work); ⚡ Live sync turns it into a count that changes on every check-off. NOW() is not allowed as a custom-function argument.
overrideOptional: point at a spare cell; change that cell to refetch instantly.
=LOGBOOK($M$3)
=LOGBOOK($M$3, 200, $D$1)
=VISIT_STATUS(range, mapLink, refresh?, override?)

The other projection of the same data as =LOGBOOK: where the journal is time-ordered history (many rows per stop), this is customer-ordered state (exactly one row each, beside your data). Put it next to your customer list and the latest check-off lands on the right row by itself.

ArgumentWhat it takes
rangeYour client rows (first cell = the name, same as =INSTAMAP).
mapLinkYour map link from =INSTAMAP, or the map id.
refreshOptional: point it at COUNTA over your =LOGBOOK journal — each new check-off changes the count, which refetches the statuses. Start the range at column B of the spill: Sheets blocks custom functions from touching the NOW() cell itself.
overrideOptional: a spare cell for instant manual refetch.
=VISIT_STATUS(A2:A50, $M$3, COUNTA(Logbook!$B$3:$F))

Publish & share

=INSTAMAP(range, title?)

The map updates itself when the sheet changes. Same title = same map, updated in place, so the link you share stays good forever.

ArgumentWhat it takes
rangeThe rows to map (first cell of each row becomes the pin name).
titleOptional map title — also its stable identity.
=INSTAMAP(A2:D50, "Client visits")
=EMBED_MAP(range, siteName)

A white-label embed link for your website: no branding, light theme, your name on the loading screen.

ArgumentWhat it takes
rangeRows to map (first cell = the pin name).
siteNameYour site's name — shows while the map loads, and pins the map's identity.
=EMBED_MAP(A2:C50, "Palouse Mindfulness")

Paste the returned link into an iframe: <iframe src="THE_LINK" width="100%" height="600" style="border:0"></iframe>

All of it, free, inside Google Sheets™

Install InstaMaps