I am trying to display markers after the map is displayed. I am unable to do so.. regardless of any error. I have assured that the snapshot is with the data and marker array is nicely created. is there any logical error?? please help.
var apps = angular.module('appa',['firebase','uiGmapgoogle-maps']);
apps.controller('mainCtrl', function($firebaseObject,$scope){
var ref = firebase.database().ref();
var marker = [];
ref.once("value")
.then(function(snapshot)
{
snapshot.forEach(function(child)
{
var mark = {
id: child.child("Id").val(),
coords: {
latitude: child.child("Lat").val(),
longitude: child.child("Long").val()
},
options: { title: child.child("Alt").val() }
};
marker.push(mark);
});
});
$scope.map = {
center:
{
latitude: 67,
longitude: 24
},
zoom: 3
};
});
<body ng-app="apps">
<div id="map_canvas" ng-controller="mainCtrl">
<ui-gmap-google-map center="map.center" zoom="map.zoom">
<ui-gmap-marker ng-repeat="m in marker" coords="m.coords" options="m.options" idkey="m.id">
</ui-gmap-marker>
</ui-gmap-google-map>
</div>
<!--example-->
</body>
oh! I hot the answer my self. It was a simple mistake. I did not defined marker array in $scope. Therefore views were not getting what var marker is. I corrected it
Related
I'm using ngMap on a project where I have different maps on different views. I have one initial page where I show a map and draw a polygon and some markers. My controller is like this:
$scope.showInitialMap = function( map ) {
/*Resize image to show on map*/
var iconGood = {
url: 'modules/cars/img/ambulance_ok.png',
scaledSize: new google.maps.Size( 40, 40 ),
origin: new google.maps.Point( 0, 0 ),
anchor: new google.maps.Point( 0, 0 )
};
/*Get all cars*/
$scope.tracks = Tracks.getTaxisRealTime( function() {
angular.forEach( $scope.tracks, function( c ) {
var infowindow = new google.maps.InfoWindow( {
content: contentString
} );
/*Set marker position fo each car*/
var marker = new google.maps.Marker( {
position: {
lat: c.Latitude,
lng: c.Longitude
},
icon: iconGood,
map: map
} );
} );
/*draw map*/
setArea( map );
} );
};
and I just add it to the view like this:
<section data-ng-controller="MapsCtrl" ng-init="InitTaxiHistory()">
<ng-map center="[19.54, -96.91]" zoom="13" style="height: 600px;" min-zoom="12">
</ng-map>
</section>
The problem is that when I go to a different view where I also show a map, it keeps the same state where I left the previous map.
How do I reset the map? Or how create 2 different instances for a map?
Creating new instance of Google Map will make question complex and not recommended at all.
see relevant issues:
What is the Proper Way to Destroy a Map Instance?
How to destroy or reset map?
Solution
And for your situation, you can deal with each ng-map with making googlemap show different things according to your current controller.
<ng-map>
<marker ng-repeat="marker in tracks" position="{{marker. Latitude}}, {{marker. Longitude}}"></marker>
<ng-map>
the markers will be removed automitically if there isn't data in $scope.tracks and if $scope.tracks is undefined.
Plunker demo.
Since NgMap extends google.maps.Map object to store all the objects (markers, shapes) you could clear the map by calling setMap() method:
$scope.clearMap = function () {
//clear markers
for (var k in $scope.map.markers) {
$scope.map.markers[k].setMap(null);
}
//clear shapes
for (var k in $scope.map.shapes) {
$scope.map.shapes[k].setMap(null);
};
};
Example
var app = angular.module('appMaps', ['ngMap']);
app.controller('mapCtrl', function ($scope, NgMap) {
$scope.cities = [
{ id: 1, name: 'Oslo', pos: [59.923043, 10.752839] },
{ id: 2, name: 'Stockholm', pos: [59.339025, 18.065818] },
{ id: 3, name: 'Copenhagen', pos: [55.675507, 12.574227] },
{ id: 4, name: 'Berlin', pos: [52.521248, 13.399038] },
{ id: 5, name: 'Paris', pos: [48.856127, 2.346525] }
];
NgMap.getMap().then(function (map) {
$scope.map = map;
});
$scope.clearMap = function () {
//clear markers
for (var k in $scope.map.markers) {
$scope.map.markers[k].setMap(null);
}
//clear shapes
for (var k in $scope.map.shapes) {
$scope.map.shapes[k].setMap(null);
};
};
$scope.showMap = function () {
//clear markers
for (var k in $scope.map.markers) {
$scope.map.markers[k].setMap($scope.map);
}
//clear shapes
for (var k in $scope.map.shapes) {
$scope.map.shapes[k].setMap($scope.map);
};
};
});
<script src="https://maps.googleapis.com/maps/api/js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<script src="https://rawgit.com/allenhwkim/angularjs-google-maps/master/build/scripts/ng-map.js"></script>
<div ng-app="appMaps" ng-controller="mapCtrl">
<button ng-click="clearMap()">Clear All</button>
<button ng-click="showMap()">Show All</button>
<map center="[59.339025, 18.065818]" zoom="4">
<marker id='ID{{city.id}}' ng-repeat="city in cities" position="{{city.pos}}" >
</marker>
<shape name="rectangle" bounds="[ [57.190, 16.149], [59.899, 20.443] ]"></shape>
</map>
</div>
I've been having a problem very similar to this
However that persons question was never answered and my situation is subtly different.
I'm trying to add a click event to my map that will change the center of the map to the location of the click. My code to do this works great, but it only works once and then when I click again I get this error:
angular-google-maps.js:6815 Uncaught TypeError: Cannot read property 'click' of undefined
Here is my map object:
vm.map = {
center: {
latitude: l.latitude,
longitude: l.longitude
},
zoom: 13,
events: {
click: function(map, event, coords) {
vm.map = {
center: {
latitude: coords[0].latLng.lat(),
longitude: coords[0].latLng.lng()
},
};
$scope.apply();
}
}
};
And here's my html:
<ui-gmap-google-map center="location.map.center" zoom="location.map.zoom" draggable="true" options="tabLocations.map.options" events=location.map.events>
<ui-gmap-search-box template="'scripts/components/tab-locations/searchbox.tpl.html'" events="location.map.searchbox.events" parentdiv="'searchbox-container'"></ui-gmap-search-box>
<ui-gmap-marker ng-if="location.active" idKey="1" coords="location" options="{draggable: false, icon: 'images/icons/gps-marker-active.svg'}"></ui-gmap-marker>
<ui-gmap-marker ng-if="!location.active" idKey="1" coords="location" options="{draggable: false, icon: 'images/icons/gps-marker-inactive.svg'}"></ui-gmap-marker>
</ui-gmap-google-map>
After your first click you are redefining a brand new map with no click event:
vm.map = {
center: {
latitude: coords[0].latLng.lat(),
longitude: coords[0].latLng.lng()
},
};
This is overriding all the previous properties you had set before, which includes click.
Use setCenter instead:
click: function(map, event, coords) {
var latLng = new google.maps.LatLng(latitude: coords[0].latLng.lat(), latitude: coords[0].latLng.lng());
vm.map.setCenter(latLng);
}
Reference: Google Maps API
I am trying to create dynamic markers to load information from my json file. For some reason, the json data never loads. When I try to load one marker, it works fine without the json data. I don't see what the error is. In the console, it says "TypeError: (intermediate value).error is not a function". Here is the code below.
html script link
<script src="https://maps.googleapis.com/maps/api/js?CLIENT ID HERE
&v=3.21&callback=initMap"
async defer></script>
External JS
var map;
function initMap() {
var myLatlng = {
lat: -25.363,
lng: 131.044
};
var centerZone = {
lat: 0,
lng: 0
};
map = new google.maps.Map(document.getElementById('map'), {
center: centerZone,
zoom: 3,
minZoom: 3
});
$.getJSON('data/data.json', function(data) {
$.each(data.markers, function(i, value) {
var myLatlng = new google.maps.LatLng(value.lat, value.lon);
alert(myLatlng);
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
title: value.lon
});
});
}.error(function(words) {
alert(words);
}));
var secretMessages = ['This', 'is', 'the', 'secret', 'message'];
/*marker.addListener('click', function() {
map.setZoom(6);
map.setCenter(marker.getPosition());
attachSecretMessage(marker, secretMessages[0]);
});*/
function attachSecretMessage(marker, secretMessage) {
var infowindow = new google.maps.InfoWindow({
content: secretMessage
});
marker.addListener('click', function() {
infowindow.open(marker.get('map'), marker);
});
}
// google.maps.event.addDomListener(window, 'load', initMap);
}
json data
{
"markers": [
{
"id": "1",
"name": "Mesoamerica",
"lat": "-25.363",
"lon": "131.044",
"zoomLevel": "6"
}
]
}
The json data will have more objects inside, this is just a sample of how I want it.
You need to wait until the JSON data loads before doing anything with it. I suggest placing everything that relies on the JSON file in a $.done() function, like this:
$.getJSON('data/data.json').done(function(data){
//everything else
});
Your browser will continue with the other lines of code while it's waiting for the $.getJSON function to return the data. That's why you're getting the "not a function" error; you're trying to call a function on something that doesn't exist and JS doesn't know what to do with it. If you place everything in $.done(), those lines won't execute until the JSON data has successfully been retrieved.
I am using Angular-google-maps, HTML code follows
<ui-gmap-google-map center='mapData.map.center' zoom='mapData.map.zoom'
events="mapEvents">
<ui-gmap-markers models="mapData.map.markers" coords="'self'">
</ui-gmap-markers>
</ui-gmap-google-map>
in JS calling
angular.extend(this, $controller('MapsMixinController',
{$scope:$scope, map:mapData.data[0].map}));
MapsMixinController as follows. Calling this controller from js code. Markers are showing & on click able to mark.
MapsMixinController.js
/**
* Controller providing common behaviour for the other map controllers
*/
angular
.module('app')
.controller('MapsMixinController', ['$scope', 'GeolocationService', 'uiGmapGoogleMapApi', 'map',
function($scope, GeolocationService, GoogleMapApi, map) {
var _this = this;
$scope.mapEvents = {
click: function(mapModel, eventName, originalEventArgs) {
var e = originalEventArgs[0];
if (e.latLng) {
$scope.mapData.map.markers.push({
id: new Date().getTime(),
latitude: e.latLng.lat(),
longitude: e.latLng.lng()
});
// This event is outside angular boundary, hence we need to call $apply here
$scope.$apply();
}
}
};
// Returns a default map based on the position sent as parameter
this.getDefaultMap = function(position) {
return {
markers: [],
center: {
latitude: position.coords.latitude,
longitude: position.coords.longitude
},
zoom: 14
};
};
// Initialize the google maps api and configure the map
GoogleMapApi.then(function() {
GeolocationService().then(function(position) {
$scope.mapData.map = map || _this.getDefaultMap(position);
}, function() {
$scope.error = "Unable to set map data"; // TODO use translate
});
});
}
]);
How can I show title on mouse hover on markers? And on click how to show description on markers?
You can add title property alone with latitude and longtitude property while creating marker data.
/**
* Controller providing common behaviour for the other map controllers
*/
angular
.module('app')
.controller('MapsMixinController', ['$scope', 'GeolocationService', 'uiGmapGoogleMapApi', 'map',
function($scope, GeolocationService, GoogleMapApi, map) {
var _this = this;
$scope.mapEvents = {
click: function(mapModel, eventName, originalEventArgs) {
var e = originalEventArgs[0];
if (e.latLng) {
$scope.mapData.map.markers.push({
id: new Date().getTime(),
latitude: e.latLng.lat(),
longitude: e.latLng.lng(),
title: "Mouse over text"
});
// This event is outside angular boundary, hence we need to call $apply here
$scope.$apply();
}
}
};
// Returns a default map based on the position sent as parameter
this.getDefaultMap = function(position) {
return {
markers: [],
center: {
latitude: position.coords.latitude,
longitude: position.coords.longitude
},
zoom: 14
};
};
// Initialize the google maps api and configure the map
GoogleMapApi.then(function() {
GeolocationService().then(function(position) {
$scope.mapData.map = map || _this.getDefaultMap(position);
}, function() {
$scope.error = "Unable to set map data"; // TODO use translate
});
});
}
]);
I use Google Maps for AngularJS
to put some markers with infoWindow.
It can open infoWindow when a marker is clicked.
But it cannot close the opened infoWindow when another marker is clicked.
<div id="map" ng-controller="MapCtrl">
<google-map
center="map.center"
zoom="map.zoom"
draggable="true"
dragging="map.dragging"
events="map.events"
control="map.control"
refresh="true">
<markers models="map.markers" coords="'self'" icon="'icon'" click="'onClicked'">
<windows show="'showWindow'" closeClick="'closeClick'" ng-cloak>
<img ng-non-bindable src="{{url}}" width="200px;" class="img-responsive" />
</windows>
</markers>
</google-map>
</div>
Here is the controller.js
var mapControllers = angular.module('mapControllers', ['google-maps']);
mapControllers.controller('MapCtrl', function($scope, $http) {
var onMarkerClicked = function (marker) {
_.each($scope.map.markers, function (mker) {
mker.showWindow = false;
});
$scope.$apply();
marker.showWindow = true;
};
$scope.map = {
current_marker: {},
control:{},
markers: [],
center: {
latitude: 35.4138,
longitude: 139.4505
},
zoom: 6,
dragging: true
};
$http.get('/v1/tweets').success(function(data) {
for (var i = 0; i < data.length; i++) {
var marker = {
latitude: data[i].lat,
longitude: data[i].lon,
text: data[i].text,
url: data[i].url,
icon: '/assets/flower.png',
showWindow: false
};
marker.closeClick = function () {
marker.showWindow = false;
$scope.$apply();
};
marker.onClicked = function () {
onMarkerClicked(marker);
};
$scope.map.markers.push(marker);
}
});
});
How can I change this code ?
Dirty hack with jQuery:
$("img[src='https://maps.gstatic.com/mapfiles/api-3/images/mapcnt3.png']").click();
Close/click all open windows before showing new Infowindow.