Durandal SPA Google Map API Map Centering - google-maps

There are a few posts regarding issues with google map api centering properly. I understand the following resizes the map:
google.maps.event.trigger(map, 'resize');
I was able to get the map to display properly within the div element on first page display. However, when navigating back to the html page that holds the map, only a fraction of the map displays within the div. The problem i'm having is figuring out how to incorporate this resize trigger. I'm new to SPA's and Durandal, here is my viewmodel responsible for the map:
define(['async!https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false'], function () {
var vm = {
title: 'Home View',
attached: initialize,
activate: function () {
toastr.success('Map View Activated');
}
};
return vm;
function initialize() {
var mapOptions = {
zoom: 10,
center: new google.maps.LatLng(-34.397, 150.644),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
}
});

Sure, you'd want to do this when the map is visible, i.e. it has a height and width. The best event for this is typically the composition complete event. So:
var vm = {
title: 'Home View',
attached: initialize,
activate: function () {
toastr.success('Map View Activated');
},
compositionComplete: function() {
google.maps.event.trigger(map, 'resize');
}
};
See the list and description of all callbacks here: Hooking Lifecycle Callbacks

Related

How to make sure that tiles are fully rendered in using google map api

I am able to capture the google map image. But I want it to capture automatically. I am able to but it has image which is not fully rendered. So I want to know is there any proper way to know that required tiles are loaded and rendered fully.I tried tilesloaded, idle events but seems not working rightly.
is it a good way to use idle under tilesloaded...i may sound wrong as i'm very new to google map api.
function initialize() {
var mapOptions = {
zoom: 17,
center: new google.maps.LatLng(lat,lng),
mapTypeId: google.maps.MapTypeId.ROADMAP,
rotateControl:true
};
map = new google.maps.Map(document.getElementById('map_canvas'), mapOptions);
google.maps.event.addListener(map, 'tilesloaded', function(event) {
console.log("tilesloaded");
map.addListener('idle', function(event) {
console.log("idle");
});
});
}
google.maps.event.addDomListener(window, 'load', initialize);
you can easily add a listener on the tilesloaded event. Like this:
google.maps.event.addListener(map, 'tilesloaded', function() {
..... your code ...
});

Google Map api V3, setPosition/setCenter is not working

There are two places where i need to show google maps.
I'm using same code for both maps(I mean I'm reusing same code for both maps).
Below are links where you can find screen shots of those two maps.
https://drive.google.com/file/d/0B2JnvvXsAALUdlVzemRVMzNMajF4OFB1V0JXc0RuN1p4eWFV/view - map1
https://drive.google.com/file/d/0B2JnvvXsAALUVGRhNm1HSldhQnpZT3k4S2I2R1YyQkp4OWZz/view - map2
I'm showing second map(map2) in bootstarp modal
first map(map1) is working fine. But in second map(map2), though I have used setCenter method, marker is not showing at center of the map(instead it is showing at top left corner).
what should i do to place marker at center of the map(in second map)?
below is my code..
initialize: function(options){
//initializing the geocoder
this.geocoder = new google.maps.Geocoder();
this.map;
},
//on show of the view
//onShow is a marionette method, which will be triggered when view is shown
onShow: function(){
var address = this.model.get("address");
//render the map with dummy latLang
this.renderMap();
//render the Map with Proper address
if(address!== ""){
this.renderMapWithProperAddress(address);
}
},
renderMap: function(){
var mapCanvas = document.getElementById("mapCanvas"), self = this,
mapOptions = {
center: new google.maps.LatLng(64.855, -147.833),//dummy latLang
zoom: 15,
mapTypeId: google.maps.MapTypeId.ROADMAP,
zoomControl: false,
mapTypeControl: false,
streetViewControl:false
};
//initializing google map
self.map = new google.maps.Map(mapCanvas, mapOptions);
$("#myModal").on("shown.bs.modal",function(){
google.maps.event.trigger(self.map, "resize");
});
},
renderMapWithProperAddress: function(address){
var self = this,marker;
self.geocoder.geocode( { "address": address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
self.map.setCenter(results[0].geometry.location);
marker = new google.maps.Marker({
map: self.map,
position: results[0].geometry.location,
title: address
});
} else {
alert("Geocode was not successful for the following reason: " + status);
}
});
}
My guess, without seeing your code, is that you need to trigger a map resize event after the bootstrap modal has been shown.
Bootstrap modal
Maps events
$('#myModal').on('shown.bs.modal', function () {
google.maps.event.trigger(map, 'resize');
});
Edit:
Here is a complete and working example. As per my comment, you should 1) Trigger a map resize and 2) set the map center to your marker coordinates.
var center = new google.maps.LatLng(59.76522, 18.35002);
function initialize() {
var mapOptions = {
zoom: 7,
mapTypeId: google.maps.MapTypeId.ROADMAP,
center: center
};
map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
var marker = new google.maps.Marker({
map: map,
position: center
});
}
$('.launch-map').on('click', function () {
$('#modal').modal({
backdrop: 'static',
keyboard: false
}).on('shown.bs.modal', function () {
google.maps.event.trigger(map, 'resize');
map.setCenter(center);
});
});
initialize();
JSFiddle demo

