1

I've been using Google geocoding v3 for about 6 months but all of a sudden it's stopped working (I get a 610 error). It's only stopped in the last week or so.

Then I came across this (see the pink box at the top of the page!): https://developers.google.com/maps/documentation/geocoding/v2/

I've read through all the documentation and not sure where to start!

I'm hoping it's a small change as it's taken a long time to get this far, can anyone help?

[See the full site here][1]


UPDATE:

require("database.php");
// Opens a connection to a MySQL server
$con = mysql_connect("localhost", $username, $password);

if (!$con)
{
    die('Could not connect: ' . mysql_error());
}

mysql_select_db("teamwork_poh", $con);


    $company = get_the_title();
    $address = get_field('address_line_1');
    $city = get_field('town_/_city');
    $post_code = get_field('post_code');
    $link = get_permalink();
    $type = get_field('kind_of_organisation');

    $sql = sprintf("select count('x') as cnt from markers where `name` = '%s'", mysql_real_escape_string($company));
    $row_dup = mysql_fetch_assoc(mysql_query($sql,$con));
    if ($row_dup['cnt'] == 0) {
        mysql_query("INSERT INTO markers (`name`, `address`, `lat`, `lng`, `type`, `link`) VALUES ('".$company."', '".$address.", ".$city.", ".$post_code."', '0.0', '0.0', '".$type."', '".$link."')");
    }
wp_reset_query();

require("database.php");

define("MAPS_HOST", "maps.googleapis.com");
define("KEY", "(my key)");

// Opens a connection to a MySQL server
$connection = mysql_connect("localhost", $username, $password);
if (!$connection) {
  die("Not connected : " . mysql_error());
}

// Set the active MySQL database
$db_selected = mysql_select_db($database, $connection);
if (!$db_selected) {
  die("Can\'t use db : " . mysql_error());
}

$query = "SELECT * FROM markers WHERE 1";
$result = mysql_query($query);
if (!$result) {
  die("Invalid query: " . mysql_error());
}

//Initialize delay in geocode speed

$delay=0;
$base_url = "http://" . MAPS_HOST . "/maps/api/geocode/json?address=";

