Currently,I have created a page showing all the locations of the users (all from MySQL database) on google map. But because there are 5000+ user locations, it takes a long time to load the page.
I would like to make it more efficiently by only querying the user locations within certain area. (the area I am viewing)
What could I do to make it more efficient? Does google maps API support the feature that I want? I heard I can do geofencing mysql, but I cannot really find how to use it.
Thank you in advance.
There are probably many ways to do what you want. If you have the longitude and latitude of the users (which sounds like you do) then instead of loading all user locations (select latitude, longitude from users) then narrow down the location by specifying a range for the coordinates of your user, so your select looks something like this (in pseudo query)
select latitude, longitude from users where latitude between (user.latitude + whateverrangeyouwant and user.latitude - whateverrangeyouwant) AND longitude between (user.longitude + whateverrangeyouwant AND user.longitude - whateverrangeyouwant);
The range can probably be taken from the map.bounds property
You can then send this back to your script using a service that will then remove the markers from the map and add the one ones based on your service response. So your javascript would look something like this (in pseudo code)
get user location;
send service request for user locations and get them back in an array
remove current markers
add new markers from service result
The service in PHP probably look something like this:
$minLat = $_REQUEST['lat'] - ($_REQUEST['dl'] / 2);
$maxLat = $_REQUEST['lat'] + ($_REQUEST['dl'] / 2);
$minLon = $_REQUEST['lon'] - $_REQUEST['dln'];
$maxLon = $_REQUEST['lon'] + $_REQUEST['dln'];
$query = 'SELECT locations.latitude,
locations.longitude
FROM locations
WHERE (latitude BETWEEN ' . $minLat . ' AND ' . $maxLat . ') AND
(longitude BETWEEN ' . $minLon . ' AND ' . $maxLon. ')';
}
$query = DB::query($query);
$json = array();
while($location = $query->fetch_assoc()) {
$json[] = $location;
}
header('Content-Type: application/json');
echo json_encode($json);
exit();
Hope that helps.
Related
I am using Google Autocomplete (under Maps Javascript API) in Angular 5.
For the purpose of my website, I retrieve details of a place, which includes any available photos. For the photos, I will get the photo URL via the getURL() method.
============
What works previously
Previously, I am able to save the url in the database and use that same url to retrieve the photos at a later date. Example of the URLs includes:
https://lh3.googleusercontent.com/p/AF1QipM3QnVu-6W-ZtoTry29MOzDt7vpWzPZAPZbBfqZ=w600-h500-k
https://lh3.googleusercontent.com/p/AF1QipPQ5imb4nzfK1TxG7KAFx2vEx1SoYXeQApA6SVX=w600-h500-k
https://lh4.googleusercontent.com/-l_W16EbIqzk/WS5E5R9_VbI/AAAAAAAAnD8/ajWr1IeY7solMudnxIV21vjqmxLt8CJOACLIB/w300-h250-k
============
Situation now
However, in recent weeks, the same getURL() method returns photos that expire. I have no problem seeing the photo when I first retrieved it. As usual, I save the url to my database. However, after a few days, I am unable to retrieve the same images. Example includes:
https://maps.googleapis.com/maps/api/place/js/PhotoService.GetPhoto?1sCmRaAAAAiEX-USwjAvitgPnxuaW7stCrTkQMxyydpcmlg5IrEWnSUS5D3Z2D9evQ_n41Ght-8dr3cZtjvx4oINIEpqj4Z4fvaCyqv6xF0oPC_lw88P6FUQ7SXP2vElr61Zi568IdEhBWY_7xGFNHvdQyDqxZApR3GhS-IM17Pp8oMGlMK0FrXW310tsPCw&3u2000&4u1000&5m1&2e1&key=AIzaSyAbdivx4G0igYO5yr3vTUJcQF5s8lTdXho&callback=none&token=96678
https://maps.googleapis.com/maps/api/place/js/PhotoService.GetPhoto?1sCmRaAAAAkz5xG6DVQSbwHyBIQIshs2FedNARq6oG0Ea6gUxvljPdnHFJqcJniD0gkd2BZQ7-IPc6FPVlYYb7G0t8K_-8hVYizZl4HGy5V1QiE4sjdWLhyWX7MnJYEA61zoup_fbpEhDWYpcVACyQ6RKsqpyS-bQKGhQw8Tg2O8rcGJfaKI0jW3T7XKAYZg&3u2000&4u1000&5m1&2e1&key=AIzaSyAbdivx4G0igYO5yr3vTUJcQF5s8lTdXho&callback=none&token=20957
https://maps.googleapis.com/maps/api/place/js/PhotoService.GetPhoto?1sCmRaAAAAfLQZlWahAqUSlQA5y7-NTeYLMDim6M1L_ht3_qNCSL4dBeX2VWVdhzuJXeqGcKN30XAv3WZHtY2QUXaoKV5fVGSUld2IdOKfV0bv32kEFUdgMlqou9Ij5YVaJ15mfoVcEhB-6hiiaiPS3349mCZMYOPyGhTrEZUg0XGOuBW1rsrLlpmaO9nvqg&3u2000&4u1000&5m1&2e1&key=AIzaSyAbdivx4G0igYO5yr3vTUJcQF5s8lTdXho&callback=none&token=38662
============
What may be the problem
From the makeup of the URLs, there are obvious differences. The older URLs comes with the googleusercontent as the domain name. While the newer photos end with a token. Right now, I am still able to retrieve the older photos even though i may have added them months ago. For the new photos, it expires after a few days.
I understand that there are solutions that require the use of photo_reference, however, I am unable to find a way to retrieve photo_reference via the javascript API I am using. I have tried to use Places Service method (new google.maps.places.PlacesService) but it returns the same getURL() method which retrieves the same temporary URL as above.
=======================
Thus my question are:
Does anyone know whether the change in url is intended or it may be an error from google? If it is intended, is there any way to get a permanent url that does not expire.
Does anyone know how to retrieve photo_reference via the google javascript API?
Many thanks for your help in advance.
Google says this is intentional behavior and that the only thing users should be “caching” is the “place_id”.
See: https://issuetracker.google.com/issues/110711934
unfortunately, I think to retrieve the photo reference, a separate Place Details request will need to be made using the Place ID.
I worked around this by writing a serverside function to recursively follow the redirect path and get the ultimate photo url. Example in elixir:
def follow(url) when is_binary(url) do
case HTTPoison.get(url) do
{:ok, %HTTPoison.Response{status_code: status_code, headers: headers}} when status_code > 300 and status_code < 400 ->
case get_location_header(headers) do
[url] when is_binary(url) ->
follow(url)
_ ->
{:error, :no_location_header}
end
{:ok, %HTTPoison.Response{status_code: 200}} ->
{:ok, url}
reason ->
{:error, reason}
end
end
defp get_location_header(headers) do
for {key, value} <- headers, String.downcase(key) == "location" do
value
end
end
so now i can take the long
https://maps.googleapis.com/maps/api/place/js/PhotoService.GetPhoto?1sCm... url and run it through follow() which returns the googleusercontent url for the image itself.
i then pass THAT url to filestack to copy and store and serve over CDN...
bit of a crazy workaround, but it finally fixed this issue for us.
Here is a code in which you can pass the temporary URL fetched from Google places service API get photos, and it returns a permanent URL that you store in your database for later use.
<?php
function get_redirect_url($url){
$redirect_url = null;
$url_parts = #parse_url($url);
if (!$url_parts) return false;
if (!isset($url_parts['host'])) return false; //can't process relative URLs
if (!isset($url_parts['path'])) $url_parts['path'] = '/';
$sock = fsockopen($url_parts['host'], (isset($url_parts['port']) ? (int)$url_parts['port'] : 80), $errno, $errstr, 30);
if (!$sock) return false;
$request = "HEAD " . $url_parts['path'] . (isset($url_parts['query']) ? '?'.$url_parts['query'] : '') . " HTTP/1.1\r\n";
$request .= 'Host: ' . $url_parts['host'] . "\r\n";
$request .= "Connection: Close\r\n\r\n";
fwrite($sock, $request);
$response = '';
while(!feof($sock)) $response .= fread($sock, 8192);
fclose($sock);
if (preg_match('/^Location: (.+?)$/m', $response, $matches)){
if ( substr($matches[1], 0, 1) == "/" )
return $url_parts['scheme'] . "://" . $url_parts['host'] . trim($matches[1]);
else
return trim($matches[1]);
} else {
return false;
}
}
function get_all_redirects($url){
$redirects = array();
while ($newurl = get_redirect_url($url)){
if (in_array($newurl, $redirects)){
break;
}
$redirects[] = $newurl;
$url = $newurl;
}
return $redirects;
}
function get_final_url($url){
$redirects = get_all_redirects($url);
if (count($redirects)>0){
return array_pop($redirects);
} else {
return $url;
}
}
echo get_final_url($temporary_google_url);
?>
Source: http://w-shadow.com/blog/2008/07/05/how-to-get-redirect-url-in-php/
I'm Trying to get the Latitude & Longitude from Google maps Places Searchbox.
you can find the whole code here.
I don't have a deep knowledge to Javascript so I've seen a couple of solutions that doesn't actually work and I think I might misplace the code that gets the lat and lng!
So please help me to figure out where should I actually put the solution.
I've tried
place.geometry.location.lat()
place.geometry.location.lng()
it somehow doesn't work!
I'd like to send these lat and lng to HTML element
so I can send them as form to a PHP action Page and then to mysql Database..
Is there a shortcut that help me send them directly to the mysql DB or to PHP directly?
Without the rest of your code, I can only show you what I have done using a form to collect an address. Using php 7 with json_decode(). There is a more efficient way to do this, but it works for me. Hope this helps.
//create string holding address to run through google geolocation API for Lat/Long
//make sure to clean your posts, I use functions from another page that cleans htmls tags, trims and removes slashes and/or runs through a reg ex to replace and/or remove unwanted entries for the particular fields type.
$address = clean_post($_POST['cust_street']).' '.clean_post($_POST['cust_city']).' '.clean_post($_POST['cust_state']).', '.clean_post($_POST['cust_zip']);
// Get JSON results from this request
$url = 'https://maps.googleapis.com/maps/api/geocode/json?address='.urlencode($address).'&sensor=false&key='.APIKEY;
$geo = file_get_contents($url);
// Convert the JSON to an array
$geo = json_decode($geo, true);
if ($geo['status'] == 'OK') {
// Get Lat & Long
$latitude = $geo['results'][0]['geometry']['location']['lat'];
$longitude = $geo['results'][0]['geometry']['location']['lng'];
}else{
$latitude = NULL;
$longitude = NULL;
$sessData['status']['type'] = 'alert alert-warning';
$sessData['status']['msg'] = 'Sorry, but it seems the address you entered is not being recognized by Google Maps API service.';
//die or exit, do something on failure
}
Then you can add these variables to your DB insert/update and/or echo them out as needed. This very code is run through an applet I am working on that takes a given address entered into a customer form and then processes that address, gets Lat and Long and then upon success, places that into the array I am running through the insert into my DB. I can then call on that to locate that customers lat and long on a map at a later date.
$custData = array(
'users_id' => $usr_id,
'cust_first_name' => clean_post( $cust_first_name ),
'cust_last_name' => clean_post( $cust_last_name ),
'cust_email' => clean_email( $cust_email ),
'cust_street' => clean_post( $cust_street ),
'cust_city' => clean_post( $cust_city ),
'cust_state' => clean_post( $cust_state ),
'cust_zip' => clean_post( $cust_zip ),
'cust_phone1' => clean_phone( $cust_phone2 ),
'cust_lat' => clean_phone( $latitude ),
'cust_long' => clean_float( $longitude ),
//etc,etc,etc
);
//$cust = new User(); further up in page
//insertCust() function comes from user class stored in class.user.php
$insert = $cust->insertCust($custData);
//set status based on data insert
if($insert){
//set some session variables and store them before any header redirects.
$_SESSION['status']['type'] = 'alert alert-success';
$_SESSION['status']['msg'] = 'You have registered '.$custName.' successfully!';
}
Btw, I am currently going through this document on XSS security and have found it to be most helpful: XSS_Filter_Evasion_Cheat_Sheet
Hope this helps.
when I click a image. It's open a new page and a value pass through this click. It's working properly. but when I click back, It's do not show the previous page.
I use this code for click.
<img src="images/view.png" hspace="5" title="View" onClick="javascript:location.href='map_view.php?ad_id=<?php echo($row["ad_id"]); ?>'" style="cursor:pointer;" />
In order to geocode any phisical address, or get its coordinates , you should use a geocoding API, being google maps api v3 the most popular, which by the way gives you a free starting point of up to 2500 daily requests.
There is a bunch of documentation and starting guides, the best are the google maps's own.
Of course you can geocode on PHP or Javascript. Its really easy.
As other answer mentioned it is possible using google maps api, you can read more and get your own API KEY (More info and Get api key).
What you need is API key from google. This will help you fetching coordinates from given address.
I have made a little demonstration how it works it might be useful for other SO users.
By using following address
https://maps.googleapis.com/maps/api/geocode/json?address=YOUR_ADDRESS&key=YOUR_API_KEY
It will return you JSON formatted results with coordinates.
Now we need to build a tiny address form and pass it it to PHP script to return us the results
HTML Address form
<form action="index.php" method="post">
Enter Address:<br>
<input type="text" name="address">
<input type="submit">
</form>
PHP code
if (isset($_POST["address"]))
{
$addressInput = $_POST["address"];
$address = str_replace(" ", "+", $addressInput);
} else
{
// stack-overflow office address as default
$address = "110+William+St,+28th+Floor+New+York,+NY+10038";
}
echo "Latitude and Longitude for address : " . str_replace("+", " ", $address) . '<br>';
$json = file_get_contents('https://maps.googleapis.com/maps/api/geocode/json?address=' . $address . '&key=PUT_YOUR_OWN_API_KEY');
$data = json_decode($json, true);
//var_dump($data);
$getLat = $data['results'][0]['geometry']['location']['lat'];
$getLng = $data['results'][0]['geometry']['location']['lng'];
echo 'latitude ' . $getLat . ', longitude ' . $getLng;
The above working code can be tested on this link.
Moving theses data to mysql database or what ever you want to use it for, is left to you.
You'll probably use JavaScript for getting location of the user; not PHP. You can use HTML5 Geolocation for the purpose.
If you need to map the users location, pass the coordinates obtained using the HTML5 Geolocation API to Google Maps.
You may also need Modernizr to determine your users browser supports HTML5 Geolocation API.
I just realized that I cannot call directly on a URL from my AngularJS application due to CORS. Therefore, I expect I will have to use the Javascript API.
The following link provides me with the data I want:
https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=' + myPosition.lat + ',' + myPosition.lng + '&rankby=distance&key=' + key + '&sensor=false&type=clothing_store
However, I cannot figure how to achieve the same using the Javascript API. I found this in the documentation, but I do not need a map - just the names and coordinates of the nearby stores.
How can I get a hold of the same data using the Javascript API?
If you've already got a Google Maps for JS API Map Key, you can do a Places query from the server side. Note, however, that you're limited to 1000 queries per day.
You can probably do this directly in your client and avoid CORS issues, but here's how I've done it previously using PHP:
<?php
function ReturnEmpty()
{
// Something's wrong, return an empty set.
echo '{"d":[]}';
}
$q = (isset($_GET["query"])) ? $_GET["query"] : 'NULL';
if( $q == "" )
{
ReturnEmpty();
}
else
{
// I'm showing the "textsearch" option, but there is also a "nearbysearch" option..
$url = "https://maps.googleapis.com/maps/api/place/textsearch/json?query="
. urlencode($q)
. "&key=YOUR_GOOGLE_MAPS_KEY_HERE";
$json = file_get_contents($url);
$data = json_decode($json, true);
echo $data;
}
?>
You can use the nearbySearch(request, callback) method on google.maps.places.PlacesService(map).
In your case, the request should have a location (that contains the lat and lng) and a radius.
There are code samples here.
I'm trying to create a Google Places URL that can be reused and concatenated with a response from my database.. Not getting this to work and have been trying for a couple of days with no luck! If I echo out the both strings, from PHP on to my web page and copy&paste it, both addresses generate the same Google Places result, but when I print the JSON decoded response I get UNKNOW_ERROR from Google..
This is what I have been trying to use. The first and the second $googlePlacesAPI contains the exact same URL, just that one is concatenated and the other is "hard coded".
$googlePlacesAPI = "https://maps.googleapis.com/maps/api/place/textsearch/json?query=" .
$BarName. "+" . $BarCity . "&sensor=false&types=bar|night_club&key=" . $mySuperSecretKey;
$googlePlacesAPI = "https://maps.googleapis.com/maps/api/place/textsearch/json?query=" .
$BarName. "+" ."Göteborg". "&sensor=false&types=bar|night_club&key=" . $mySuperSecretKey;
To get the value of $BarCity I use this piece of code (before creating the $googlePlacesAPI variable):
$row = mysqli_fetch_array(mysqli_query($con, "SELECT * FROM City WHERE ID = $CityID"));
mysqli_close($con);
$BarCity = $row['CityName'];
EDIT:
This is how I decode the answer:
$placesSearch = json_decode(file_get_contents($googlePlacesAPI));
You probably want to close the connection after you're done with $row:
$row = mysqli_fetch_array(mysqli_query($con, "SELECT * FROM City WHERE ID = $CityID"));
$BarCity = $row['CityName'];
mysqli_close($con);
See a sample of mysqli_fetch_array usage at http://nl3.php.net/mysqli_fetch_array#example-1728