how would one go about calling meteor method from inside GoogleMaps.ready callback? I am using dburles:google-maps package.
On the client
GoogleMaps.ready('eventsmap', function(map) {
google.maps.event.addListener(map.instance, 'click', function(event) {
Markers.insert({lat: event.latLng.lat(), lng: event.latLng.lng()});
});
...
I tried following:
GoogleMaps.ready('eventsmap', function(map) {
google.maps.event.addListener(map.instance, 'click', function(event) {
var lat = event.latLng.lat();
var lng = event.latLng.lng();
Meteor.call("insertMarker", lat, lng, function(error, results) {
if(error) {
console.log(error.reason);
} else {
console.log(results);
}
});
});
...
On the server I have "insertMarker" method which will insert marker into Markers collection.
But got event is not defined exception. Any idea? Thank you.
Sorry guys, I just wrapped the method call inside if(event){...} conditional. It needed something to trigger the call. It works now, missed that one xD
Related
I am loading a google map with GeoJSON, and after the map is loaded and the data layers are applied, I would like to trigger a click event at a specific point automatically for the user. Subsequently, they can click all over the map to interact with it.
So for the automatic load part, I tried something like this:
var x = new google.maps.LatLng(myLongitude, myLatitude);
google.maps.event.trigger(map.data, 'click', WHAT_GOES_HERE?);
but I can't figure out what goes in the last part of that function. The corresponding function for clicking is this:
map.data.addListener('click', function (event) {
...
code
...
}
The event fires, but event is null of course. I need (event) to be populated with a feature (that's what the type is expected to be) but I can't seem to figure out how to get the feature from a long/lat.
So I load my data layers, I have my long/lat, but I can't seem to retrieve a feature from the long/lat. Any suggestions on how to retrieve this?
A (on)Click looks like this (let's say we put a marker there):
map.addListener('click', function (event) {
var position = {lat: event.latLng.lat(), lng: event.latLng.lng()}
//alert(JSON.stringify(position));
var marker = new google.maps.Marker({position: position, map: map});
});
So let's reverse this.
let's say you heve buttons that invoke a click on Brussels or Paris
<input type="button" value="click on Brussels" onclick="clickOnMap(50.85, 4.35)">
<input type="button" value="click on Paris" onclick="clickOnMap(48.84, 2.35)">
<script>
function clickOnMap(lat, lng) {
var event = {latLng: {}};
event.latLng.lat = function() { return lat };
event.latLng.lng = function() { return lng };
google.maps.event.trigger(map, 'click', event);
}
</script>
Clicking on the button will have the same effect as clicking on the map, on the same coordinates.
And of course you can call the function clickOnMap automatically.
Are you helped with this?
Edit: let's say you need more properties of event, like event.feature.getProperty("name");
Try adding something like this:
I don't know what else is expected, but you can keep adding properties like this.
function clickOnMap(lat, lng, name) {
var event = {latLng: {}, feature: {}};
event.latLng.lat = function() { return lat };
event.latLng.lng = function() { return lng };
event.feature.getProperty = function(property) { return name; };
google.maps.event.trigger(map, 'click', event);
}
I follow this guide
https://developers.google.com/maps/documentation/javascript/places#places_photos
to create place photo as marker icon. This is my map initialization code:
var map;
function initMap() {
// Create a map centered in Pyrmont, Sydney (Australia).
map = new google.maps.Map(document.getElementById('map'), {
center: {lat: -6.920812, lng: 107.604116},
zoom: 13
});
var request = {
location: map.getCenter(),
radius: '5000',
type: ['shopping_mall']
};
var service = new google.maps.places.PlacesService(map);
service.textSearch(request, callback);
}
// Checks that the PlacesServiceStatus is OK, and adds a marker
// using the place ID and location from the PlacesService.
function callback(results, status) {
console.log(results);
if (status == google.maps.places.PlacesServiceStatus.OK) {
for (var i = 0; i < results.length; i++) {
var place = results[i];
createPhotoMarker(place);
}
}
}
google.maps.event.addDomListener(window, 'load', initMap);
this is the createPhotoMarker function
function createPhotoMarker(place) {
var photos = place.photos;
if (!photos) {
var marker = new google.maps.Marker({
map: map,
position: place.geometry.location,
title: place.name
});
return;
}
var marker = new google.maps.Marker({
map: map,
position: place.geometry.location,
title: place.name,
icon: photos[0].getUrl({'maxWidth': 35, 'maxHeight': 35})
});
}
the function will create regular marker if place photo is not available. But for the place with photo available, I get this error :
Failed to load resource: the server responded with a status of 404 () lh3.googleusercontent.com/w35-h35-p/AF1QipOIL6GVVmtqp_cw_hBEQxdILZSa8poMO0HAqFHd=k
And the map only shows regular marker.
What did I do wrong?
This is the fiddle http://jsfiddle.net/v90fmrhp/
==========Update 2017-07-07============
Thanks for the answers and fixes
It seems the issue solved. My fiddle is working now
https://issuetracker.google.com/issues/63298126
Marked as Fixed
Good news! We have fixed this issue. Thanks for your patience.
Happy Mapping!
Looks like the error you are seeing is caused by some issue on Google's side. It's affecting quite a few other users as well, have a look at their public issue tracker:
Thanks for reporting this issue. We verified it and we'll keep tracking it.
https://issuetracker.google.com/issues/63298126
UPDATE (2017-07-06):
A fix for this is going into our release process now and it should be out soon - probably Monday at the latest.
https://issuetracker.google.com/issues/63298126#comment13
Had the same issue and Sulyman suggested a workaround that is working but I don't know for how long when google fixes this.
Google Places Photos .GetUrl is adding width and height to url
Here is what we did.
if(place.photos != null){
for(var i = 0; i < place.photos.length; i++){
//Do a string replace to get the w-h-p out of there.
var str = place.photos[i].getUrl({"maxWidth": 100, "maxHeight": 100});
var res = str.replace("w100-h100-p", "p");
self.pacPhotos.push({
id : res
});
}
}else {
console.log("no photo");
}
}
I also ran into this with google places api. Everything was working fine then randomly it stopped. It seems likely that it is due to google making changes as they get ready for releasing a better maps api to support vector
#DKinnison saved me with his solution so I just wanted to post my ES6 solution for parsing a received place. I commented out the other properties I am personally not using in case you need to.
const PHOTO_WIDTH = 600;
const PHOTO_HEIGHT = 600;
export function parseGooglePlace(place) {
if (!place) {
return;
}
const {
// address_components,
formatted_address,
geometry,
// icon,
// id,
// international_phone_number,
name,
// rating,
// reviews,
// opening_hours,
photos: _photos = [],
place_id,
// reference,
types = [],
// url: mapsURL,
// utc_offset,
// vicinity,
website,
} = place;
const photos = _photos.map(p =>
p
.getUrl({ maxWidth: PHOTO_WIDTH, maxHeight: PHOTO_HEIGHT })
.replace(`w${PHOTO_WIDTH}-h${PHOTO_HEIGHT}-p`, 'p'),
);
return {
website,
name,
photos,
address: formatted_address,
placeId: place_id,
geometry,
types,
};
}
Trying out polymer and wanted to know how to add a marker element to the polymer element. I know how to add the marker to a standard google map. Should I just insert a marker object into the google-map elements marker array? If so whats the signature and is there an example? Do I need to call some sort of map init or refresh after I do so, or does it update automatically?
(function() {
Polymer({
is: 'users-map',
created: function(){
this.loadMap(this.data[0]);
},
loadMap: function(row) {
var map = document.querySelector('#users-location-map');
row.users.forEach(function (user) {
var location = user.location;
var markerOptions = {
position: {lat: location[1], lng: location[0]},
//map: map //can't set this otherwise it throws an error on finding the google library
};
if (!user.online) {
markerOptions.icon = 'http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=%E2%80%A2|666666';
}
map.markers.push(something); //how should I instanstiate this something
// new google.maps.Marker(markerOptions); //normally I would just do this
});
},
The answer below works if I comment out the map assingment.
It depends if you are using the google-map and google-map-marker or the google map API directly.
If you use the google-map and google-map-marker elements this approach should work:
marker = document.createElement('google-map-marker');
marker.longitude = location[0];
marker.latitude = location[1];
marker.icon = 'ICON_UR'
Polymer.dom(this.$.map).appendChild(marker);
If you use the google map API directly your normal appraoch with new google.maps.Marker(markerOptions); should work fine.
I had same task early and have solution by this question. I hope my example will have in future for solution.
For example we have google-map polymer in our html:
<google-map map="{{map}}" latitude="40.730610" longitude="-73.935242" zoom="5" click-events="true" mouse-events="true" api-key="{{you_api_key}}" disable-default-ui>
</google-map>
And for dynamically create marker on google-map by click and add EventListener for drag event I write script like this:
<script> var map = document.querySelector('google-map');
map.addEventListener('google-map-click', function (e) {
let marker = document.createElement('google-map-marker');
let latLng = e.detail.latLng;
marker.setAttribute('latitude', latLng.lat());
marker.setAttribute('longitude', latLng.lng());
marker.setAttribute('title', "Marker name");
marker.setAttribute('draggable', true);
marker.setAttribute('click-events', true);
marker.setAttribute('mouse-events', true);
marker.addEventListener('google-map-marker-dragend', function (e) {
let latLng = e.detail.latLng;
marker.setAttribute('latitude', latLng.lat());
marker.setAttribute('longitude', latLng.lng());
});
Polymer.dom(map).appendChild(marker);
});
</script>
Hope it help in future. Thanks.
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/
I am trying to load a GeoJSON to the google maps javascript api and then process the GeoJSON by calling map.data.forEach . I cant get the map.data.forEach function to work it seems that it is never called.
The GeoJSON gets loaded fine and is displayed on my map.
Any suggestions why map.data.forEach would not work here?
Here is my code:
var myMap;
function initialize() {
// Create a simple map.
myMap = new google.maps.Map(document.getElementById('map-canvas'), {
zoom: 8,
center: {
lat: 48.2081743,
lng: 16.3738189
}
});
}
function calculate(map) {
console.log("calculating")
map.data.forEach(function (feature) {
console.log("tester");
});
console.log("end calculating");
}
function loadGeoJson(map) {
map.data.loadGeoJson('mini.json');
}
google.maps.event.addDomListener(window, 'load', function () {
initialize();
loadGeoJson(myMap);
calculate(myMap);
});
This is caused by javascripts asynchronous nature. When you have the code
loadGeoJson(myMap);
calculate(myMap);
and loadGeoJson loads an external resource, calculate will most likely be executed before loadGeoJson has finished. It is very easy to reproduce your problem.
Unfortunately there is no callback opportunity in google.maps.Data::loadGeoJson, but if you wrap the call of calculate into a small setTimeout, then you should be good :
loadGeoJson(myMap);
setTimeout(function() {
calculate(myMap);
}, 500);
see a fiddle with your code from above -> http://jsfiddle.net/SAS6Q/
You can also use jQuery and Ajax to load your JSON synchronously to avoid setting time delays:
function loadGeoJson(map) {
$.ajax({
url: mini.json,
dataType: 'json',
async: false,
success: function(data)
{var features = map.data.addGeoJson(data);}
});
}