Google places javascript library to search for places inside my database - google-places

I have a mysql database with places.Each place has a longitude/latitude.
What I want is to search for places inside an area, e.g. places inside London.
Is this possible to do with the Google places javascript library?
thanks!

All of this and more is possible using the Google Places JavaScript library.
There's a code snippet on the page above that does exactly that (searching for places based on longitude / latitude).
var map;
var service;
var infowindow;
function initialize() {
var pyrmont = new google.maps.LatLng(-33.8665433,151.1956316);
map = new google.maps.Map(document.getElementById('map'), {
mapTypeId: google.maps.MapTypeId.ROADMAP,
center: pyrmont,
zoom: 15
});
var request = {
location: pyrmont,
radius: '500',
types: ['store']
};
service = new google.maps.places.PlacesService(map);
service.nearbySearch(request, callback);
}
function callback(results, status) {
if (status == google.maps.places.PlacesServiceStatus.OK) {
for (var i = 0; i < results.length; i++) {
var place = results[i];
createMarker(results[i]);
}
}
}

Related

Automatically show street view map when inputting an address

I want to put in a street address, and have it programatically determine the coordinates and heading for the purposes of generating a street view map. instantstreetview.com does this, so I know it can be done. From the docs:
function initialize() {
var fenway = {lat: 42.345573, lng: -71.098326};
var map = new google.maps.Map(document.getElementById('map'), {
center: fenway,
zoom: 14
});
var panorama = new google.maps.StreetViewPanorama(
document.getElementById('pano'), {
position: fenway,
pov: {
heading: 34,
pitch: 10
}
});
map.setStreetView(panorama);
}
Problem is, I don't know the heading of the address I want. Is there a simple way to achieve this?
You may want to look into getting the LatLng from the StreetViewLocation of the StreetViewPanorama rendered to compute the heading using the computeHeading() in the Geometry library in the Javascript API.
Take a look at this sample JSBin. I've created two Street View divs with the lat/lngs of two addresses across the street from each other. Notice that, regardless of the lat/lng, the same pano is returned, but there is no heading information, so the view is the same:
Now, look at this this modified JSBin. After computing the heading based on the StreetViewLocation.latLng of the panorama and lat/lng of the addresses passed into StreetViewService and using that as the pov for the panoramas, the correct Street View imagery is shown for each address:
The pertinent code:
var ll = new google.maps.LatLng(37.435292,-122.129517);
var svs = new google.maps.StreetViewService();
svs.getPanorama({location: ll, preference: 'nearest'}, function(data, status){
var pos = data.location.latLng;
var head = google.maps.geometry.spherical.computeHeading(pos, ll);
var panorama = new google.maps.StreetViewPanorama(
document.getElementById('street-view'),
{
pano: data.location.pano,
pov: {heading: head, pitch:0}
});
});
EDIT: Adding another simple JSBin showing the use of the Geocoder to get the LatLng for the addresses: Pertinent code:
var ll;
var geocoder = new google.maps.Geocoder();
var svs = new google.maps.StreetViewService();
geocoder.geocode({address: "757 Moreno Ave Palo Alto, CA"}, function(results, status) {
if (status == 'OK') {
ll = results[0].geometry.location;
svs.getPanorama({location: ll, preference: 'nearest'}, function(data, status){
var pos = data.location.latLng;
var head = google.maps.geometry.spherical.computeHeading(pos, ll);
panorama = new google.maps.StreetViewPanorama(
document.getElementById('street-view'),
{
pano: data.location.pano,
pov: {heading: head, pitch:0}
});
});
}
});

How to find the exact location details from latitude and longitude?

