Undefined LatLng google map in AngularJs Controller - angularjs

I want to retrieve the longitude and latitude position of my click mouse event, but i can't, it gives me Undefined. Any one can help me please ?
I'm using AngularJS and I found that we can do
google.maps.event.addListener(map, 'click', function(event) {
console.log(event.latLng);
});
But I can't do so in my controller it gives me an error, or maybe i don't know how to use that!!
here is my code :
$scope.map = {
center: {
latitude: 36,
longitude: -80
},
events: {
"click": function (event) {
console.log(event.latLng);
}
}
}
and I tried that too but it gives me (Nan,Nan)
$scope.map = {
center: {
latitude: 36,
longitude: -80
},
events: {
"click": function (event) {
var pos = new google.maps.LatLng(event.latLng, event.latLng);
console.log("position: " + pos);
}
}
}

I could solve it like that
events: {
tilesloaded: function (map, eventName, originalEventArgs) {
//map is trueley ready then this callback is hit
},
click: function (mapModel, eventName, originalEventArgs) {
var e = originalEventArgs[0];
var lat = e.latLng.lat(),lon = e.latLng.lng();
console.log("lat long: "lat, lon);
$scope.$apply();
}
}

Related

Angular Google Maps idle event fires multiple times

I am using angular-google-maps v-2.3.3. I am loading markers using the "markers" directive and using map "idle" event for some manipulations. My problem is, Every time when the user zoom in or zoom out or pan the map, "idle" event is getting fired n number of times based on the number of markers with in the bounds. For eg: If there are 40 markers, The idle event is getting called 40 times instead of once. Below is my code where I am setting up the idle event.
angular.extend(vm, {
map: {
center: { latitude: 47, longitude: 2 },
markersControl: {},
mapControl: {},
events: {
tilesloaded: function(map) {
$scope.$apply(function() {
vm.mapInstance = map;
});
var map = vm.map.mapControl.getGMap();
$timeout(function() {
google.maps.event.trigger(map, 'resize');
}, 100);
},
dragend: dragend,
idle: function() {
try {
var markers = vm.map.markersControl.getGMarkers();
var map = vm.map.mapControl.getGMap();
for (var i = 0; i < markers.length; i++) {
if (map.getBounds().contains(markers[i].getPosition())) {
markers[i].setVisible(true);
} else {
markers[i].setVisible(false);
}
}
} catch (err) {
// Handle error(s) here
}
}
},
window: {
closeClick: function() {
var markers = vm.map.markersControl.getGMarkers();
markers.forEach(function(v, i) {
v.setAnimation(null);
});
}
}
}
});

With Angular update the scope from an event handler

I am having one issue I was hoping someone would help me on. I am using Angular and the angular google maps directive. I have an event handler registered on idle so that I want to update what markers are shown but when the event is handled it returns the map and I've lost scope so I am unsure how to add new markers onto the map?
I setup a map like so:
<google-map center="map.center" zoom="map.zoom" events="map.events"> <markers> <marker ng-repeat="marker in map.markers" coords="marker"> </marker> </markers> </google-map>
That then uses the following to setup its initial values on events:
$scope.map = {
center: {
latitude: 45,
longitude: -73
},
zoom: 8,
events:{
idle:getJobs
},
markers:[]
};
When the event fires the getJobs function I have lost the scope so cannot push new markers onto the map with angular, any ideas??
function getJobs($scope) {
self = this;
JobService.getJobs(self.map).then(function(jobData){
for (var i = 0; i < jobData.length; i++) {
var job = jobData[i];
if (job.get('location') != null && job.get('location').longitude != null) {
$scope.map.markers.push(createJobMarker(job.get('role'),job.get('location').longitude,job.get('location').latitude),i);
}
}
});
}
Try
function getJobs($scope) {
self = this;
JobService.getJobs(self.map).then(function(jobData){
$scope.apply(function () {
for (var i = 0; i < jobData.length; i++) {
var job = jobData[i];
if (job.get('location') != null && job.get('location').longitude != null) {
$scope.map.markers.push(createJobMarker(job.get('role'),job.get('location').longitude,job.get('location').latitude),i);
}
}
});
});
}
Update:
I see, you are just losing reference to the scope variable. Try setting up your event like this:
$scope.map = {
center: {
latitude: 45,
longitude: -73
},
zoom: 8,
events:{
idle: function () {
getJobs($scope);
}
},
markers:[]
};

angular-google-maps center zoom multiple markers

