Ionic google map shows only first time a view is loaded - angularjs

My ionic app gets some places from the database and generates a map from this data.
$scope.$on('$ionicView.beforeEnter', function(){
// get event data
Events.getEvent($stateParams.eventId).then(function(data){
$scope.eventInfo = data[0];
$ionicLoading.hide();
// get location data
if(data[0].location){
Locations.getLocation(data[0].location).then(function(data){
$scope.location = data[0];
// call the map
$scope.initialize($scope.location.locstreet, $scope.location.zip, $scope.location.ort);
});
}
});
After retrieving the data, the script calls the initialize function:
function initialize(strasse, plz, ort) {
var map = new google.maps.Map(document.getElementById('map'),{
zoom: 14
});
img = new google.maps.MarkerImage("img/icon.png", null, null, null, new google.maps.Size(30,30));
var geocoder = new google.maps.Geocoder();
var address = strasse + ", " + plz + " " + ort;
geocoder.geocode({'address': address}, function(results, status) {
if (status === google.maps.GeocoderStatus.OK) {
map.setCenter(results[0].geometry.location);
var marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location,
icon: img
});
} else {
alert('Geocode was not successful for the following reason: ' + status);
}
});
}
This works great the first time I´m navigating to this view. If I leave the view and come back to the same view with other data, the map just shows grey with the google logo right bottom.
I think that this could happen because of the multiple intializing var map. But if I declare var map outside of the funktion it doesn´t work either.

Add this : cache: false to your state provider (when you defined your map).
This worked for me.

Related

How to write a function that is common for all the Controllers

I am developing an Micro finance Angular Application in that i am trying to locate the location of agent who login to my application...and i storing the details in collection(ActivityDetails)...But the requirement is quite different...like once the agent is logged in to our application means every One Hour the location should be tracked and stored in collection(ActivityDetails)...for this i used set interval function....it execute successfully but when i navigate to different controller the function is not executing because i write location tracking and storing code in SignIn Controller when it navigate to diff.. controller i am facing the problem ...How can i make these function globally that run successfully once logged in
and irrespective of any controller..please help me out to find solution for this....and i am new to Angular just i have 3 month of experience... below i am adding the function.. please verify and guide me..Thank You..
///////Signin Controller code for location tracking//////////
$scope.nearme = function(firstname,activity,date,time) {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function (position)
{
lat = position.coords.latitude;
lng = position.coords.longitude;
var latlng = new google.maps.LatLng(lat, lng);
var geocoder = geocoder = new google.maps.Geocoder();
geocoder.geocode({ 'latLng': latlng }, function (results, status)
{
if (status == google.maps.GeocoderStatus.OK)
{
if (results[1])
{
console.log(results[1].formatted_address)
console.log(firstname)
console.log(date)
console.log(time);
var obj={};
obj["User"]=firstname;
obj["Activity"]=activity;
obj["Date"]=$scope.date;
obj["Time"]=$scope.time;
obj["LocationDetails"]=results[1].formatted_address;
console.log(obj)
$http.post("/ncrActivityDetails",obj).success(function(res9){
console.log(res9)
})
}
}
});
});
}
}
/////////////setInterval Function for calling every one hour///////////
setInterval(function(){
$scope.date3 = {date1:new Date()}
$scope.activity="Tracking";
var dates = new Date(((new Date($scope.date3.date1).toISOString().slice(0, 23))+"-05:30")).toISOString();
var a = dates.split("T");
$scope.date = a[0];
$scope.time = a[1];
console.log($scope.date)
console.log($scope.time)
$scope.nearme($scope.firstname,$scope.activity,$scope.date,$scope.time);
},3600000);
////////////////ActivityDetails collection sample data/////////
{
"_id" : ObjectId("5a8a6936fa642a14149a12d1"),
"User" : "7829780519",
"Activity" : "Login",
"Date" : "2018-02-19",
"Time" : "11:35:26.777Z",
"LocationDetails" : "Sri laxmivenkateshwara, #1/10, 4th Main, Srinivasanagar, B S K 3rd Stage, Water Tank Rd, Banashankari 3rd Stage, Banashankari, Bengaluru, Karnataka 560085, India"
}
solutions: 1) create your function in your .run module so that it will work eventhough you have navigated to different controllers ,
check this link
.run(function($interval){
setInterval(function(){
$rootScope.nearme($scope.firstname,$scope.activity,$scope.date,$scope.time);},3600000);});
2) create a service - link