Meteor: modals and google maps

I am displaying a google map in a modal and I see lots of people have had this issue and there seems to be a fix but so far nothing I've tried has worked.
Basically I am loading googles places search in Template.map.rendered - it seems like something is happening with the DIVs because when I resize the window it re-renders and displays properly.
Now, I have tried all kinds of tricks (hiding / showing various DIVs), calling google.maps.event.trigger(map, "resize"); etc.
The map template is being loaded into another template that is a form (with other fields etc).
If someone could point me in a fruitful direction that would be awesome - seems like it should be a simple fix but I'm stumped.
Thanks!
You're in luck, we just solved our issue regarding this. Assuming the template map is called within a modal:
Template.map.rendered = function() {
Tracker.autorun(function() {
Session.set('map_available', true);
var center = {
latitude: -1.8445
longitude: 52.9445
}; // end var center
var zoomLevel = 15;
if(Session.equals('map_available', true)) {
GoogleMaps.init({'sensor': true, 'key' : 'OPTIONAL_KEY' },
function() {
var mapOptions = {
zoom: zoomLevel,
minZoom: 15,
maxZoom: 20,
mapTypeId: google.maps.MapTypeId.ROADMAP,
navigationControlOptions: {
style: google.maps.NavigationControlStyle.SMALL
};
map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
map.setCenter(new google.maps.LatLng( center.latitude, center.longitude ));
} // end closure param 2 of GoogleMaps init
}); // end GoogleMaps.init
} // end Session.equals 'map_available'
} //end Tracker.autorun
} // end Template.map.rendered
Template.map.destroyed = function() {
Session.set('map_available', false);
}
So the strategy here is to monitor dependency tracking independently and make sure it gets re-added after any DOM reactions. Bonus feature here is that if you include var center modification inside Tracker.autorun (e.g. var center = navigator.location) you will have a map that changes center when you move around (lat, long has changed).
Also, we used the extension mrt:googlemaps for the GoogleMaps integration. Seems to be the best one to use.
Had the same problem that stumped me for an hour. My easy fix was to wrap it in a window onload. Try it, you might like it :-)
Template.mapsAutoComplete.rendered = function() {
window.onload = function () {
var map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
...
};
};

Google Map not rendering correctly after first view with Backbone.js