while ($row = @mysql_fetch_assoc($result)) {
    if (!($row['lat'] * 1)) {
        $geocode_pending = true;

    while ($geocode_pending){

    $address = $row["address"];
    $id = $row["id"];

    $request_url = $base_url . "" . urlencode($address) ."&sensor=false";

    sleep(0.1);

$json = file_get_contents($request_url);
$json_decoded = json_decode($json);

$status = $json_decoded->status;

 if (strcmp($json_decoded->status, "OK") == 0) {

$geocode_pending = false;

      $lat = $json_decoded->results[0]->geometry->location->lat;
      $lng = $json_decoded->results[0]->geometry->location->lng;

// echo 'here';

      $query = sprintf("UPDATE markers " .
             " SET lat = '%s', lng = '%s' " .
             " WHERE id = '%s' LIMIT 1;",
             mysql_real_escape_string($lat),
             mysql_real_escape_string($lng),
             mysql_real_escape_string($id));
      $update_result = mysql_query($query);

      echo $id;

      if (!$update_result) {
        die("Invalid query: " . mysql_error());
      }
    }

   else {
 // failure to geocode
      $geocode_pending = false;
      echo "Address " . $address . " failed to geocode. ";
      echo "Received status " . $status . "\n";
    }

  //  usleep($delay);

    }
}

}
Rob
  • 6,304
  • 24
  • 83
  • 189
  • What exactly is the problem (or more specifically, what's your question)? I go to your site, I see a map... – duncan Mar 15 '13 at 10:51
  • @duncan It's no longer plotting markers via geocoding. It stopped working as per the google link on 8th March but can't work out what to change to get it to geocode markers again. – Rob Mar 15 '13 at 10:54
  • Check http://stackoverflow.com/a/15289007/2110460 for more information and links to guides for updating – Rafe Mar 15 '13 at 11:31
  • @Rafe Thanks, I came across that but can't work out where mine is going wrong. I've tried changing the url (see update in question) but that doesn't affect it, any ideas? – Rob Mar 15 '13 at 11:32
  • Forget about the map generation at the moment. Have you checked your xml? And are you sure you want to continue using xml rather than switching to json? – Rafe Mar 15 '13 at 11:38
  • @Rafe Yes xml is the way we need to move forward for various other reasons. So where it's building the xml, are the nodes incorrectly named now? – Rob Mar 15 '13 at 11:46
  • Sorry, maybe I didn't make myself clear. If you put the address for your xml doc into a web browser, does it give a valid response? Do you get the xml doc. Web browsers can parse xml docs fine so it's an easy check. – Rafe Mar 15 '13 at 11:50
  • @Rafe I'm going to this address - http://www.teamworksdesign.com/clients/poh/wp-content/themes/default/phpsqlajax_genxml.php and it appears to be working but not doing the lat/long correctly. – Rob Mar 15 '13 at 12:02
  • Check your database values – david strachan Mar 15 '13 at 12:13
  • @davidstrachan The lat/long in the database should've been geocoded but that part isn't working so it got entered in as 0 & 0. – Rob Mar 15 '13 at 12:15
  • Your base_url setting is completely wrong for v3. It should match "http://maps.googleapis.com/maps/api/geocode/xml?address=" Notice how there is no 'geo' or output definition? I just tried geocoding the address in your xml feed and it worked fine with that address format. – Rafe Mar 15 '13 at 12:21
  • @Rafe I've just updated my question, I thought the same but it still won't geocode the address. – Rob Mar 15 '13 at 13:18
  • I've been there and all I can say that it IS a lot of work and probably nothing to work around it. Good luck! – slawekwin Mar 15 '13 at 13:24
  • @slawekwin Are we going in the right direction with the url? – Rob Mar 15 '13 at 13:31
  • Ok, you have "$coordinates = $xml->Response->Placemark->Point->coordinates" in your code which doesn't seem to tie up with any of the xml path supplied by the geocoding. Have a look at http://maps.googleapis.com/maps/api/geocode/xml?address=Royal+Greenwich+Observatory,+Royal+Borough+of+Greenwich&sensor=false and you will see the path structure. – Rafe Mar 15 '13 at 13:43
  • @Rafe Thanks for all the help by the way. In a few comments up, you mentioned you ran an address through my url - how did you actually do that? – Rob Mar 15 '13 at 13:46
  • I used the same method as I just showed with the Royal Observatory link above. I try to stay away from using real data in comments. – Rafe Mar 15 '13 at 13:52
  • I just noticed... you are not putting the sensor on the end of the address. You need that sensor data either before or after the address or it will not return a result. – Rafe Mar 15 '13 at 13:55
  • @Rafe I just tried the following: `define("MAPS_HOST", "maps.googleapis.com"); $base_url = "http://" . MAPS_HOST . "/maps/api/geocode/xml?"; $request_url = $base_url . "address=" . urlencode($address) . "&sensor=false&Key=" . KEY;` Still no luck! – Rob Mar 15 '13 at 14:02
  • @Rafe I've created a bounty so you might want to put a real answer just in case it works. – Rob Mar 17 '13 at 12:18

2 Answers2

4

As you are storing the coordinates in database it would be best to geocode when you insert new record. ie

require("dbinfo.php");//Your database parameters
//Connect to database
$dbh = new PDO("mysql:host=$host;dbname=$database", $username, $password);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
try {
    //Prepare query
    $name = "%".$company."%";//Wildcard for PDO paramerter
    $countSql = "SELECT COUNT(*) FROM markers WHERE `name` LIKE ?"; 
    $countStmt = $dbh->prepare($countSql);
    // Assign parameter
    $countStmt->bindParam(1,$name);
    //Execute query
    $countStmt->execute();  
    // check the row count  
    if ($countStmt->fetchColumn() == 0) { #1 EDIT changed >0 to ==0
        echo "No row matched the query."; //EDIT  From Row
        $q =$address.','.$city.','.$post_code.',UK'; 
        echo "\n";
        $base_url = "http://maps.googleapis.com/maps/api/geocode/xml?address=";
        $request_url = $base_url.urlencode($q)."&sensor=false";
        $xml = simplexml_load_file($request_url) or die("url not loading");
        if($xml->status=="OK"){#2
            // Successful geocode
            $lat = $xml->result->geometry->location->lat;
            $lng = $xml->result->geometry->location->lng; 
            $insertSql ="INSERT INTO markers (`name`, `address`, `lat`, `lng`, `type`, `link`) VALUES (?,?,?,?,?,?)";
            $insertStmt = $dbh->prepare($insertSql);
            // Assign parameter
            $insertStmt->bindParam(1,$company);
            $insertStmt->bindParam(2,$address); 
            $insertStmt->bindParam(3,$lat);
            $insertStmt->bindParam(4,$lng);
            $insertStmt->bindParam(5,$type);
            $insertStmt->bindParam(6,$link);
            //Execute query
            $insertStmt->execute();
        } #2
        else{
            "No rows inserted."; 
        }#2
    } #1
    else {#1
    echo "Rows matched the query."; //EDIT From No row
    } #1 
}// End try 


catch(PDOException $e) {
    echo "I'm sorry I'm afraid you can't do that.". $e->getMessage() ;// Remove or modify after testing 
    file_put_contents('PDOErrors.txt',date('[Y-m-d H:i:s]').", myFile.php, ". $e->getMessage()."\r\n", FILE_APPEND);  
 }

I have converted your code to PDO as it is advisable to stop using mysql_functions as these a deprecated.

I have left you to implement how you will deal with geocoding not returning coordinates. You can also check and deal with the following status codes

OVER_QUERY_LIMIT

ZERO_RESULTS

REQUEST_DENIED

INVALID_REQUEST

See pastebin For status code implementation

david strachan
  • 7,174
  • 2
  • 23
  • 33
  • @Rob I have updated the code to PDO as I no longer use mysql_ functions and it was easier to modify my code to suit your requirements.The code works – david strachan Mar 17 '13 at 15:35
  • @Rob There is an error in the code I will change it in answer. As you have a problem with over limit I have made additions to code and pasted it in [patebin](http://pastebin.com/NVyC8xSA) – david strachan Mar 19 '13 at 14:39
  • Ahhhhhhhhh got it! It was my other code clashing with it, it was creating the marker then your code was doing the same but geocoding it so they clashed. I'll give it a few more tests but it looks like its worked. Thanks very much for the patience!! – Rob Mar 19 '13 at 15:00
  • If you look at pastebin you will see I have added how to deal with status codes .The action you take is dependant on your application – david strachan Mar 19 '13 at 15:03
  • Ok, brilliant. Just to clear up my understanding of whats happening, it's taking the address, checking the name is unique, geocoding it, then saving the result in the database. At the moment it only takes line 1 of the address, for accuracy should I include line 2 and the county? Would that give it more accuracy and more chance of plotting? Last question - the whole process makes 1 geocode request? – Rob Mar 19 '13 at 15:09
  • @Rob The more details in the query improves the accuracy. The trouble arises if you want to limit the search to one country it will always return coordinates even if the other parameters would return zero results. – david strachan Mar 19 '13 at 15:32
  • @Rob does the answer provide what you require – david strachan Mar 20 '13 at 11:49
2

Going by our earlier comments, there are just a couple of changes required that should get you back on your feet.

These are, changing the address for v3 geocoding

define("MAPS_HOST", "maps.googleapis.com");
$base_url = "http://" . MAPS_HOST . "/maps/api/geocode/xml?";
$request_url = $base_url . "address=" . urlencode($address) . "&sensor=false";

And secondly changing the path in the returned xml file for setting lat/long

$coordinates = $xml->Response->Placemark->Point->coordinates;
$coordinatesSplit = split(",", $coordinates);
// Format: Longitude, Latitude, Altitude
$lat = $coordinatesSplit[1];
$lng = $coordinatesSplit[0];

Can be completely replaced with

$lat = $xml->result->geometry->location->lat;
$lng = $xml->result->geometry->location->lng;

The next piece about stopping it from going over geocoding limits. What you need to do is set a simple check before you run through the geocoding.

while ($row = @mysql_fetch_assoc($result)) {
    if (!($row['lat'] * 1)) {// add this line
        $geocode_pending = true;
            while ($geocode_pending){
                //do geocoding stuff
            }
        }
    }// add this close
}
Rafe
  • 793
  • 6
  • 15
  • Just a quick question (thanks for the answer, it solved the initial problem) - I'm now hitting the geocoding query limit, only because it's trying to geocode all 130 addresses each and every time. The solution is to geocode the address when it gets entered into the database but not sure how to do this. I've tried David's answer but no luck, is there any alternatives? – Rob Mar 19 '13 at 09:52
  • I thought you had a new question for this. The simple answer is to do a check just before your $geocode_pending = true; to see if the lat and lng are already set. If they are not, then run the code, if they are, then skip it. – Rafe Mar 19 '13 at 10:27
  • I got told to keep this question going. Any chance for a code example, it's now gone over my head. Bounty's yours then! – Rob Mar 19 '13 at 10:33
  • That update should do the trick. I made it so it checks for any combination of numeric 0 or string "0.0". You may want to tweek it if it does not suit your needs/coding practices. – Rafe Mar 19 '13 at 12:44
  • Ok thanks, I'm still currently over the query limit. How long does it take to clear that? I guess I'll know if it worked once that's gone. The marker went into the database with zero lat/lng. – Rob Mar 19 '13 at 12:59
  • Your geocoding 'was' doing an update in the geocoding piece which set the lat and lng after getting the relative pieces of information. You must have that update happening or the check will always return false and the geocoding will happen again. – Rafe Mar 19 '13 at 13:04
  • I've updated my question with what I did just to make sure I haven't done something stupid! – Rob Mar 19 '13 at 13:09
  • To be honest, the number of times you have run that geocoding and update piece, there should not be a 0 lat or long left! – Rafe Mar 19 '13 at 13:31