Bing Maps API V8 - map.layers.clear() method removes the polyline from map view

Some time ago, the map.layers.clear() method would not remove the polyline from the map, but now, after some Bing update, the polyline is being removed when map.layers.clear() is called. How can I solve this?
Map initialize
var map = new Microsoft.Maps.Map(document.getElementById('myMap'), {
credentials: 'Your Bing Maps Key',
center: new Microsoft.Maps.Location(47.606209, -122.332071),
zoom: 12
});
Here add pushpins
// Add pushpins
function addPushpins() {
// Generate an array of 10 random pushpins within current map bounds
var pushpins = Microsoft.Maps.TestDataGenerator.getPushpins(10, map.getBounds());
var layer = new Microsoft.Maps.Layer();
layer.add(pushpins);
map.layers.insert(layer);
}
Here is update direction callback
// On update directions callback
function onUpdateDirections() {
map.layers.clear();
}
Call addPushpins function
addPushpins();
Here is the Bing Maps Direction Manager sample code
Microsoft.Maps.loadModule('Microsoft.Maps.Directions', function() {
var directionsManager = new Microsoft.Maps.Directions.DirectionsManager(map);
// Set Route Mode to driving
directionsManager.setRequestOptions({
routeMode: Microsoft.Maps.Directions.RouteMode.driving
});
// Callback for on update directions
Microsoft.Maps.Events.addHandler(directionsManager, 'directionsUpdated', onUpdateDirections);
var waypoint1 = new Microsoft.Maps.Directions.Waypoint({
address: 'Redmond',
location: new Microsoft.Maps.Location(47.67683029174805, -122.1099624633789)
});
var waypoint2 = new Microsoft.Maps.Directions.Waypoint({
address: 'Seattle',
location: new Microsoft.Maps.Location(47.59977722167969, -122.33458709716797)
});
directionsManager.addWaypoint(waypoint1);
directionsManager.addWaypoint(waypoint2);
// Set the element in which the itinerary will be rendered
directionsManager.setRenderOptions({
itineraryContainer: document.getElementById('printoutPanel')
});
directionsManager.calculateDirections();
});
UPDATE - Removes partials pushpins
// Map initialize
var map, pushpins, layer;
map = new Microsoft.Maps.Map(document.getElementById('myMap'), {
credentials: 'Your Bing Maps Key',
center: new Microsoft.Maps.Location(47.606209, -122.332071),
zoom: 12
});
// Here is the Bing Maps Direction Manager sample code
Microsoft.Maps.loadModule('Microsoft.Maps.Directions', function() {
var directionsManager = new Microsoft.Maps.Directions.DirectionsManager(map);
// Set Route Mode to driving
directionsManager.setRequestOptions({
routeMode: Microsoft.Maps.Directions.RouteMode.driving
});
var waypoint1 = new Microsoft.Maps.Directions.Waypoint({
address: 'Redmond',
location: new Microsoft.Maps.Location(47.67683029174805, -122.1099624633789)
});
var waypoint2 = new Microsoft.Maps.Directions.Waypoint({
address: 'Seattle',
location: new Microsoft.Maps.Location(47.59977722167969, -122.33458709716797)
});
directionsManager.addWaypoint(waypoint1);
directionsManager.addWaypoint(waypoint2);
// Callback for on update directions
Microsoft.Maps.Events.addHandler(directionsManager, 'directionsUpdated', onUpdateDirections);
directionsManager.calculateDirections();
});
// On update directions callback
function onUpdateDirections() {
clearLayers();
window.setTimeout(function() {
addPushpins();
}, 2000);
}
// Add pushpins
function addPushpins() {
// Generate an array of 10 random pushpins within current map bounds
pushpins = Microsoft.Maps.TestDataGenerator.getPushpins(10, map.getBounds());
layer = new Microsoft.Maps.Layer();
layer.add(pushpins);
map.layers.insert(layer);
}
// Clear layers
function clearLayers() {
// map.layers.clear();
if (layer !== undefined) {
var currentPrimitives = layer.getPrimitives();
/* remove those that are Pushpins */
for (var i = 0; i < currentPrimitives.length; i++) {
var entity = currentPrimitives[i];
if (entity instanceof Microsoft.Maps.Pushpin){
layer.remove(entity);
}
}
}
}
This is to be expected. It not clearing in the past would have been considered a bug. If you want to clear your layers, but leave the directions you have two options. Clear the layers before calculating the directions, or clear the individual layer rather than all layers in the map.
You could examine your layer, get the primitives from it and remove only the pins. Something like the following:
var currentPrimitives = layer.getPrimitives();
/* remove those that are Pushpins */
for (var i = 0; i < currentPrimitives.length; i++) {
var entity = currentPrimitives[i];
if (entity instanceof Microsoft.Maps.Pushpin){
layer.remove(entity);
}
}

