Google Places API show schools and stores - javascript

Using the Google Maps API with the places library I am able to show nearby schools using the recommended method shown here.
var map;
var infowindow;
function initMap() {
var pyrmont = {lat: -33.867, lng: 151.195};
map = new google.maps.Map(document.getElementById('map'), {
center: pyrmont,
zoom: 15
});
infowindow = new google.maps.InfoWindow();
var service = new google.maps.places.PlacesService(map);
service.nearbySearch({
location: pyrmont,
radius: 500,
type: ['store']
}, callback);
}
function callback(results, status) {
if (status === google.maps.places.PlacesServiceStatus.OK) {
for (var i = 0; i < results.length; i++) {
createMarker(results[i]);
}
}
}
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(place.name);
infowindow.open(map, this);
});
}
Here's a working fiddle: https://jsfiddle.net/api/post/library/pure/
The problem is that if I also want to show nearby stores as well as schools, everyone seems to recommend simply doing this:
type: ['store', 'school']
While this technically works, the problem is the map just shows a bunch of meaningless default markers with no way of knowing what it what.
So my question is: How can I change the icon for the schools and stores? Ideally I would show a different icon for each different type.

It's no different than adding custom marker in regular map.Only thing is that you need to make api calls separately for each type.So even type: ['store', 'school'] would work and you get results but there is no type specifier in the results to tell whether it's a school or shop .Also you would need to create their separate callbacks for setting their separate icons
function createMarker(place) {
var placeLoc = place.geometry.location;
var marker = new google.maps.Marker({
icon:"http://example.com/icon.png", //<-- only this line is enough for icon
map: map,
position: place.geometry.location
});
go through this for a better understanding
Moreover every result will have a default icon (as icon property), that can also be used
var marker = new google.maps.Marker({
icon:place.icon,
map: map,
position: place.geometry.location
});

Related

Location based on correct map center for Google Place Service Nearby Search results

This code successfully takes a localStorage place id variable passed from an autocomplete field (can click "Map It" and enter a place in the pop up that appears, at roadtripsharing.com to test), and creates a marker, info window, and circle. I included a default location {lat: 39, lng: -105} in case users accessed the page directly without any localStorage use. However, even when I go from the home page and store something in local storage, the places that come up (in this case ATM machines) are all centered around Colorado Springs, USA, which is the {lat: 39, lng: -105}.
I believe at the point of declaring
var request = {
location: mapit.getCenter(),
radius: 5000,
// query: 'atm'
types: ['atm']
};
mapit.getCenter() should be results[0].geometry.location (the marker location based on the localStorage Place ID passed from the home page). How to make the Place Service Nearby Search result use this as the location instead of always {lat: 39, lng: -105}?
function initMapIt() {
var mapit = new google.maps.Map(document.getElementById('mapitmap'), {
center: {lat: 39, lng: -105},
zoom: 11,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var rtscircle = new google.maps.Circle({
radius:document.getElementById("rtsfader").value*1609.34,
strokeWeight: 2,
strokeColor: "blue",
strokeOpacity: 0.9,
fillColor: "red",
fillOpacity: 0.15,
clickable: false,
map: mapit
});
if (localStorage.placetopass !== null){
var rtsgeocoder = new google.maps.Geocoder;
var newplace = localStorage.getItem('placetopass');
rtsgeocoder.geocode({'placeId': newplace}, function(results, status) {
if (status === google.maps.GeocoderStatus.OK) {
if (results[0]) {
mapit.setZoom(11);
mapit.setCenter(results[0].geometry.location);
var rtsmarker = new google.maps.Marker({
map: mapit,
position: results[0].geometry.location
});
var rtsinfowindow = new google.maps.InfoWindow;
rtsinfowindow.setContent(results[0].formatted_address+'<p>Rate this place?</p>');
rtsinfowindow.open(mapit, rtsmarker);
rtsmarker.addListener('click', function() {
rtsinfowindow.open(mapit, rtsmarker);
});
rtscircle.setCenter(results[0].geometry.location);
jQuery("#rtsfader").change(function(){
rtscircle.setRadius(document.getElementById("rtsfader").value*1609.34);
});
}
else {
rtscircle.setCenter({lat: 39, lng: -105});
}
} else {
rtscircle.setCenter({lat: 39, lng: -105});
}
});
document.getElementById("rts-aahs").play();
}
var request = {
location: mapit.getCenter(),
radius: 5000,
// query: 'atm'
types: ['atm']
};
var infowindow = new google.maps.InfoWindow();
var service = new google.maps.places.PlacesService(mapit);
service.nearbySearch(request, callback);
function callback(results, status) {
if (status == google.maps.places.PlacesServiceStatus.OK) {
for (var i = 0; i < results.length; i++) {
createMarker(results[i]);
console.log(results[i]);
}
}
else
alert("Status not OK");
}
function createMarker(place) {
// alert("createMarker function");
var placeLoc = place.geometry.location;
var marker = new google.maps.Marker({
map: mapit,
position: place.geometry.location
});
console.log(marker);
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent(place.name);
infowindow.open(mapit, this);
});
}
}
The problem is you are calling mapit.getCenter() before you call mapit.setCenter(results[0].geometry.location). This happens because the you update the map center in the callback of rtsgeocoder.geocode(...), but you don't wait for that to run before continuing with doing the nearbySearch. You can verify this easily by adding a couple of console.log calls just before the getCenter/setCenter calls and observing the order they happen.
To fix this, you could try one of these approaches:
wait for up to some deadline (e.g. 2 seconds) for rtsgeocoder.geocode to run its callback before calling getCenter (and the nearbySearch based on it). This isn't very robust, for example a slow network link could mean it takes more than 2 seconds, and in the meantime you have no markers to show your user.
call nearbySearch from your rtsgeocoder.geocode callback as well as immediately — or even every time the map center is changed. Because adding lots of markers to a map can consume memory and slow down the page you'll probably want to remove the old markers when you get the new ones. For example by keeping an array of of markers added by your createMarker function and call marker.setMap(null) on each of them.
I think option 2 is usually the better choice.

Google Map with Local Churches, how to construct API call?

Is there are way to retrieve a map from Google using the API so that it displays a list of local churches with churches with markers?
I have the basic syntax, and I have a basic API account setup, but I am not how/if I can use the type field.
var mapOptions = {
center: new google.maps.LatLng("-33.8670522", "151.1957362"),
zoom: 11,
scrollwheel: false,
streetViewControl: false,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("googlemaps"), mapOptions);
Yes, you can do this, using Google Places API.
I'll use JavaScript API, since you seem to have a map being built with such API.
As said in documentation:
The Places service is a self-contained library, separate from the main Maps API JavaScript code. To use the functionality contained within this library, you must first load it using the libraries parameter in the Maps API bootstrap URL:
<script src="https://maps.googleapis.com/maps/api/js?libraries=places"></script>
After this, using JavaScript Places API you can request places by type and a radius (in meters). The maximum allowed radius is 50.000 meters.
Here a piece of code that demonstrate this:
var request = {
location: sydney,
radius: 5000,
types: ['church']
};
var service = new gm.places.PlacesService(map);
service.nearbySearch(request, handlePlaceResponse);
Obs.: In this example, handlePlaceResponse is a callback to handle the response and create the markers. See in the complete example how it works.
This will request by churches in a 5km radius from Sydney point (lat: -33.8670522, lng: 151.1957362).
To overlay markers you'll need handle the response. In the example I used only name to put as content of InfoWindow. You can see details about the response here: Place Details Responses
So, a function to create markers look like this:
/**
* Creates marker with place information from response
*/
function createMarker(place) {
var marker = new google.maps.Marker({
map: map,
position: place.geometry.location
});
var infowindow = new google.maps.InfoWindow();
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent(place.name);
infowindow.open(map, this);
});
}
Also, if you need, for types supported in place search, see this link: Place Type
Here an example using as point the used by you and 5000 meters for radius:
<html>
<head>
<title>Google Maps - Places Sample</title>
<style>
body {
margin: 0;
}
#map {
height: 600px;
width: 100%;
}
</style>
<script src="https://maps.googleapis.com/maps/api/js?libraries=places"></script>
<script>
var gm = google.maps;
var map;
var bounds;
var service;
var infowindow;
var sydney = new gm.LatLng(-33.8670522, 151.1957362);
function initialize() {
var options = {
zoom: 15,
center: sydney,
mapTypeId: gm.MapTypeId.ROADMAP,
streetViewControl: false,
scrollwheel: false
};
map = new gm.Map(document.getElementById("map"), options);
var request = {
location: sydney,
radius: 5000,
types: ['church']
};
bounds = new gm.LatLngBounds();
infowindow = new gm.InfoWindow();
service = new gm.places.PlacesService(map);
service.nearbySearch(request, handlePlaceResponse);
}
/**
* Handle place response and call #createMarker to creat marker for every place returned
*/
function handlePlaceResponse(results, status) {
if (status == gm.places.PlacesServiceStatus.OK) {
for (var i = 0; i < results.length; i++) {
createMarker(results[i]);
}
}
map.fitBounds(bounds);
map.setCenter(bounds.getCenter());
}
/**
* Creates marker with place information from response
*/
function createMarker(place) {
var location = place.geometry.location;
var marker = new gm.Marker({
map: map,
position: location
});
bounds.extend(location);
gm.event.addListener(marker, 'click', function() {
infowindow.setContent(place.name);
infowindow.open(map, this);
});
}
gm.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
<div id="map"></div>
</body>
</html>

