Set Google Maps bounds with angular-google-maps - angularjs

I'm trying to set bounds into Google Maps instance but with no success. I'm using AngularJS and angular-google-maps module. My last try was:
<div id="map_canvas">
<ui-gmap-google-map
center="map.center"
zoom="map.zoom"
bounds="map.bounds"
options="options">
<div ng-repeat="d in devicesMarkers track by d.id">
<ui-gmap-marker
idkey="d.id"
coords="d.center"
options="d.options">
</ui-gmap-marker>
<ui-gmap-circle
center="d.center"
stroke="d.circle.stroke"
fill="d.circle.fill"
radius="d.circle.radius"
visible="d.options.visible">
</ui-gmap-circle>
</div>
</ui-gmap-google-map>
</div>
In my app.js I wrote:
(...)
.controller('TaihMapController', ['$scope', '$log', 'uiGmapGoogleMapApi', function($scope, $log, GoogleMapApi) {
$scope.devicesMarkers = devices;
$scope.map = {
center: { latitude: devices[0].center.latitude, longitude: devices[0].center.longitude },
zoom: 12,
bounds: {}
// fit: true,
};
GoogleMapApi.then(function(maps) {
$log.debug(maps);
var myBounds = new maps.LatLngBounds();
for (var k = 0; k < devices.length; k++) {
var _tmp_position = new maps.LatLng(
devices[k].center.latitude,
devices[k].center.longitude);
myBounds.extend(_tmp_position);
}
$scope.map.bounds = myBounds;
$scope.googleVersion = maps.version;
// $scope.bounds = myBounds;
// $scope.zoom = maps.getZoom();
// maps.fitBounds(myBounds);
// $scope.bounds = maps.getBounds();
});
The function maps.fitBounds() doesn't exist. I try the $scope.map.bounds approach, but didn't respond the way I think.

If you're using angular-google-map's "markers" directive, just add the fit="true" attribute (ui-gmap-markers).
Example :
<ui-gmap-google-map center="map.center" zoom="map.zoom" options="map.options">
<ui-gmap-markers fit="true" models="markers" coords="'self'"></ui-gmap-markers>
</ui-gmap-google-map>
Source:
https://stackoverflow.com/a/29707965

According to docs, directives bounds is slightly different with google maps bounds. You should explicitly set northeast and southwest attributes with their own latitude and longitude.
Below should work:
$scope.map.bounds = {
northeast: {
latitude: myBounds.getNorthEast().lat(),
longitude: myBounds.getNorthEast().lng()
},
southwest: {
latitude: myBounds.getSouthWest().lat(),
longitude: myBounds.getSouthWest().lng()
}
};

Related

AngularJS change variable outside of function

I have a function in Angular that changes the center value for Google Maps when a user clicks on the map. The correct center value is then alerted to the screen but the marker does not change to that position like it should.
Web page: http://alainwebdesign.ca/pl2/#/getLocation
Controller:
.controller('GetlocationCtrl', ['$scope', "uiGmapLogger", "uiGmapGoogleMapApi", "$state", "$stateParams",
function ($scope, $log, GoogleMapApi, $state, $stateParams) {
$log.currentLevel = $log.LEVELS.debug;
center = { latitude: 49.22, longitude: -122.66 }; //default center
alert(JSON.stringify(center));
console.log($stateParams);
$scope.map = {
center: center,
pan: false,
zoom: 16,
refresh: false,
events:
{ click: function newCenter(mapModel, eventName, originalEventArgs)
{
$scope.$apply(function(){
var e = originalEventArgs[0];
center = { latitude: e.latLng.lat(), longitude: e.latLng.lng() };
alert(JSON.stringify(center));
return center;
});
}
}
}
HTML partial/view:
<!--Add ability to input location as address-->
<div style="height: 100%">
<h1>TEST</h1> <!--NOT SHOWING ON PAGE WHICH MEANS THIS IS NOT BEING INVOKED WHEN
URL IS: '/getLocation' like it should-->
<ui-gmap-google-map
center='map.center'
zoom='map.zoom'
draggable='map.draggable'
dragging='map.dragging'
refresh='map.refresh'
options='map.options'
events='map.events'
pan='map.pan'>
<ui-gmap-marker
idKey='1'
events='map.events'
coords='map.center'
>
</ui-gmap-marker>
</ui-gmap-google-map>
<script src='//maps.googleapis.com/maps/api/js?key=AIzaSyD4_0KuPivZyV-1EwNGmBCgLc_Z0o8Dyw8'></script>
</div>
You can directly set $scope.map.center instead of center variable and it will be ok. Here is working click function example:
click: function newCenter(mapModel, eventName, originalEventArgs)
{
$scope.$apply(function(){
var e = originalEventArgs[0];
$scope.map.center = { latitude: e.latLng.lat(), longitude: e.latLng.lng() };
});
}

AngularJS ng-click not firing using angular-google-maps' windows

I wanted to automatically center the map to the user's location once loaded so I used $scope.$apply() once geolocation is loaded as seen in my TestCtrl in controller.js here:
$scope.drawMap = function(position) {
$scope.$apply(function() {
$scope.myLocation.lng = position.coords.longitude;
$scope.myLocation.lat = position.coords.latitude;
$scope.map = {
center: {
latitude: $scope.myLocation.lat,
longitude: $scope.myLocation.lng
},
zoom: 14,
events: {
click: $scope.clickCallback
}
};
});
};
navigator.geolocation.getCurrentPosition($scope.drawMap);
$scope.test = function(){
alert("hola");
};
The $scope.clickCallback is used to push new markers to the map on click event.
// inside TestCtrl
var markers = [], counter = 1;
$scope.clickCallback = function(map, eventName, event){
var lat = event[0].latLng.lat();
var lng = event[0].latLng.lng();
markers.push(createNewMarker(counter, lat, lng));
$scope.$apply(function(){
$scope.newMarker = markers;
});
counter++;
};
As you can see, there's another $scope.$apply there to apply the new marker/s.
The createNewMarker() is where the markers (ui-gmap-markers) models is defined.
// still inside TestCtrl
var createNewMarker = function(i, lat, lng, idKey) {
if (idKey == null) {
idKey = "id";
}
var foo = "<h4>New Marker</h4><form><input type='text' placeholder='Event name' name='name'></input> <input type='button' value='submit'></input><input type='button' ng-click='test()' value='Delete marker'></input></form>";
var bar = $compile(foo)($scope);
var ret = {
latitude: lat,
longitude: lng,
show: true,
options: {
draggable: true,
animation: google.maps.Animation.DROP,
},
windows: {
title: "New Marker",
},
windowsOptions: {
content: foo,
}
};
ret[idKey] = i;
return ret;
};
Now the marker is showing fine when I click on the map including the window, but when I click on the Delete marker button, my $scope.test() function isn't firing up. I tried using $compile but it returns a bunch of error about $scope.
Here's my template:
<ion-content scroll="false">
<ui-gmap-google-map center='map.center' zoom='map.zoom' bounds="map.bounds" events="map.events">
<ui-gmap-markers models="newMarker" coords="'self'" icon="'icon'" options="'options'">
<ui-gmap-windows show="show" options="'windowsOptions'">
</ui-gmap-windows>
</ui-gmap-markers>
</ui-gmap-google-map>
</ion-content>
Anyone familiar with this scenario? I'm using Ionic Framework btw.
It does not have to be this complex.
As a creator of ngMap, I would recommend this,
http://ngmap.github.io/drawings.html#/marker-remove#marker-remove
To set the current location, just use current-location
<map center="current-location" zoom="12" on-click="addMarker()">
<marker ng-repeat="pos in positions" position="{{pos.lat}}, {{pos.lng}}"></marker>
</map>
http://plnkr.co/edit/e1SioHQ6NTSYCp0EbR0x?p=preview

angular google map searchbox - places_changed is not called from the $route.current controller

I'm having an issue with angular google maps and the search box.
Even if the ng-view onLoad works as expected, after typing in the search box, the places_changed callbacks are not called from the correct controller but only from the first one (and the default) defined in $routeProvider.
You can find more details below:
Part of the template:
<div ng-controller="map">
<div>
<script type="text/ng-template" id="searchbox.tpl.html">
<input type="text" placeholder="Search Place..." class="google-maps-search">
</script>
<ui-gmap-google-map center='map.center' events="map.events" options="map.options" zoom='map.zoom'>
<ui-gmap-search-box template="map.searchbox.template" events="map.searchbox.events" position="BOTTOM_RIGHT"></ui-gmap-search-box>
<ui-gmap-marker coords="map.marker.coords" options="map.marker.options" events="map.marker.events" idkey="map.marker.id"></ui-gmap-marker>
<ui-gmap-markers models="mapMarkers" coords="'self'" icon="'icon'">
<ui-gmap-windows show="show">
<div ng-non-bindable>{{title}}</div>
</ui-gmap-windows>
</ui-gmap-markers>
</ui-gmap-google-map>
</div>
<div><div ng-view="" onload="renderView()"></div></div>
Part of the parent controller:
app.controller('map', function ($scope, $log, $location) {
$scope.map = {
events: {
click: function(map, eventName, args) {}
},
marker: {
id: 0,
coords: {
latitude: $scope.lat,
longitude: $scope.lng
},
options: { draggable: true }
},
searchbox: {
template: 'searchbox.tpl.html',
events: {
places_changed: function (searchBox) {}
}
}
};
});
And the following in each of the children controllers (defined in $routeProvider):
$scope.map.searchbox.events.places_changed = function (searchBox) {
var place = searchBox.getPlaces();
if (!place || place == 'undefined' || place.length == 0) {
console.log('no place data :(');
return;
}
$scope.lat = place[0].geometry.location.lat();
$scope.lng = place[0].geometry.location.lng();
$scope.map.center = {
"latitude": $scope.lat,
"longitude": $scope.lng
};
$scope.renderView();
};
Do you have any ideas?

angular-google-maps causes "TypeError: undefined is not a function" with angularjs 1.3

I've implemented a very basic map using the angular-google-maps module. After the page has finished processing all scripts, I will always find a "TypeError: undefined is not a function" logged in the Chrome Developer Tools console, even though everything seems to work as expected.
It happens when $scope.control.getGMap().fitBounds($scope.bounds); is called within the uiGmapIsReady promise function.
angular.module('app', ['uiGmapgoogle-maps'])
.config(function (uiGmapGoogleMapApiProvider) {
uiGmapGoogleMapApiProvider.configure({
// key: 'your api key',
v: 3.17,
libraries: 'weather,geometry,visualization'
});
})
.controller('MainController', ['$scope', '$timeout', 'uiGmapGoogleMapApi', 'uiGmapIsReady', function ($scope, $timeout, uiGmapGoogleMapApi, uiGmapIsReady) {
$scope.markers = [
{ latitude: 33.970675, longitude: -118.454618},
{ latitude: 33.980675, longitude: -118.454618},
{ latitude: 33.974246, longitude: -118.455458}
]
uiGmapGoogleMapApi.then(function (maps) {
$scope.bounds = new maps.LatLngBounds();
angular.forEach($scope.markers, function (value, key) {
var myLatLng = new maps.LatLng($scope.markers[key].latitude, $scope.markers[key].longitude);
$scope.bounds.extend(myLatLng);
});
$scope.map = { center: { latitude: $scope.bounds.getCenter().lat(), longitude: $scope.bounds.getCenter().lng() }, zoom: 5 };
$scope.map.options = { MapTypeId: maps.MapTypeId.HYBRID };
});
$scope.control = {};
uiGmapIsReady.promise().then((function (maps) {
$scope.control.getGMap().fitBounds($scope.bounds);
}));
$scope.refreshMap = function () {
$scope.control.refresh({ latitude: $scope.bounds.getCenter().lat(), longitude: $scope.bounds.getCenter().lng() });
}
$scope.streetZoom = function () {
$scope.control.getGMap().setZoom(14);
}
}])
And here is the markup
<ui-gmap-google-map
center="map.center"
zoom="map.zoom"
options="map.options"
control="control">
<ui-gmap-marker idkey="$index" coords="item" ng-repeat="item in markers track by $index">
<ui-gmap-window options="windowOptions" closeclick="closeClick()">
<p class="google-window">{{item.latitude}}, {{item.longitude}}</p>
</ui-gmap-window>
</ui-gmap-marker>
</ui-gmap-google-map>
And here is the error message:
TypeError: undefined is not a function angular.js:11655
Any insight as to why this happens would greatly be appreciated! I feel like I've broken something and don't know why.

Working example of angular-google-maps search function

Does anyone have an example of a working search box like the one the angular-google-maps-team is showing under 'search-box' on this site: https://angular-ui.github.io/angular-google-maps/#!/api
If you write something it sure does find it in a dropdown, but when you press enter, the map doesn't respond. - How can you make the map move to the correct location when you hit enter?
html:
<ui-gmap-google-map center="map.center" zoom="map.zoom" draggable="true">
<ui-gmap-search-box template="searchbox.template" events="searchbox.events" position="BOTTOM_RIGHT"></ui-gmap-search-box>
<ui-gmap-marker coords="marker.coords" options="marker.options" events="marker.events" idkey="marker.id">
</ui-gmap-google-map>
js controller:
$scope.map = {
"center": {
"latitude": 52.47491894326404,
"longitude": -1.8684210293371217
},
"zoom": 15
}; //TODO: set location based on users current gps location
$scope.marker = {
id: 0,
coords: {
latitude: 52.47491894326404,
longitude: -1.8684210293371217
},
options: { draggable: true },
events: {
dragend: function (marker, eventName, args) {
$scope.marker.options = {
draggable: true,
labelContent: "lat: " + $scope.marker.coords.latitude + ' ' + 'lon: ' + $scope.marker.coords.longitude,
labelAnchor: "100 0",
labelClass: "marker-labels"
};
}
}
};
var events = {
places_changed: function (searchBox) {
var place = searchBox.getPlaces();
if (!place || place == 'undefined' || place.length == 0) {
console.log('no place data :(');
return;
}
$scope.map = {
"center": {
"latitude": place[0].geometry.location.lat(),
"longitude": place[0].geometry.location.lng()
},
"zoom": 18
};
$scope.marker = {
id: 0,
coords: {
latitude: place[0].geometry.location.lat(),
longitude: place[0].geometry.location.lng()
}
};
}
};
$scope.searchbox = { template: 'searchbox.tpl.html', events: events };
I suggest you look at examples sent to angular-google-maps github.
There's a piece of JavaScript lacking in 123Tax response which is found at https://github.com/angular-ui/angular-google-maps/blob/master/example/assets/scripts/controllers/search-box.js
And this snippet is loaded in https://github.com/angular-ui/angular-google-maps/blob/master/example/search-box.html
// the following controls the map in your Controller
$scope.map = { control: {}, center: { latitude: 37.70, longitude: -122.344 }, zoom: 9, refresh: {}};
function placeToMarker(searchBox, id) {
var place = searchBox.getPlaces();
if (!place || place == 'undefined' || place.length == 0) {
return;
}
var marker = {
id: id,
place_id: place[0].place_id,
name: place[0].name,
address: place[0].formatted_address,
latitude: place[0].geometry.location.lat(),
longitude: place[0].geometry.location.lng(),
latlng: place[0].geometry.location.lat() + ',' + place[0].geometry.location.lng()
};
// push your markers into the $scope.map.markers array
if (!$scope.map.markers) {
$scope.map.markers = [];
}
// THIS IS THE KEY TO RECENTER/REFRESH THE MAP, to your question
$scope.map.control.refresh({latitude: marker.latitude, longitude: marker.longitude});
// the following defines the SearchBox on your Controller; events call placeToMarker function above
var searchBoxEvents = {
places_changed: function (searchBox) {
placeToMarker(searchBox, id);
}
};
// this is defined on the Controller, as well. This specifies which template searchBoxEvents should match to; note the parentdiv
$scope.searchBox = { template:'searchBox.template.html', events:searchBoxEvents, parentdiv: 'searchBoxParent'};
// in your HTML, declare where you want the searchBox. parentdiv: 'searchBoxParent' above looks for the id="searchBoxParent" in HTML
<div class="col-xs-12 col-md-12" id="searchBoxParent">
<script type="text/ng-template" id="searchBox.template.html">
<input type="text" ng-model="address" placeholder="Search Address" required />
</script>
</div>
//Lastly, in HTML, make sure you wrap ui-gmap-search-box & ui-gmap-markers in ui-gmap-google-map
<ui-gmap-google-map id="map-canvas" center="map.center" zoom="map.zoom" draggable="true" options="options" control="map.control">
<ui-gmap-search-box template="searchBox.template" events="searchBox.events" parentdiv="searchBox.parentdiv"></ui-gmap-search-box>
<ui-gmap-markers idkey="map.idkey" models="map.markers" coords="'self'" icon="'icon'" click="'onClicked'" fit="true"></ui-gmap-markers>
</ui-gmap-google-map>
Gavin's answer is correct,just some more details about the 'searchbox.tpl.html of his example.
It has to be placed outside of the directive like this:
<body>
<div id="searchBoxParent"></div>
<div id="map_canvas" ng-controller="mainCtrl">
<script type="text/ng-template" id="searchbox.tpl.html">
<input type="text" placeholder="Search Box">
</script>
<ui-gmap-google-map center="map.center" zoom="map.zoom" draggable="true" options="options">
<ui-gmap-search-box template="searchbox.template" events="searchbox.events" parentdiv="searchbox.parentdiv"></ui-gmap-search-box>
</ui-gmap-google-map>
</div>
<!--example-->
</body>
Working plunkr: http://embed.plnkr.co/1rpXQhcZqwJ7rv0tyK9P/ (for some reason the plunkr only worked in chrome for me but not in firefox)
I could not comment on Gavin's answer because of lack of repution, this is why I add the info as additional answer.

Resources