Add custom marker with store logo in ionic using google map

I am working with ionic and i want to display map marker with store logo. I constructed a default marker and I have lots of store pics or logos which need to be placed within the marker show in above image. I have used cordova geolocation plugin for get current location of user.
Response array like this :
var markers = [{
storeName: "Dib Dab Extract",
profilePic: "img/dibdab.png",
address: "420 Mary Jane Way",
rating: "4",
reviews: "4379",
offer: "100 Free Coins with 1st Purchse",
lat: "53.896408",
long: "-105.991427"
}]
Custom Marker Icon :
var image = {
url: 'img/ic_map_pin_gray.png', // image is 512 x 512
scaledSize: new google.maps.Size(80, 80),
};
Marker set on map like this :
var markerPos = new google.maps.LatLng(record.lat, record.long);
// Add the markerto the map
var marker = new google.maps.Marker({
map: map,
animation: google.maps.Animation.DROP,
position: markerPos,
icon: image,
});
Issue is resolved using Custom Marker. I have done code like this and i get exact marker like i want in above question. So i posted this answer that help anyone who want custom marker like this. i have refer https://humaan.com/blog/custom-html-markers-google-maps/
// Map Initilize function
function initMap() {
var options = {
timeout: 10000,
enableHighAccuracy: true
};
$cordovaGeolocation.getCurrentPosition(options).then(function(position) {
var latLng = new google.maps.LatLng(position.coords.latitude,position.coords.longitude);
var mapOptions = {
center: latLng,
zoom: 15,
disableDefaultUI: true,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map"), mapOptions);
//Wait until the map is loaded
//Load the markers
loadMarkers();
//});
}, function(error) {
console.log(error);
console.log("Could not get location");
//Load the markers
loadMarkers();
});
}
//load marker using rest api
function loadMarkers() {
CommonService.ShowLoader();
YOUR REST API SERVICE.then(function(res) {
angular.forEach(res, function(value, key) {
var record = value;
console.log(record);
var image = {
url: 'img/ic_map_pin_gray.png', // custom background image (marker pin)
scaledSize: new google.maps.Size(70, 70),
};
var markerPos = new google.maps.LatLng(record.lat, record.long);
//Add the markerto the map
var marker = new google.maps.Marker({
map: map,
animation: google.maps.Animation.DROP,
position: markerPos,
icon: image,
});
var img_src = record.profilePic;
var overlay = new CustomMarker(
markerPos,
map, {image: img_src}
);
});
}).catch(function(error, status, headers, config) {
console.log(error);
});
}
//CustomMarker function
function CustomMarker(latlng, map, args) {
this.latlng = latlng;
this.args = args;
this.setMap(map);
}
CustomMarker.prototype = new google.maps.OverlayView();
CustomMarker.prototype.draw = function() {
var self = this;
var div = this.div;
if (!div) {
div = this.div = document.createElement('img');
div.src = self.args.image;
div.className = 'marker';
div.style.position = 'absolute';
div.style.cursor = 'pointer';
div.style.width = '35px';
div.style.height = '35px';
div.style.borderRadius = '50%';
if (typeof(self.args.marker_id) !== 'undefined') {
div.dataset.marker_id = self.args.marker_id;
}
google.maps.event.addDomListener(div, "click", function(event) {
google.maps.event.trigger(self, "click");
});
var panes = this.getPanes();
panes.overlayImage.appendChild(div);
}
var point = this.getProjection().fromLatLngToDivPixel(this.latlng);
if (point) {
div.style.left = (point.x - 18) + 'px'; // set custom (i set it as i want to set in map )
div.style.top = (point.y - 56) + 'px'; //set custom (i set it as i want to set in map )
}
};
This worked for me.
marker = new MarkerWithLabel({
position: new google.maps.LatLng(item.latitude, item.longitude),
animation: google.maps.Animation.DROP,
labelContent: "My Job Location",
labelAnchor: new google.maps.Point(10, 38),
labelClass: "markLabelsJob", // the CSS class for the label
labelInBackground: false,
icon: 'img/active-job-pin.png',
map: map
});

Google Map Update dynamically in Angular

http://plnkr.co/edit/Zd9GwG?p=preview
I am working on this google map + angular.js example . I want to change the location center dynamically depend on the variable .i.e. I want to make it dynamic center. Please suggest how to do this ?
I want to do some thing Like this.
// Code goes here
//Add the requried module 'angular-ui' as a dependency
angular.module('maptesting', ['ui.directives']);
function MapCtrl($scope) {
$scope.lat = 35.120922 ;
$scope.long = -89.97731 ;
var ll = new google.maps.LatLng($scope.lat, $scope.long);
$scope.mapOptions = {
center: ll,
zoom: 15,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
//Markers should be added after map is loaded
$scope.onMapIdle = function() {
//alert("DF");
if ($scope.myMarkers === undefined){
var marker = new google.maps.Marker({
map: $scope.myMap,
position: ll
});
$scope.myMarkers = [marker, ];
}
};
$scope.showMarkerInfo = function(marker) {
$scope.myInfoWindow.open($scope.myMap, marker);
};
$scope.changeval = function(){
$scope.lat = 13.0810 ;
$scope.long = 80.2740 ;
};
}
You need to watch for changes in the scope in order to refresh the map.
Demo Plunkr
(just use the input fields above the map to change the center of the map in real time)
The important part is $scope.$watch:
var updateCenter = function() {
var ll = new google.maps.LatLng($scope.lat, $scope.long);
$scope.myMap.panTo(ll);
// eventually more stuff
}
$scope.$watch('lat', updateCenter);
$scope.$watch('long', updateCenter);

Google maps Info Window Overlay content just like that in maps.goole.com

I want have the info window content for a marker just a s below
My code so far is
loadEmbeddedMap : function() {
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "http://maps.google.com/maps/api/js?sensor=false&callback=initEmbeddedMap";
document.body.appendChild(script)
},
initEmbeddedMap : function() {
var myLatlng = new google.maps.LatLng(40, -80);
var myOptions = {
zoom: 8,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById("embeddedGoogleMap"), myOptions);
geocoder = new google.maps.Geocoder();
geocoder.geocode( { 'address': $('#userMapAddress').val()}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results[0].geometry.location);
marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location
});
console.debug(results[0]);
infowindow = new google.maps.InfoWindow();
var infoWindowContent = "<div><strong>Address:</strong></div>";
infoWindowContent += "<div>"+results[0].address_components[0].short_name+","+results[0].address_components[1].short_name+"</div>";
infoWindowContent += "<div>"+results[0].address_components[5].short_name+","+results[0].address_components[7].short_name+"</div>";
//infoWindowContent += results[0].formatted_address;
infowindow.setContent(infoWindowContent);
infowindow.open(map, marker);
} else {
//alert("Geocode was not successful for the following reason: " + status);
}
});
$('#embeddedGoogleMapWrapper').show();
},
Code above outputs this
How to get those 'Directions', 'Search near by' stuffs..? Any helps appreciated..
I would start by reading
http://code.google.com/apis/maps/documentation/localsearch/devguide.html#hiworld
As i can see it is possible to do what you want. I cant get you a straight answer but maybe a clue.
I would create my own form in infowindow at least pretty close to the original google one and handle click events by sending those search queries.
Than you need to handle search results
http://code.google.com/apis/maps/documentation/localsearch/devguide.html#handle_search_results
Do some testing with
http://code.google.com/apis/ajax/playground/#the_hello_world_of_local_search
For example you can get lat from localSearch.results[i].lat and so on.
I hope you can get something out of this

Resources