Update markers with current position on Google Map API

I am learning to use javascript right now with Rails and I'm having some issues with updating my markers according to my current position using AJAX. I believe the ready page:load is not running the updated coords that have been attached as a data-attribute, coords since the page is not technically reloading. How can I use my current position data and update it with events with longitude/latitude values?
var map;
$(document).on('ready page:load', function() {
if ("geolocation" in navigator) {
myMap.init();
var coords = $('#map-canvas').data('coords');
if (coords){
myMap.addMarkers(coords);
}
}
});
myMap.init = function() {
if(navigator.geolocation){
var mapOptions = {
zoom: 14,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
navigator.geolocation.getCurrentPosition(function(position){
var pos = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
var infoWindow = new google.maps.InfoWindow({
map: map,
position: pos
});
var marker = new google.maps.Marker({
position: new google.maps.LatLng(position.coords.latitude, position.coords.longitude),
map: map
});
map.setCenter(pos);
var latitude = position.coords.latitude;
var longitude = position.coords.longitude;
$.ajax({
url:"/all_events",
method: "GET",
data: {
latitude: latitude,
longitude: longitude
},
dataType: 'script'
});
});
} else {
document.getElementById('map-canvas').innerHTML = 'No Geolocation Support.';
}
};
myMap.addMarkers = function(coords){
var image = "http://maps.google.com/mapfiles/ms/icons/yellow-dot.png"
coords.forEach(function(coord){
var myMarker = new google.maps.Marker({
position: new google.maps.LatLng(coord.latitude, coord.longitude),
map: map,
icon: image
});
});
}
In order to make your script work in the way you want please try out the following steps:
Put your foreach loop in a function and call it at the end of your successive AJAX callbacks.
Load the AJAX once the Google Maps have finished loading completely. If Google Maps library has not finished loading than you wont be able to create a Google LatLng object, this is what is probably happening over here.
Hope this would help

Display Multiple Markers in Array - Google Maps API

How can I clean this so that the code handles multiple listings better? I have seen some code examples that pull the marker info from an array, but I can't seem to get it to work.
The markers need to have "icon:", "url:" and "title:" attributes. The "icon:" so I can change each markers appearance, the "url:" to point through to the page dedicated to each marker and the "title" just to add the markers name on hover.
I also need the array in the script as I am not gathering it from a database or anything like that.
I am pretty green when it comes to javascript and google maps api, any help would be greatly appreciated.
function createMap(lat, lng, zoomVal) {
var mapOptions = { center: new google.maps.LatLng(lat, lng),
zoom: zoomVal,
scrollwheel: false,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
var myLatlnglow = new google.maps.LatLng(23.654332,-79.387867);
var markerlow1 = new google.maps.Marker({
position: myLatlnglow,
icon: 'images/map-dot.png',
map: map,
url: '#',
title: 'Name'
});
google.maps.event.addListener(markerlow1, 'click', function() {
window.location.href = markerlow1.url;
});
var myLatlnglow = new google.maps.LatLng(23.688458,-79.300619);
var markerlow = new google.maps.Marker({
position: myLatlnglow,
icon: 'images/map-dot.png',
map: map,
url: '#',
title: 'Name'
});
google.maps.event.addListener(markerlow, 'click', function() {
window.location.href = markerlow.url;
});
}
var map;
function initialize() {
createMap(23.668493, -29.410812,12);
if(navigator.geolocation) {
success = function(position) {
createMap(position.coords.latitude, position.coords.longitude,13);
};
error = function() {
createMap(23.648493, -29.410812,12);
}
navigator.geolocation.getCurrentPosition(success, error);
}
}
If I were you I would make an object of objects for the sake of readability. If you must have efficiency, and want to save space and typing, replace the object with an array and address the data by index (0,1,2...)
Here's a demo
// inside function createMap(...)
...
markerData = {
bing: {
lat: 23.654332,
lng: -79.387867,
icon: "http://labs.google.com/ridefinder/images/mm_20_red.png",
url: "http://www.bing.com/",
title: "some search engine"
},
yahoo: {
lat: 23.688458,
lng: -79.300619,
icon: "http://labs.google.com/ridefinder/images/mm_20_blue.png",
url: "http://www.yahoo.com/",
title: "Great free games"
}
};
for (markerId in markerData) {
markers[markerId] = createMarker(markerData[markerId]);
}
markers['bing'].setTitle("new title");
}
function createMarker(data) {
var myLatLng = new google.maps.LatLng(data.lat, data.lng);
var marker = new google.maps.Marker({
position: myLatLng,
icon: data.icon,
map: map,
title: data.title
});
google.maps.event.addListener(marker, 'click', function() {
window.location.href = data.url;
});
return marker;
}
It should also help later to save the references to the created markers, I'm using the global object markers and the same IDs.
var map;
var markers = {};
If you later need to change a marker property it is accessible through markers.
markers['bing'].setTitle("new title");

Marker content (infoWindow) Google Maps

I'm trying to add infoWindow's to multiple markers on a Google Map. The closest I have come is to get an infoWindow to display the last address you can see in the array, on all markers. The bit of code I have pasted below does not work, I get an "Uncaught TypeError: Cannot read property '4' of undefined". I'm sure this is a scope issue, but I'm going round in circles here and could do with some help:
var hotels = [
['ibis Birmingham Airport', 52.452656, -1.730548, 4, 'Ambassador Road<br />Bickenhill<br />Solihull<br />Birmingham<br />B26 3AW','(+44)1217805800','(+44)1217805810','info#ibisbhamairport.com','http://www.booknowaddress.com'],
['ETAP Birmingham Airport', 52.452527, -1.731644, 3, 'Ambassador Road<br />Bickenhill<br />Solihull<br />Birmingham<br />B26 3QL','(+44)1217805858','(+44)1217805860','info#etapbhamairport.com','http://www.booknowaddress.com'],
['ibis Birmingham City Centre', 52.475162, -1.897208, 2, 'Ladywell Walk<br />Birmingham<br />B5 4ST','(+44)1216226010','(+44)1216226020','info#ibisbhamcity.com','http://www.booknowaddress.com']
];
for (var i = 0; i < hotels.length; i++) {
var marker = new google.maps.Marker({
position: new google.maps.LatLng(hotels[i][1], hotels[i][2]),
map: map,
icon: image,
title: hotels[i][0],
zIndex: hotels[i][2]
});
var infoWindow = new google.maps.InfoWindow();
google.maps.event.addListener(marker, 'click', function () {
var markerContent = hotels[i][4];
infoWindow.setContent(markerContent);
infoWindow.open(map, this);
});
}
Thanks in anticipation.
We've solved this, although we didn't think having the addListener outside of the for would make any difference, it seems to. Here's the answer:
Create a new function with your information for the infoWindow in it:
function addInfoWindow(marker, message) {
var infoWindow = new google.maps.InfoWindow({
content: message
});
google.maps.event.addListener(marker, 'click', function () {
infoWindow.open(map, marker);
});
}
Then call the function with the array ID and the marker you want to create:
addInfoWindow(marker, hotels[i][3]);
Although this question has already been answered, I think this approach is better :
http://jsfiddle.net/kjy112/3CvaD/ extract from this question on StackOverFlow google maps - open marker infowindow given the coordinates:
Each marker gets an "infowindow" entry :
function createMarker(lat, lon, html) {
var newmarker = new google.maps.Marker({
position: new google.maps.LatLng(lat, lon),
map: map,
title: html
});
newmarker['infowindow'] = new google.maps.InfoWindow({
content: html
});
google.maps.event.addListener(newmarker, 'mouseover', function() {
this['infowindow'].open(map, this);
});
}

Categories

Resources