I have following problem. I'm using google maps in php to get the address of latitude and longitude and a map snapshot of this location.
To obtain address I use following code:
// INITIALIZING CURL
$returnValue = NULL;
$ch = curl_init();
// SERVICE CALL
$url = "http://maps.googleapis.com/maps/api/geocode/json?latlng=".$lat.",".$lon."&sensor=false";
// SETTING PARAMS OF CURL
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
// GETTING AND RESULTING RESULT
$result_part = curl_exec($ch);
$json = json_decode($result_part, TRUE);
And I parse obtained JSON as follows:
// PARSING RESULTS FROM JSON
if (isset($json['results'])) {
foreach ($json['results'] as $result_part) {
foreach ($result_part['address_components'] as $address_component) {
$types = $address_component['types'];
// GETTING STREET
if (in_array('route', $types)) {
$addr = $address_component['long_name'];
}
// GETTING STREET NUMBER
if (in_array('street_number', $types)) {
$number = $address_component['long_name'];
}
// GETTING COUNTRY
if (in_array('country', $types)) {
$country = $address_component['long_name'];
}
// GETTING POSTAL CODE
if (in_array('postal_code', $types)) {
$postal_code = $address_component['long_name'];
}
// GETTING CITY
if (in_array('locality', $types)) {
$city = $address_component['long_name'];
}
}
}
}
It works fine but sometimes the address is not obtained. It looks like some overload of requests but I dont understand why because the site that I'm programming is not accessible yet for other people.
Other problem connected to this is the map snapshots. Here is the code:
<? echo "<a href = \"https://maps.google.com/maps?q=".$lat.",".$lon."\" target=\"_blank\">" ?>
<? echo "<img src=\"http://maps.googleapis.com/maps/api/staticmap?center=" . $lat . "," . $lon . "&zoom=16&size=200x200&markers=color:blue%7Clabel:I%7C" . $lat . "," . $lon . "&sensor=false\" alt=\"google maps\" width=\"200\" height=\"200\" /></a>" ?>
This works also fine but sometimes I obtain image like this:
I doubt that I exceeded the limit.
Any ideas ? Thank you for your answers.
As #geocodezip has suggested it could be because of not using a key.
Also as per the reverse geocoding documentation on :
https://developers.google.com/maps/documentation/geocoding/#ReverseGeocoding
Note: Reverse geocoding is an estimate. The geocoder will attempt to find the closest addressable location within a certain tolerance; if no match is found, the geocoder will return zero results.
Related
I have a "users" table with columns:
Id | user_id | name | ip_address | lat | lng
The id column, user_id, name and ip_address have been populated, and now have 100k users.
The lat (latitude) and lng (longitude) columns have now been created, and I need them populated from the IP (you can not get the geolocation of the user).
I do not want precise location, just the approximate location, so what I need is a script that picks up the IP of each user, somehow extracts the latitude and longitude, and inserts into the database.
I have looked at "http://www.geoplugin.net/xml.gp?ip=" and "http://ip-api.com/json/" but I have no idea how to use api for 100k of users, nor PHP or mysql code, or shell to do this.
I am using only PHP, MySQLi with MySQL database. The application will display a list of users "nearby" (within a 100miles radius).
Excuse me, I'm very new to programming and I really do not know how to solve this.
Edit:
I just created an api that returns me all user_id and their respective IPs in an array.
Just being 105k of records, for being json, it was light but I did not want to share json publicly here because it would be the same as explaining my users' data.
the result of api is something like this:
{
"api_status": 200,
"ips": [
{
"user_id": "1",
"ip_address": "177.198.86.7x"
},
{
"user_id": "21",
"ip_address": "177.18.246.9x"
},
{
"user_id": "52",
"ip_address": "177.36.60.1x"
}
]
}
I am using the following function to return my data in php
function List_ip() {
global $sqlConnect, $db;
if ($db['loggedin'] == false) {
return false;
}
$ips = mysqli_query($sqlConnect, "SELECT `user_id` , `ip_address` FROM " . T_USERS . " WHERE `active` = '1'");
while ($fetched_data = mysqli_fetch_assoc($ips)) {
$list_ip[] = array_map('utf8_encode', $fetched_data);
}
return $list_ip;
}
I don't have much idea about limiting the number of requests, but try the below code to get the details from ip-api.
$url = "http://ip-api.com/batch";
$headers = array('Content-Type: application/json');
$fields = '[{"query": "208.80.152.201"}, // You can add multiple IP address in the same format.
{"query": "8.8.8.8"},
{"query": "24.48.0.1"}]';
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_POSTFIELDS, $fields);
$httpCode = curl_getinfo($curl , CURLINFO_HTTP_CODE);
$response = curl_exec($curl);
if ($response === false)
$response = curl_error($curl);
foreach(json_decode($response) as $value){
echo $value->lat; //Use the result to store the information in DB
}
curl_close($curl);
Refer their documentation to get an idea about the data returned by their API.
Also, for limiting, try this solution
The maxmind/GeoIP2-php should get you want you need.
Install it and download the GeoIP2-City.mmdb file.
Than just a matter of initiating it:
$record = new Reader('path/to/GeoLite2-City.mmdb');
and reading the data from it, such as:
$city = $record->city->name;
$latitude = $record->location->latitude;
$longitude = $record->location->longitude;
Doing it this way will mean zero dependency on third-party API limitations.
What you are asking for requires intermediate skills with PHP and MySQL etc.. I have done many things like this, and will tell you that firstly to get accurate GEO IP information you will have to use javascript or pay for a service (from my findings). For example www.maxmind.com has a free and pay, the pay is a bit better.
What I would do is try writing a script that reads all of the users out of the database in a loop, then download geopip or use an api to take the IP fields and return the Lat/Lon. Then finally add the step that writes it back to the DB .
A very rough example:
// build a class or function that looks up IP addresses (can be local)
$geoip2 = new GeoIp2Lookup(true);
// get all users from DB
$allUsersArray = function_results_db_lookup_users();
// get the users lat/lon
for ($i=0; $i<count($allUsersArray); $i++) {
$record = $geoip2->getGeoDataArr($allUsersArray[$i]['ip_address']);
$allUsersArray[$i]['lat'] = $record['lat'];
$allUsersArray[$i]['lon'] = $record['lon'];
}
// now write a function to place in DB the new data
update_users_db($allUsersArray);
You can easily use the IP2Location PHP Module at https://www.ip2location.com/development-libraries/ip2location/php which is free.
To install, add the below line into your composer.json file.
{
"require": {
"ip2location/ip2location-php": "8.*"
}
}
Run the command:
composer install
Note: You just need to include the below code in order to use the library.
require 'vendor/autoload.php';
You'll need the DB5.LITE database which you can download for free at https://lite.ip2location.com/
Example usage of the PHP module
<?php
require 'IP2Location.php';
$myip = '8.8.8.8';
$db = new \IP2Location\Database('./database/IP-COUNTRY-SAMPLE.BIN', \IP2Location\Database::FILE_IO);
$records = $db->lookup($myip, \IP2Location\Database::ALL);
echo '<pre>';
echo 'IP Address : ' . $records['ipAddress'] . "\n";
echo 'Country Code : ' . $records['countryCode'] . "\n";
echo 'Country Name : ' . $records['countryName'] . "\n";
echo 'Region Name : ' . $records['regionName'] . "\n";
echo 'City Name : ' . $records['cityName'] . "\n";
echo 'Latitude : ' . $records['latitude'] . "\n";
echo 'Longitude : ' . $records['longitude'] . "\n";
echo '</pre>';
?>
Today i have some php cURL code that must show to user his loacation like: ip, country, city it have.. And if the user is bot - do nothing. So, i do it like this, but it's not working properly. Only ip is shown and nothing else.. Please help.. And let the power be with you.. Thank to all for help.
<?php
$ip = $_SERVER['REMOTE_ADDR'];
$apiurl = "https://api.2ip.ua/geo.json?ip=$ip";
//--
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "$apiurl");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$contents = curl_exec ($ch);
//--
curl_close ($ch);
//- **************-//
$pieces = explode('"', $contents);
$country = $pieces['7'];
$city = $pieces['11'];
$city2 = $pieces['13'];
echo "Your IP is :" . $ip . " and country " .$country. " and city " .$city;
?>
Don't use explode!, the answer of the api is a JSON, instead you got to do this:
$data = json_decode($contents, true);
$country = $data['country'];
$city = $data['city'];
and so on for any other field you need.
BTW you can also improve the IP detection with this code that support multiple detection with ipv4 and ipv6 support
if (isset($_SERVER['REMOTE_HOST'])) {
$ip = $_SERVER['REMOTE_HOST'];
} elseif (isset($_SERVER['HOST'])) {
$ip = $_SERVER['HOST'];
} elseif (isset($_SERVER['REMOTE_ADDR'])) {
$ip = $_SERVER['REMOTE_ADDR'];
} else {
$host = '';
}
$ip = str_replace("::ffff:","",$ip);//::ffff:127.127.127.127 en caso de jugo ipv6
Regards and vote up
First, don't use explode, use json_decode instead and then there is something wrong with the SSL-Certificate of your API so use http instead.
<?php
$ip = $_SERVER['REMOTE_ADDR'];
$apiurl = "http://api.2ip.ua/geo.json?ip=";
$contents = file_get_contents($apiurl . $ip);
$json = json_decode($contents);
$country = $json->country;
$city = $json->city;
echo "Your IP is :" . $ip . " and country " . $country . " and city " . $city;
I previously had a Google geocoding script working to extract longitude and latitude using local addresses in a database.
In the last 6 months I've switched hosts, and apparently Google has implemented a new forward geocoder. Now it just returns the url not loading error from the xml script call.
I've tried everything to get my code working. Even sample coding from other websites won't work on my server. What am I missing? Is there possibly a server side setting that is blocking this from executing properly?
Attempt # 1:
$request_url = "http://maps.googleapis.com/maps/api/geocode/xml?new_forward_geocoder=true&address=1600+Amphitheatre+Parkway,+Mountain+View,+CA";
echo $request_url;
$xml = simplexml_load_file($request_url) or die("url not loading");
$status = $xml->status;
return $status;
Simply returns url not loading. I have tried with and without the new_forwad_geocoder. I have also tried with and without https.
The $request_url string DOES return proper results if you simply copy and paste it to a browser.
Also tried this just to see if I could get a file to return. Attempt 2:
$request_url = "http://maps.googleapis.com/maps/api/geocode/json?new_forward_geocoder=true&address=1600+Amphitheatre+Parkway,+Mountain+View,+CA";//&sensor=true
echo $request_url."<br>";
$tmp = file_get_contents($request_url);
echo $tmp;
Any idea what could be causing the connection failure?
I wasn't ever able to get this working with XML again and the file_get_contents call was the culprit I'm almost positive.
I've posted what I did get to work with JSON/Curl (below) in case anyone has similar issues.
Ultimately I think the problems I ran into had to do with an upgrade to our Apache version on the server; and some of the default settings related to file_get_contents and fopen being more restrictive. I haven't confirmed this though.
This code does work though:
class geocoder{
static private $url = "http://maps.google.com/maps/api/geocode/json?sensor=false&address=";
static public function getLocation($address){
$url = self::$url.$address;
$resp_json = self::curl_file_get_contents($url);
$resp = json_decode($resp_json, true);
//var_dump($resp);
if($resp['status']='OK'){
//var_dump($resp['results'][0]['geometry']['location']);
//echo "<br>";
//var_dump($resp['results'][0]['geometry']['location_type']);
//echo "<br>";
//var_dump($resp['results'][0]['place_id']);
return array ($resp['results'][0]['geometry']['location'], $resp['results'][0]['geometry']['location_type'], $resp['results'][0]['place_id']);
}else{
return false;
}
}
static private function curl_file_get_contents($URL){
$c = curl_init();
curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($c, CURLOPT_URL, $URL);
$contents = curl_exec($c);
curl_close($c);
if ($contents) return $contents;
else return FALSE;
}
}
$Address = "1600 Amphitheatre Parkway, Mountain View, CA";
$Address = urlencode(trim($Address));
list ($loc, $type, $place_id) = geocoder::getLocation($Address);
//var_dump($loc);
$lat = $loc["lat"];
$lng = $loc["lng"];
echo "<br><br> Address: ".$Address;
echo "<br>Lat: ".$lat;
echo "<br>Lon: ".$lng;
echo "<br>Location: ".$type;
echo "<br>Place ID: ".$place_id;
I am working on a little project for a programming course here on my university. It involves getting data from the google api (JSON) and providing some of that information to the user.
function compare($city, $start, $destination)
{
// merge city with start and destination
$city_start = $start . ', ' . $city;
$city_destination = $destination . ', ' . $city;
// reject symbols that start with ^
if (preg_match("/^\^/", $city) OR preg_match("/^\^/", $start) OR preg_match("/^\^/", $destination))
{
return false;
}
// reject symbols that contain commas
if (preg_match("/,/", $city) OR preg_match("/,/", $start) OR preg_match("/,/", $city))
{
return false;
}
// determine url
$url = "http://maps.googleapis.com/maps/api/directions/json?origin=$city_start&destination=$city_destination&sensor=false&mode=bicycling";
echo $url;
// open connection to google maps
$curl_session = curl_init($url);
curl_setopt($curl_session, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl_session, CURLOPT_HEADER, 0);
// get data from json output
$json = curl_exec($curl_session);
curl_close($curl_session);
var_dump($json);
}
The above code returns a 400 error at var_dump, where $city, $start and $destination are respectively starting adress, destination adress and the city where the addresses belong to. The url stored in $url works alright and returns JSON output when entered in a browser.
Can anyone tell me what I am doing wrong?
Cheers,
D.
You could try and urlencode the variables:
$city_start = urlencode($start . ', ' . $city);
$city_destination = urlencode($destination . ', ' . $city);
I'm new to PHP, and I want to get latitude and longitude of a place and then add them to MySQL database.
I'm using Google Geo-code API to get them, this is what I do right-row
for ($i = 0; $i<1000; $i++) {
$sql = mysql_query("SELECT place_address FROM place_locator WHERE place_id =".$i, $this->db) or die('invalide request : ' . mysql_error());
if (mysql_num_rows($sql)) {
while ($place = mysql_fetch_assoc($sql)) {
//Encode the place string I got, to get rid of space
$encodePlace = str_replace(" ", "%20", $place["place_address"]);
//Use Google API
$url = 'http://maps.googleapis.com/maps/api/geocode/json?address='.$encodePlace.'&sensor=false';
//Use Curl to send the request
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response = curl_exec($ch);
$obj = json_decode($response, true);
$updateSql = mysql_query("UPDATE `place_locator`.`place_locator` SET
`latitude` = '".$obj["results"][0]["geometry"]["location"]["lat"]."',
`longitude` = '".$obj["results"][0]["geometry"]["location"]["lng"]."' WHERE `place_locator`.`place_id` = ".$i, $this->db) or die('Invalide : ' . mysql_error());
curl_close($ch);
}
}
It works for a loop of 10,when going to 1000, it will take a lot of time and many results didn't updated to the database.
I think may be multi thread should help, but I don't really know how it works, please help me.
Thanks in advance
I had the same problem. Google limits the frequency of the requests! Try a sleep(1); in the loop and it will work but need much more time.