Extract lat longs from a string with other text

So one of our website was built to use map points and rather than putting the lat/longs in a nice CSV array so i could split them out and use for any map system, they were put in a field with the code specifically for Openmap.

eg GEOMETRYCOLLECTION(POINT(-5.4317736623495 50.195116418422, -7.431773495 58.195176518422))

This is a major pain as there isn’t even commas between the lat/longs only between the different sets of points. So i can trim the first bit off because it is a known length for all entries

eg -5.4317736623495 50.195116418422, -7.431773495 58.195176518422))

But i am now stuck as i need to get the numbers up until the whitespace and then the second value from the whitespace to the comma (i only need the first set of lat/longs for now).

I can’t just trim a specific distance as the first number is not consistant in length.

I thought i’d cracked it with

function extract_numbers($string)
preg_match_all('/([\\d]+)/', $string, $match);

return $match[0];

$string = 'GEOMETRYCOLLECTION(POINT(-5.4317736623495 50.195116418422))';

$numbers_array = extract_numbers($string);

echo 'Lat =  -'.$numbers_array[0].'.'.$numbers_array[1];
echo '<br>';
echo 'Lon =  '.$numbers_array[2].'.'.$numbers_array[3];

But this removes the minus sign. So i hard coded it back in but then realised that some of the lat/lons should have a minus and some don’t so my map points are all over the shop. It also removed the decimal place so i had to add that back in.

Any suggestions how to do this?

many thanks

Should be simple enough to use explode() to break it up into the appropriate chunks

awesome thanks …

$str = substr("GEOMETRYCOLLECTION(POINT(-5.4317736623495 50.195116418422, -7.431773495 58.195176518422))", 25);
print_r (explode(" ",$str));

simple when you know how :slight_smile:

edit - just realised the comma is still there so will have to add a bit more code to remove that.

so final code looks like this

$str = str_replace(",","",substr("GEOMETRYCOLLECTION(POINT(-5.4317736623495 50.195116418422, -7.431773495 58.195176518422))", 25));
$array = (explode(" ",$str));
print_r (explode(" ",$str));

//echo $array[2];

Pretty sure it would have been a lot easier if it had just been a comma separated array!

thanks for your help. saved me a lot of time.

Looks good! Much cleaner now too.

this decided to fight me all the way. So the above code would have worked but i then ran into 2 more problems.

So some of the data begins ‘GEOMETRYCOLLECTION(LINESTRING(…’ and some of the data begins ‘GEOMETRYCOLLECTION(POINT(…’

So i have to cut away different lengths depending on the string.

Second problem is that some of the data was input as (…lat long, lat long…) N.B there is a space between the first and second set and some was set as (…lat long,lat long…) which doens’t have space so explode didn’t split it up. So i had to add some more code to catch that.

So this is now what i had to do (probably much better and cleaner way but this works for what i need)

$string =  $row_geo['field_beach_geocoder_openlayers_wkt']; //this is from the database

$str = trim($string); //to get rid of any leading whitespace

//we need to check if it contains point or single
if (preg_match('/point/i',$str)){
	$str = substr($str, 25);
elseif (preg_match('/line/i',$str)){
	$str = substr($str, 30);

//now i can explode
$array = (explode(" ",$str));
//print_r (explode(" ",$str));

//almost but not quite
$array1 = preg_replace("/,.*/", "", $array[1]); //there is a comma kicking around i need to get rid of
$array1 = preg_replace("/\\).*/", "", $array[1]); //there is a final bracket on some shorter entries to get rid of too

 //finally get lat long
$lng =  $array[0];
$lat =  $array1;

//yay i can update my table

that was not so much fun! wish it was csv!

Just to verify, I had assumed that GEOMETRYCOLLECTION(POINT()) will only contain four coordinates ( lat and long for two different locations ) at any given time…is that correct?

Nevermind, I see after I reread everything. If you want to clean it up a little, you can always use FILTER_SANITIZE_NUMBER_FLOAT; otherwise, if you’re happy with it now and it works, you’re good to go!