[email protected]

CASE STUDY: ACF Google Map Radius Search

February 2, 2024

Radius Search ACF Google Map Field

In this case study I’ll walk through how I was able to create a radius search from Google map data for a client.

It’s a bit technical if you just want to see the output, scroll down to the video for a demo of the front end.

My clients requirement was for a user to enter their Zip code and then for the code to search on a custom post type called location and return all locations within a 100 mile radius.

We had attached an ACF google map field to the custom post type so we could save the address data of the location on the post, I created a map and I could output all of the data points on the map, so far so good.

Problem One – Google Maps Latitude and Longitude Data Is Serialised

The data is serialised so it is very hard to search on an ACF google map, so I create two new fields (latitude and longitude) and upon save of the custom post type I grab the ACF field latitude and longitude and save them into their own fields.

function nm_update_lat_long($post_id){
	
	$post_type = get_post_type( $post_id );

    if ( 'location' == $post_type ) {
	
		$xxx_map= get_field('xxx_google_map', $post_id);
	
		$_POST["acf"]["field_65b8c2e984961"]=$xxx_map['lat'];
		$_POST["acf"]["field_65b8c2fb84962"]=$xxx_map['lng'];
	
		return $_POST;
	}
}

add_action('acf/save_post', 'nm_update_lat_long',1);

Convert Zip Code TO Co-Ordinates

Using the Google maps API I can do a search using a zip code and return a set of latitude and longitude co-ordinates I can use to create my search are. The code looks like this.

function nm_get_coords_zip_code($zip){
	
	
	$api_key=get_field('xxx_options_google_map_api_key','options'); 
	$url = "https://maps.googleapis.com/maps/api/geocode/json?address=".$zip."&sensor=false&key=".$api_key;
        $details=file_get_contents($url);
        $result = json_decode($details,true);
        $account_lat=$result['results'][0]['geometry']['location']['lat'];
        $account_long=$result['results'][0]['geometry']['location']['lng'];
	return array($account_lat,$account_long);
	
}

The Search Box

Using maths I’ve not used since school, I was able to return a box which is 100 miles radius of my zip code. Who am I kidding I found it on stack overflow.

function nm_getBoundingBox($lat_degrees,$lon_degrees,$distance_in_miles) {

    $radius = 3963.1; // of earth in miles

    // bearings - FIX   
    $due_north = deg2rad(0);
    $due_south = deg2rad(180);
    $due_east = deg2rad(90);
    $due_west = deg2rad(270);

    // convert latitude and longitude into radians 
    $lat_r = deg2rad($lat_degrees);
    $lon_r = deg2rad($lon_degrees);

    // find the northmost, southmost, eastmost and westmost corners $distance_in_miles away
    // original formula from
    // http://www.movable-type.co.uk/scripts/latlong.html

    $northmost  = asin(sin($lat_r) * cos($distance_in_miles/$radius) + cos($lat_r) * sin ($distance_in_miles/$radius) * cos($due_north));
    $southmost  = asin(sin($lat_r) * cos($distance_in_miles/$radius) + cos($lat_r) * sin ($distance_in_miles/$radius) * cos($due_south));

    $eastmost = $lon_r + atan2(sin($due_east)*sin($distance_in_miles/$radius)*cos($lat_r),cos($distance_in_miles/$radius)-sin($lat_r)*sin($lat_r));
    $westmost = $lon_r + atan2(sin($due_west)*sin($distance_in_miles/$radius)*cos($lat_r),cos($distance_in_miles/$radius)-sin($lat_r)*sin($lat_r));


    $northmost = rad2deg($northmost);
    $southmost = rad2deg($southmost);
    $eastmost = rad2deg($eastmost);
    $westmost = rad2deg($westmost);

    // sort the lat and long so that we can use them for a between query        
    if ($northmost > $southmost) { 
        $lat1 = $southmost;
        $lat2 = $northmost;

    } else {
        $lat1 = $northmost;
        $lat2 = $southmost;
    }


    if ($eastmost > $westmost) { 
        $lon1 = $westmost;
        $lon2 = $eastmost;

    } else {
        $lon1 = $eastmost;
        $lon2 = $westmost;
    }

    return array($northmost, $southmost, $eastmost, $westmost);
}

The Query

I setup a query to search the data looking for locations within the bounds of the co-ordinates I had grabbed from the search box in the previous step. I saved those co-ordinates in an erray $distance_box. Here are the query arguments I used.

$args = array(
	'post_type'	=> 'location',
	'post_status' => 'publish',	
	
	'meta_query'	=> array(
		 'relation' => 'AND', 
		
		array(
			'key'		=> 'xxx_latitude',
		
			'value'		=> array($distance_box[1]),
			'compare'	=> '>=',
			'type' => 'NUMERIC',
		),
		
				array(
			'key'		=> 'xxx_latitude',
			'value'		=> array($distance_box[0]),
			'compare'	=> '<=',
			'type' => 'NUMERIC',
		),
		
		
		array(
			'key'		=> 'xxx_longitude',
		
			'value'		=> array($distance_box[2]),
			'compare'	=> '<=',
			'type' => 'NUMERIC',
		),
		
				array(
			'key'		=> 'xxx_longitude',
			'value'		=> array($distance_box[3]),
			'compare'	=> '>=',
			'type' => 'NUMERIC',
		),
		
		
	)	
		
	
);

Video Demo

Here’s what it looks like on the front end.

Wrap Up – Radius Search ACF Google Map Field

So here’s my case study on how to search ACF google map fields via a 100 mile radius.

If you need help implementing Google maps on your site please get in touch.

Photo by José Martín Ramírez Carrasco on Unsplash

Article by GeneratePress

Lorem ipsum amet elit morbi dolor tortor. Vivamus eget mollis nostra ullam corper pharetra torquent auctor metus. Natoque tellus semper taciti nostra primis lectus donec tortor semper habitant taciti primis tempor montes.