I am trying to get further information for places which I am showing on a map, such as the place address, phone number etc. You can see my code here:
http://jsfiddle.net/aboother/4q3jcg1s/
I have done a 'console_log(place)' as below:
function createMarker(place) {
var placeLoc = place.geometry.location;
var marker = new google.maps.Marker({
map: map,
position: place.geometry.location
});
console.log(place);
var request = { reference: place.reference };
service.getDetails(request, function(details, status) {
google.maps.event.addListener(marker, 'click', function() {
console.log(place);
infowindow.setContent(place.name + "<br />" + place.vicinity);
infowindow.open(map, this);
});
});
}
but I can't see the address or phone number in this object even though I know you can get this information. I can only see 'vicinity', 'name' and other basic information. Can anyone help?
Well you used the service: service.nearbySearch() to search nearby based on some criteria. Similarly there is the following service: service.getDetails() to get all the perspective details. I am not exactly sure but from my understanding the service uses the placeID to match and get all the details pertaining to that location.
In regards to your code, instead of directly creating a marker for each place, pass it to the getDetails() service and then create a marker. I logged the place and all the details are there, you use the data to your needs.
Below is the modified code:
function callback(results, status) {
if(status == google.maps.places.PlacesServiceStatus.OK) {
for(var i = 0; i < results.length; i++) {
service.getDetails(results[i], function(place, status) {
if (status == google.maps.places.PlacesServiceStatus.OK) {
var marker = new google.maps.Marker({
map: map,
position: place.geometry.location
});
console.log(place);
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent(place.name);
infowindow.open(map, this);
});
}
});
}
}
}
Here is the fiddle: Use whichever console you used to expand each location and you will see all their data, from phone numbers, to their review: http://jsfiddle.net/r61tqtxw/1/
Related
I'm working on a project where I'd like to show the choosen event on google maps with some additional information. (ex. all gas stations radius 2km).
Google doesn't allow a nearby search with multiple types.
Restricts the results to places matching the specified type. Only one type may be specified (if more than one type is provided, all types following the first entry are ignored).
So for now I'd like to change the type (ex. gas_station or store) if I click to a custom button I added.
(used the google document example)
Screenshot: http://imgur.com/qYwLuw4
Question:
Which is the best way to change the type and refresh the map with the new information?
I'd like to present you our solution.
We wrote a clear() and a showType() function, which will erase all markers and let the right ones appear on click. By the way we give the button a state class called "selected" for CSS styling.
We didn't find a solution to show both (washstation AND fuelstation).
<script type="text/javascript">
var map;
var infowindow;
var service;
var eventLocation = {lat: <?= $arrCoordinates['latitude']?>, lng: <?= $arrCoordinates['longitude']?>};
var markers = [];
var wash = document.getElementById('wash'); //washbutton
var fuel = document.getElementById('fuel'); //fuelstation button
function initMap() {
map = new google.maps.Map(document.getElementById('eventmap'), {
center: eventLocation,
zoom: 13,
});
infowindow = new google.maps.InfoWindow();
service = new google.maps.places.PlacesService(map);
showType('gas_station');
fuel.classList.add("selected");
typeControl(map);
}
// Type control function
function typeControl ( map ) {
google.maps.event.addDomListener(fuel, 'click', function() {
wash.classList.remove("selected");
fuel.classList.remove("selected");
clear()
showType('gas_station')
this.classList.add("selected");
});
google.maps.event.addDomListener(wash, 'click', function() {
wash.classList.remove("selected");
fuel.classList.remove("selected");
clear()
showType('car_wash')
this.classList.add("selected");
});
}
function showType(type) {
service.nearbySearch({
location: eventLocation,
radius: 10000,
type: [type]
}, callback);
}
function clear() {
markers.forEach(marker => marker.setMap(null));
markers = [];
}
function callback(results, status) {
clear()
if (status === google.maps.places.PlacesServiceStatus.OK) {
for (var i = 0; i < results.length; i++) {
createMarker(results[i]);
}
createTuningEventMarker();
}
}
function createTuningEventMarker(place) {
var eventLocation = {lat: <?= $arrCoordinates['latitude']?>, lng: <?= $arrCoordinates['longitude']?>};
var eventIcon = {
url: 'https://www.foo.lol/img/icons/pin.svg',
// This marker is 20 pixels wide by 32 pixels high.
scaledSize: new google.maps.Size(60, 60),
// The origin for this image is (0, 0).
origin: new google.maps.Point(0,0),
// The anchor for this image is the base of the flagpole at (0, 32).
anchor: new google.maps.Point(30,60)
};
var marker = new google.maps.Marker({
map: map,
icon:eventIcon,
position: eventLocation
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent('<?= $event['name']?>');
infowindow.open(map, this);
});
}
function createMarker(place) {
var placeLoc = place.geometry.location;
var marker = new google.maps.Marker({
map: map,
position: place.geometry.location
});
markers.push(marker);
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent(place.name + "<br>Adress: " + place.vicinity);
infowindow.open(map, this);
});
}
</script>
I have created a google map using V3 js API, and inside the map I am showing multiple markers. When I am clicking on a markers it does an ajax call and shows the result in the infowindow. I have added an external link outside the map, clicking on which it will display the corresponding marker result in side the map. I have used the below code to do the functionality..
$('#marker_link').click(function () {
var longitude = $(this).find("#longitude").val();
var latitude = $(this).find("#latitude").val();
var index = $(this).find("#index").val();
google.maps.event.trigger(gmarkers[index], "click", {
latLng: new google.maps.LatLng(latitude, longitude)
});
});
This code is pulling the marker data correctly and showing in a window. But at that time the map goes blank. How can we fix it. How can we keep the map along with the store result.
Here gmarkers[ ] is a global array where I am keeping all the markers that are created during the map is rendered.
The below code I have used while showing markers in the map for the first time.
var marker = new google.maps.Marker({
map: map,
position: new google.maps.LatLng(pLat, pLong),
});
gmarkers.push(marker);
google.maps.event.addListener(marker, 'click', function (event) {
var dataString = 'store_id=' + {{ store.store_id }}
$.ajax({
type: "GET",
url: GET_STORE_DATA,
data: dataString,
success: function(res) {
if(res != '') {
var contentString = res;
var infoWindow = new google.maps.InfoWindow({ content: contentString });
infoWindow.setPosition(event.latLng);
infoWindow.open(map);
google.maps.event.addListener(map, 'click', function() {
infoWindow.close();
});
} else {
alert('No data found')
}
}
});
});
I am new to Sencha Touch, knows Javascript,jQuery,HTML5.
I am developing simple Google Map application with Sencha Touch + Sencha Architect where it place marker on current position and also use Google Place to find 'store'(i.e. types need for Google place search) near the current location. I am getting the locations in 'callbackPlaces' (i.e. latitude, longitude) but Google.Maps.Marker gives error in 'callbackPlaces' method (i.e. called through 'addMarker' method and I also tried and tested by putting Google.Maps.Marker in 'callbackPlaces').
Ext.define('MyApp.view.Map', {
extend: 'Ext.Map',
alias: 'widget.map',
config: {
useCurrentLocation: true,
listeners: [
{
fn: 'onMapMaprender',
event: 'maprender'
}
]
},
onMapMaprender: function(map, gmap, options) {
this.initializePlaces();
},
initializePlaces: function() {
//Set Marker on Current Position
var geo = this.getGeo();
var currentPosition = new google.maps.LatLng(geo.getLatitude(), geo.getLongitude());
this.createMarker(currentPosition);
//request set for Places Services
var request = {
location: currentPosition,
radius: 500,
types: ['store']
};
this.getMap().zoom = 15;
// Call PlacesService
var service = new google.maps.places.PlacesService(this.getMap());
service.nearbySearch(request, this.callbackPlaces);
},
callbackPlaces: function(results, status) {
if (status == google.maps.places.PlacesServiceStatus.OK) {
for (var i = 0; i < results.length; i++) {
addMarker(results[i]);
}
}
},
createMarker: function(position) {
//Here Position = Google Map LatLng
var infoWindow = new google.maps.InfoWindow();
var marker = new google.maps.Marker({
map: this.getMap(),
position: position
});
google.maps.event.addListener(marker, "click", function() {
infoWindow.setContent("Lng: " + marker.position.lng() + "\n Lat: " + marker.position.lat());
infoWindow.open(this.getMap(), marker);
});
},
addMarker: function() {
//Here Place = google.maps.places
var infoWindow = new google.maps.InfoWindow();
var marker = new google.maps.Marker({
map: this.getMap(),
position: place.geometry.location
});
google.maps.event.addListener(marker, "click", function() {
infoWindow.setContent("Lng: " + marker.position.lng() + "\n Lat: " + marker.position.lat());
infoWindow.open(this.getMap(), marker);
});
}
});
I don't know what went wrong!
Any help|hint would appreciated!
Thanks in advance.
You pointed out there was a scope issue in the callbackPlaces function.
Therefore you should replace the following line:
service.nearbySearch(request, this.callbackPlaces);
with
service.nearbySearch(request, function (results, status) {
this.callbackPlaces.call(this, [results, status]);
});
Hope this helps
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
});
}
The "drag", "dragstart" and "dragend" events in the Google Maps V3 API each pass a mouseEvent to the registered callback function.
However - this event does not contain any information as to which marker is being dragged. How can I determine that?
This is even more complicated if you are just looking at the "dragend" event - which would only have the new coordinates, making it impossible to even infer from the coordinates.
I'd assume there's got to be an easy way to just determine which marker is being dragged...
I would attach add the drag event to the marker using a listener when it is created.
google.maps.event.addListener(marker, 'dragend', function() {
//do something with the event.
});
here is an example fiddle: http://jsfiddle.net/2YQg6/10/
(Dont mind the other stuff I just edited a fiddle I have used before to handle draggable markers.)
The relavant code is in the marker creation loop:
//geo code and build markers for each list item.
for (var i = 0; i < $listItems.length; i++) {
geocoder.geocode({
'address': $($listItems[i]).text()
}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var marker = new google.maps.Marker({
position: results[0].geometry.location,
map: map,
draggable: true,
originalPos: results[0].geometry.location
});
google.maps.event.addListener(marker, 'dragend', function() {
infoWindow.setContent("marker originally at this position: " + this.originalPos + " was dragged to: " + this.position);
infoWindow.open(map, this);
});
markers.push(marker);
}
});
}