Im creating a mobile app with Phonegap, Backbone.js, Require.js and PageSlider (https://github.com/ccoenraets/PageSlider).
I want to display a simple Google Map with a marker. The template looks like:
<div class='main-content' id='map-container'>
<a href="geo:51.903679,-8.468274">
<div id="map-canvas"></div>
</a>
</div>
Here is the view:
define(function (require) {
"use strict";
var $ = require('jquery'),
_ = require('underscore'),
Backbone = require('backbone'),
tpl = require('text!tpl/Map.html'),
side_nav = require('text!tpl/SideNav.html'),
template = _.template(tpl),
map, myLatlng, mapOptions, marker;
return Backbone.View.extend({
initialize: function () {
this.render();
},
initMap: function () {
myLatlng = new google.maps.LatLng(51.903679, -8.468274);
mapOptions = {
center: myLatlng,
zoom: 12,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(this.$el.find('#map-canvas')[0],
mapOptions);
marker = new google.maps.Marker({
position: myLatlng,
map: map,
title: 'Christians Brothers College Cork'
});
},
render: function () {
this.$el.html(template({side_nav:side_nav}));
this.initMap();
},
});
});
Here is a link to the app. When you click on "location", the map renders perfectly. But when you navigate anywhere else, then back to location, only a tiny portion of the map can be seen in the top left hand corner.
I tried doing, which was suggested here:
google.maps.event.trigger(map, 'resize').
but to no avail. Any ideas?
Your view works on a node not appended to the DOM, thus without size, a situation Google Map is not very fond of. It is your router, via PageSlider, that does append the node after your render function has occurred.
Here is a demo of your predicament : http://jsfiddle.net/3C7g3/
You have several options to solve it:
call google.maps.event.trigger(map, 'resize') after the node is inserted into the DOM (this bit of code corresponds to your router entry for the map)
// assuming you stored the map object in your view
require(["app/views/Map"], function (Map) {
var view = new Map();
slider.slidePage(view.$el);
google.maps.event.trigger(view.map, 'resize');
});
http://jsfiddle.net/3C7g3/1/
insert the node into DOM before calling render. In your case, that probably means removing render from the view.initialize and calling view.render after container.append(page); in your slidePageFrom method.
http://jsfiddle.net/3C7g3/2/
a more hackish way would be to temporarily add the element to the DOM, apply Google Maps, and then remove it from the DOM
initMap: function () {
// assuming a temp class that hides the element. For example,
// .temp {position: absolute; visibility:hidden; }
this.$el.addClass('temp');
$('body').append(this.$el);
// ...
this.$el.remove();
this.$el.removeClass('temp');
}
http://jsfiddle.net/3C7g3/3/

Sencha touch - unable to google map markers

I'm learning sencha touch and trying put markers on the google map. I've looked at most of the examples online but I'm unable to get the marker and the infoWindow to work. Below is my code:
myApp.views.MapCard = Ext.extend(Ext.Panel, {
id: "mapcard",
layout: 'card',
initComponent: function() {
this.map = new Ext.Map({
useCurrentLocation: true,
mapOptions: {
zoom: 12,
},
});
this.panel = new Ext.Panel({
layout: 'fit',
items: this.map,
});
this.items = this.panel;
myApp.views.MapCard.superclass.initComponent.call(this);
refresh = function(theMap) {
var geoTag = {
lat: '47.584863',
longi: '-122.147026',
text: 'Hello World',
}
addMarker(geoTag, theMap);
}
addMarker = function(geoTag, theMap) {
var latLng = new google.maps.LatLng(geoTag.lat, geoTag.longi);
var marker = new google.maps.Marker({
map: theMap.map,
position: latLng
});
google.maps.event.addListener(marker, "click", function() {
geoTagBubble.setContent(tweet.text);
geoTagBubble.open(theMap.map, marker);
});
};
geoTagBubble = new google.maps.InfoWindow();
refresh(this.map);
},
});
Ext.reg('mapcard', myApp.views.MapCard);
I'm also unable to get the current location of the user, I'm pretty sure that the map is not loaded during the initComponent. I would be calling a json service to pull the lat/lon and loop through later. If there is a better implementation, please let me know!
Thanks a ton!
Here's a pretty minimal example application that demonstrates this:
http://septa.mobi
You can find the source code under view-source or on GitHub:
https://github.com/mjumbewu/Septnuts/
Here's panel where marker are added to a map:
https://github.com/mjumbewu/Septnuts/blob/master/src/Septnuts/MapPanel.js
WARNING: there is a bug in Sencha Touch 1.x that prevents embedded Google Maps from receiving ANY click events
You need to include this patch after including sencha-touch.js in order for any click listener on the map to work:
https://github.com/mjumbewu/Septnuts/blob/master/src/sencha-maptouch-patch.js