I'm using AngularJS for Google Maps and want to dynamically center and zoom a map based on multiple markers that are dynamically loaded. This is for a Cordova app using the Ionic Framework.
Here's my view:
<ion-view title="" ng-controller="MapCtrl as vm">
<ion-content class="padding">
<google-map id="mainMap" control="vm.googleMap" draggable="true" center="vm.map.center" zoom="vm.map.zoom" mark-click="false">
<markers idKey="mainMap" fit="vm.map.fit">
<marker idKey="marker.id" ng-repeat="marker in vm.map.markers" coords="marker.coords" options="marker.options">
<marker-label content="marker.name" anchor="2 0" class="marker-labels"/>
</marker>
</markers>
</google-map>
</ion-content>
</ion-view>
Here's my controller:
angular.module('myApp.controllers', [])
.controller('MapCtrl', function($scope, $ionicPlatform) {
var vm = this;
vm.googleMap = {}; // this is filled when google map is initialized, but it's too late
vm.mapMarkers = [];
vm.arrMarkers = [
{
id: "home",
name: "home",
coords: {
latitude:xxxxxxx, //valid coords
longitude:xxxxxxx //valid coords
},
options: {
animation: google.maps.Animation.BOUNCE
}
},
{
id: "placeAId",
name: "Place A",
coords: {
latitude:xxxxxxx, //valid coords
longitude:xxxxxxx //valid coords
}
},
{
id: "placeBId",
name: "Place B",
coords: {
latitude:xxxxxxx, //valid coords
longitude:xxxxxxx //valid coords
}
}
];
vm.map = {
center: { //how to determine where to center???
latitude: xxxxxxx, //valid coords
longitude: xxxxxxx //valid coords
},
zoom: 12, //how to determine zoom dynamically???
fit: true,
markers: vm.arrMarkers
};
var setMapBounds = function () {
var bounds = new google.maps.LatLngBounds();
createMarkers();
var markers = vm.mapMarkers;
for(var i=0; i<markers.length; i++) {
bounds.extend(markers[i].getPosition());
}
var map = vm.googleMap.control.getGMap();
map.setCenter(bounds.getCenter());
map.fitBounds(bounds);
//remove one zoom level to ensure no marker is on the edge.
map.setZoom(map.getZoom()-1);
// set a minimum zoom
// if you got only 1 marker or all markers are on the same address map will be zoomed too much.
if(map.getZoom()> 15){
map.setZoom(15);
}
};
var createMarkers = function() {
var map = vm.googleMap.control.getGMap(); //vm.googleMap.control is undefined because this fire before map is initialized
angular.forEach(vm.restaurants, function(restaurant, index) {
var marker = new google.maps.Marker({
map: map,
position: new google.maps.LatLng(restaurant.coords.latitude, restaurant.coords.longitude),
title: restaurant.name
});
vm.mapMarkers.push(marker);
});
};
$ionicPlatform.ready(function() {
setMapBounds();
});
})
So, my question is how do I center and zoom the map using multiple dynamically loaded markers? Also, how do I get an instance of googleMap.control (vm.googleMap.control) before the map is loaded?
Here's my code just in case anyone was wondering how to do this locally. This is a simple solution for what I needed and my indeed go back to angualr-google maps, but as of now this works fine in my application.
angular.module('myApp.controllers', [])
.controller('MapCtrl', function($scope) {
var vm = this;
vm.googleMap = null;
vm.mapMarkers = [];
var onSuccess = function(position) {
vm.userLocation.coords.latitude = position.coords.latitude;
vm.userLocation.coords.longitude = position.coords.longitude;
initializeMap();
};
var onError = function(error) {
alert('code: ' + error.code + '\n' + 'message: ' + error.message);
};
vm.userLocation = {
id: "home",
title: "home",
coords: {
latitude: 33.636727,
longitude: -83.920702
},
options: {
animation: google.maps.Animation.BOUNCE
}
};
vm.places = [
{
id: "78869C43-C694-40A5-97A0-5E709AA6CE51",
title: "Place A",
coords: {
latitude: 33.625296,
longitude: -83.976206
}
},
{
id: "52319278-83AA-46D4-ABA6-307EAF820E77",
title: "Place B",
coords: {
latitude: 33.576522,
longitude: -83.964981
}
}
];
var addMarkers = function() {
var userLocation = new google.maps.Marker({
map: vm.googleMap,
position: new google.maps.LatLng(vm.userLocation.coords.latitude, vm.userLocation.coords.longitude),
//animation: vm.userLocation.options.animation,
title: vm.userLocation.title
});
vm.mapMarkers.push(userLocation);
angular.forEach(vm.places, function(location, index) {
var marker = new google.maps.Marker({
map: vm.googleMap,
position: new google.maps.LatLng(location.coords.latitude, location.coords.longitude),
title: location.title
});
vm.mapMarkers.push(marker);
});
var bounds = new google.maps.LatLngBounds();
for (var i = 0; i < vm.mapMarkers.length; i++) {
bounds.extend(vm.mapMarkers[i].getPosition());
}
vm.googleMap.setCenter(bounds.getCenter());
vm.googleMap.fitBounds(bounds);
//remove one zoom level to ensure no marker is on the edge.
vm.googleMap.setZoom(vm.googleMap.getZoom() - 1);
// set a minimum zoom
// if you got only 1 marker or all markers are on the same address map will be zoomed too much.
if (vm.googleMap.getZoom() > 15) {
vm.googleMap.setZoom(15);
}
};
var initializeMap = function() {
var mapOptions = {
mapTypeId: google.maps.MapTypeId.ROADMAP,
zoom: 12,
center: new google.maps.LatLng(vm.userLocation.coords.latitude, vm.userLocation.coords.longitude)
};
var div = document.getElementById("map_canvas");
//var map = plugin.google.maps.Map.getMap(div, mapOptions);
vm.googleMap = new google.maps.Map(div, mapOptions);
addMarkers();
var width = screen.width;
var height = screen.height;
};
navigator.geolocation.getCurrentPosition(onSuccess, onError);
})
Your previous answer is good but doesn't include usage of the google maps directives you mentioned in the begining of the post. There is a way to do it using those directives, here is how:
Assuming we are in the directive's scope
Define scope.mapControl = {}; - this will have new access methods for map and markers
When defining your markup for the directives - for map and marker - include this control attribute to be added:
<ui-gmap-google-map center='map.center' zoom='map.zoom' control="mapControl">
<ui-gmap-marker ng-repeat="location in locations" coords="location.coordinates" options="location.markerOptions" idkey="location.id" control="mapControl">
<ui-gmap-window options="location.markerWindowOptions" closeclick="closeMarkerWindow(location.id)" show="true">
<div>{{location.description}}</div>
</ui-gmap-window>
</ui-gmap-marker>
</ui-gmap-google-map>
In your directive's event or some method:
var map = scope.mapControl.getGMap();
var markers = scope.mapControl.getGMarkers();
var bounds = map.getBounds();
for (var i = 0; i < markers.length; i++) {
bounds.extend(markers[i].getPosition());
}
map.setCenter(bounds.getCenter());
map.fitBounds(bounds);
map.setZoom(map.getZoom() - 1);