I tried using Google Maps API for 'Reverse Geocoding' to get the location by providing latitude and longitude. This gives the street address, city and country info. But I need to get the exact details like building name, shop name etc. For example, while querying the co-ordinates "72.9011206,19.0517508", Google Maps API gives "Plot No 5, VN Purav Marg, Borla, Union Park, Chembur, Mumbai, Maharashtra 400071, India". But I need to get the name of the shop "Barista Lavazza" as available in 'Google Earth' for the same co-ordinate details.
One option would be to use the Google Maps Javscript API Places library nearbySearch, search the returned results for the closest result to the requested position.
proof of concept fiddle
code snippet:
var map;
var infowindow;
var searchLoc = new google.maps.LatLng(19.0517508, 72.9011206);
function initialize() {
map = new google.maps.Map(
document.getElementById("map_canvas"), {
center: searchLoc,
zoom: 18,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
infowindow = new google.maps.InfoWindow();
var request = {
location: searchLoc,
radius: '50'
};
service = new google.maps.places.PlacesService(map);
service.nearbySearch(request, callback);
}
function callback(results, status) {
if (status == google.maps.places.PlacesServiceStatus.OK) {
var bounds = new google.maps.LatLngBounds();
var distMin = Number.MAX_VALUE;
var idxMin = -1;
for (var i = 0; i < results.length; i++) {
var place = results[i];
bounds.extend(results[i].geometry.location);
var distance = google.maps.geometry.spherical.computeDistanceBetween(results[i].geometry.location, searchLoc);
if (distance < distMin) {
distMin = distance;
idxMin = i;
}
}
var marker = createMarker(results[idxMin]);
google.maps.event.trigger(marker, 'click');
}
}
function createMarker(place) {
var placeLoc = place.geometry.location;
var marker = new google.maps.Marker({
map: map,
position: place.geometry.location
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent("<h2 style='color:blue'>"+place.name + "</h2><br>" + place.vicinity + "<br>" + marker.getPosition().toUrlValue(7));
infowindow.open(map, this);
});
return marker;
}
google.maps.event.addDomListener(window, "load", initialize);
html,
body,
#map_canvas {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js?libraries=geometry,places"></script>
<div id="map_canvas"></div>

nearbySearch with name specified like wildcard

I am after a way to do a Google Maps API V3 "nearbySearch" by specifying both an exact location but not an exact store name (like a wildcard search).
e.g., If the request was for "Starbucks" in "San Francisco" it would return all Places called "Starbucks", whether the Place had more words in it's title or not e.g., results would contain "Starbucks Coffee", "Starbucks Smith St" or simply "Starbucks". Currently it looks like it only finds identical matches, "Starbucks".
Code (more info here):
var map;
var service;
var infowindow;
function initialize() {
// Specify lat/lng of search location
var SanFran = new google.maps.LatLng(37.777119,-122.41964);
// Create new map object
map = new google.maps.Map(document.getElementById('map'), {
mapTypeId: google.maps.MapTypeId.ROADMAP,
center: SanFran,
zoom: 15
});
// Create request parametres
var request = {
location: SanFran
, radius: '500',
, name: "Starbucks"
};
// Call the nearby search using the parametres
service = new google.maps.places.PlacesService(map);
service.nearbySearch(request, callback);
}
// Asynchronous marker creation at returned locations
function callback(results, status) {
if (status == google.maps.places.PlacesServiceStatus.OK) {
for (var i = 0; i < results.length; i++) {
var place = results[i];
createMarker(results[i]);
}
}
}
I've done some reading and whilst it looks like API3 doesn't offer Wildcard search, I'm hoping there are work arounds.
Thanks in advance!
Sorry all, the answer was really quite simple. I should have been using the textSearch rather than nearbySearch:
...
// Create request parametres
var request = {
location: SanFran
, radius: '500',
, query: "Starbucks"
};
// Call the nearby search using the parametres
service = new google.maps.places.PlacesService(map);
service.textSearch(request, callback);
...
More info here https://developers.google.com/maps/documentation/javascript/places#TextSearchRequests

How to load markers from XML file with directions API in Google Maps

I'm trying to load markers from XML file on a map used for outputing directions. Basically, it's the combination of two demos found on Google's documentation pages.
Directions: https://google-developers.appspot.com/maps/documentation/javascript/examples/directions-panel
XML: http://gmaps-samples-v3.googlecode.com/svn/trunk/xmlparsing/downloadurl_info.html
I have first created the directions map and then tried to add XML file that contains markers.
I'm probably making a simple mistake, but since I'm not good with js and coding, can't find what. There are no errors displayed, only a blank page.
Here is my current code:
<script>
var directionDisplay;
var directionsService = new google.maps.DirectionsService();
function initialize() {
directionsDisplay = new google.maps.DirectionsRenderer();
var mapOptions = {
zoom: 7,
mapTypeId: google.maps.MapTypeId.ROADMAP,
center: new google.maps.LatLng(41.850033, -87.6500523)
};
var map = new google.maps.Map(document.getElementById('map_canvas'), mapOptions);
directionsDisplay.setMap(map);
directionsDisplay.setPanel(document.getElementById('directions-panel'));
var control = document.getElementById('control');
control.style.display = 'block';
map.controls[google.maps.ControlPosition.TOP].push(control);
}
var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
downloadUrl("http://gmaps-samples-v3.googlecode.com/svn/trunk/xmlparsing/moredata.xml", function(data) {
var markers = data.documentElement.getElementsByTagName("marker");
for (var i = 0; i < markers.length; i++) {
var latlng = new google.maps.LatLng(parseFloat(markers[i].getAttribute("lat")),
parseFloat(markers[i].getAttribute("lng")));
var marker = createMarker(markers[i].getAttribute("name"), latlng);
}
});
function calcRoute() {
var start = document.getElementById('start').value;
var end = document.getElementById('end').value;
var request = {
origin: start,
destination: end,
travelMode: google.maps.DirectionsTravelMode.DRIVING
};
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
}
});
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
Here is the (non-working) jsFiddle: http://jsfiddle.net/ajJ3u/
Problems from a quick review:
you are creating the map twice.
you don't have a createMarker function. If that call came from one of the examples, you missed bringing it to the new map.
downloadUrl is subject to a cross-domain security restriction. If your page is not running in the "http://gmaps-samples-v3.googlecode.com" domain, it won't work. You need to access xml from the same domain as the page is running in or use a proxy.
Example of directions from/to markers from xml (translated to v3 from Mike Williams' v2 tutorial

Geocoding using Google Maps API v3 - Linking the original request to the response

I have a list of schools that I want to plot on a Google Map. I'm using Google's Geocoding Service to lookup the lng/lat for a given postcode, upon successfully retrieving this information I want to drop a marker, together with adding the appropriate event listener that opens an infobox when a given marker is clicked.
When I make a request to the geocoder it's in the context of a school, when I receive a callback I lose this context. You'll see from code below that I've come up with a clunky solution to this, although it fails occasionally when the geocoder results truncate the postcode.
Should I be using something like jQuery's Deferred Object to solve this issue?
var geocoder;
var map;
var infowindow
var iterator = 0;
geosearch = new Array();
function drop() {
for (var i = 0; i < schools.length; i++) {
setTimeout(function() { // delay added to prevent being throttled
addMarker();
iterator++;
}, i * 1000);
}
}
function addMarker() {
address = schools[iterator].addresses[0].address.zip;
geosearch[address] = schools[iterator]; // this is how I'm keeping track of initial request
geocoder.geocode( { 'address': address }, function(results, status) {
var school = geosearch[results[0].address_components[0].short_name]; // loading the school associated with the initial request, which only works if the postcode completely matches up - clunky!
if (status == google.maps.GeocoderStatus.OK) {
// each school has tags, I want to set a marker if certain tags exist
if ($.inArray('D', school.tags) > 0) {
var image = 'map_markers/brown_MarkerD.png';
} else if ($.inArray('C', school.tags) > 0) {
var image = 'map_markers/red_MarkerC.png';
} else if ($.inArray('B', school.tags) > 0) {
var image = 'map_markers/yellow_MarkerB.png';
} else if ($.inArray('A', school.tags) > 0) {
var image = 'map_markers/green_MarkerA.png';
} else {
var image = 'map_markers/blue_MarkerZ.png';
}
// add the marker to the map, using result
var marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location,
draggable: false,
icon: image,
shadow: 'http://www.google.com/mapfiles/arrowshadow.png',
animation: google.maps.Animation.DROP
});
// adds listening on marker so that popup box appears when clicked
google.maps.event.addListener(marker, 'click', (function(marker, school) {
return function() {
infowindow.setContent(
''+school.name+''
+'<address>'
+school.addresses[0].address.street+'<br />'
+school.addresses[0].address.city+'<br />'
+school.addresses[0].address.state+'<br />'
+school.addresses[0].address.zip+'<br />'
+school.addresses[0].address.country+'<br />'
+'</address>');
infowindow.open(map, marker);
}
})(marker, school));
} else {
console.log("* NOT found: " + status);
}
});
}
function initialise() {
geocoder = new google.maps.Geocoder();
infowindow = new google.maps.InfoWindow();
var latlng = new google.maps.LatLng(54.82659788452641,-3.417279296874991);
var mapOptions = {
zoom: 6,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
drop(); // loops through schools to add marker
}
I would suggest geocoding the addresses offline and storing the coordinates in your database (or wherever you are storing the addresses). Then use the coordinates to display the markers.
I would also suggest reviewing this article on geocoding strategies from the documentation
To answer your question, I would suggest using javascript function closures to associate the address with the callback function.
The problem I was experiencing here was just a questions of scope, and in particular the way that I was referencing the school within the addMarker() function. Rather than referencing the school within the schools array using the global iterator variable, I instead pass in this school, this way the correct school is always referenced on the callback that is created within this scope.
var geocoder;
var map;
var infowindow
var iterator = 0;
function drop() {
for (var i = 0; i < schools.length; i++) {
setTimeout(function() {
addMarker(schools[iterator]); // pass in the school as an argument
iterator++;
$('#current_school').text(iterator); // taken this out of addMarker()
}, i * 1000);
}
}
function addMarker(school) {
geocoder.geocode( { 'address': school.addresses[0].address.zip }, function(results, status) {
... // the inners from here remain the same
});
}