Weird behavior of angular-google-maps in Safari

Im using this project (http://angular-google-maps.org/#!/) to work with AngularJS. My code seems like:
app.js
function ( $scope, markerService ) {
var markerCollection = [];
angular.extend($scope, {
map: {
control: {},
center: {
latitude: 33.5,
longitude: -112
},
zoom: 10,
fit: true,
visible: true,
pan: true,
options: {
navigationControl: true,
scaleControl: true
}
}
});
var setMapMarkers = function (){
var markers = {};
var index = 0;
angular.forEach($scope.services, function (key) {
var service = key.address;
markerCollection.push(service);
var serviceId = service.service.id;
markers[index] = {
"latitude": parseFloat(service.latitude),
"longitude": parseFloat(service.longitude)
};
index++;
});
$scope.markers = markers;
};
setMapMarkers();
}
Im getting this behavior in Safari and its a very weird.
https://www.dropbox.com/s/r7iwlr9mnboem1d/MapGrab.mov?dl=0
Someone maybe know what can be the problem?

Gmap API V3 marker coordinates

I have found example if someone need however I need to get first coordinates from address so later can adjust it. Someone knows how to do it?
var geocoder = new google.maps.Geocoder();
function geocodePosition(pos) {
geocoder.geocode({
latLng: pos
}, function(responses) {
if (responses && responses.length > 0) {
updateMarkerAddress(responses[0].formatted_address);
} else {
updateMarkerAddress('Cannot determine address at this location.');
}
});
}
function updateMarkerStatus(str) {
document.getElementById('markerStatus').innerHTML = str;
}
function updateMarkerPosition(latLng) {
document.getElementById('info').innerHTML = [
latLng.lat(),
latLng.lng()
].join(', ');
}
function updateMarkerAddress(str) {
document.getElementById('address').innerHTML = str;
}
function initialize() {
var latLng = new google.maps.LatLng(1.54232,-1.4353423);
var map = new google.maps.Map(document.getElementById('mapCanvas'), {
zoom: 8,
center: latLng,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var marker = new google.maps.Marker({
position: latLng,
title: 'Point A',
map: map,
draggable: true
});
// Update current position info.
updateMarkerPosition(latLng);
geocodePosition(latLng);
// Add dragging event listeners.
google.maps.event.addListener(marker, 'dragstart', function() {
updateMarkerAddress('Dragging...');
});
google.maps.event.addListener(marker, 'drag', function() {
updateMarkerStatus('Dragging...');
updateMarkerPosition(marker.getPosition());
});
google.maps.event.addListener(marker, 'dragend', function() {
updateMarkerStatus('Drag ended');
geocodePosition(marker.getPosition());
});
// Onload handler to fire off the app.
google.maps.event.addDomListener(window, 'load', initialize);
if your browser support the geolocation you want get coordinate with this function :
navigator.geolocation.getCurrentPosition(function(position) {
geolocationCoordinates = new google.maps.LatLng(position.coords.latitude,position.coords.longitude);
//position.coords.latitude = latitude coordonates;
//position.coords.longitude = longitude coordonates;
}
after, you can create a new map whith this coordonates.
This code is functional with all browser supporting the geolocation.

Resources