Google maps and knockoutjs - google-maps

I am making a single page app where in the second view I need to display the Google map. I am using the Google maps API where the map object is to be created.
var map = new google.maps.Map(mapId, {
zoom: 5,
center: new google.maps.LatLng(55, 11),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
The parameter mapId is giving me a problem. The view contains a div with id say "mapId", but I am not able to get the id and so the map cannot be displayed. I tried HTML binding, attribute binding but it does not work. I am new to knockout. Please suggest some method

You should use a custom binding like so:
ko.bindingHandlers.map = {
init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
var mapObj = ko.utils.unwrapObservable(valueAccessor());
var latLng = new google.maps.LatLng(
ko.utils.unwrapObservable(mapObj.lat),
ko.utils.unwrapObservable(mapObj.lng));
var mapOptions = { center: latLng,
zoom: 5,
mapTypeId: google.maps.MapTypeId.ROADMAP};
mapObj.googleMap = new google.maps.Map(element, mapOptions);
}
};
Your HTML would look like this:
<div id="mapDiv" data-bind="style:{width:'300px',height:'300px'},map:myMap"></div>
Finally your view model:
function MyViewModel() {
var self = this;
self.myMap = ko.observable({
lat: ko.observable(55),
lng: ko.observable(11)});
}
Here is a fiddle that does a bit more than what you are asking but should work fine for your case as well.

Here's a good example of using Knockout JS and Google Maps. Hopefully, it will help get you on the right track.
http://www.codeproject.com/Articles/387626/BikeInCity-2-KnockoutJS-JQuery-Google-Maps

I have modified "schmidlop" binding to reset marker on change in inputs (lat long inputs) and marker always in center of map.
Html
<input data-bind="value: mapOne().lat" />
<input data-bind="value: mapOne().lng" />
Binding , Include this in some js file and include it in html.
ko.bindingHandlers.map = {
init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
$("#" + element.getAttribute("id")).data("mapObj","");
mapObj = ko.utils.unwrapObservable(valueAccessor());
var latLng = new google.maps.LatLng(
ko.utils.unwrapObservable(mapObj.lat),
ko.utils.unwrapObservable(mapObj.lng));
var mapOptions = { center: latLng,
zoom: 12,
mapTypeId: google.maps.MapTypeId.ROADMAP};
mapObj.googleMap = new google.maps.Map(element, mapOptions);
mapObj.marker = new google.maps.Marker({
map: mapObj.googleMap,
position: latLng,
draggable: true
});
mapObj.onChangedCoord = function(newValue) {
var latLng = new google.maps.LatLng(
ko.utils.unwrapObservable(mapObj.lat),
ko.utils.unwrapObservable(mapObj.lng));
mapObj.googleMap.setCenter(latLng);
mapObj.marker.setPosition(latLng);
};
mapObj.onMarkerMoved = function(dragEnd) {
var latLng = mapObj.marker.getPosition();
mapObj.lat(latLng.lat());
mapObj.lng(latLng.lng());
};
mapObj.lat.subscribe(mapObj.onChangedCoord);
mapObj.lng.subscribe(mapObj.onChangedCoord);
google.maps.event.addListener(mapObj.marker, 'dragend', mapObj.onMarkerMoved);
$("#" + element.getAttribute("id")).data("mapObj",mapObj);
}
};
View Model
self.mapOne = ko.observable();
self.mapOne({'lat':ko.observable(87.22),'lng':ko.observable(27.22)});

Instead of mapId you'll want to use document.getElementById('map'), where 'map' is the id of the div containing the map (<div id="map"></div>). This jsFiddle should help.

Related

Using Lat Long from model data in view to populate google map coordinates

I have a small app that retrieves data from a database and displays information. It is all vehicle information and two of the fields are Latitude and Longitude.
I am trying to get a map to show up when the user clicks "Details" but I cannot figure out how to get the model data into the function so that it shows.
What I have tried.
//Setting a hidden input equal to the value
<input type='hidden' id='test-lat' value='#Html.Display(model => model.Lat)' />
//Then starting the script
<script>
var a = $('#test-lat').val();
var map;
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
center: {lat: a, lng: 41},
zoom: 8
});
}
</script>
This just gives me a gray box
No need to use hidden-control, you can directly implement model value as parameters.
<script>
$(document).ready(function () {
initialize();
});
function initialize() {
var mapOptions = {
center: new google.maps.LatLng('#Model.Lat', '#Model.Lng'),
zoom: 8,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map"), mapOptions);
// create a marker
var latlng = new google.maps.LatLng('#Model.Lat', '#Model.Lng');
var marker = new google.maps.Marker({
position: latlng,
map: map,
title: 'Vehicle Place'
});
}
</script>

Centering google maps on a placeholder

Does anyone know if its possible to center a embedded map on an actual placeholder? I mean so that that when the map loads and is centered you can actually see the landmark and the marker in the the map?
function initialize() {
var map_canvas = document.getElementById('map_canvas');
var map_options = {
center: new google.maps.LatLng(51.515727, -0.141388),
zoom: 16,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
var map = new google.maps.Map(map_canvas, map_options)
}
This is my initialise function that inputs the coordinates of the shop I want to have directions to. However there is not placeholder (pin marker) over the shop. Am I able to do that?
Thanks!
You need to explicitly specify the marker and set its position. Following your example...
var map_canvas = document.getElementById('map_canvas');
var position = new google.maps.LatLng(51.515727, -0.141388);
var mapOptions = {
zoom: 16,
center: position,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(map_canvas, map_options);
You have to then create the marker object...
var marker = new google.maps.Marker({
position: position,
map: map,
title: "ANYTHING YOU WANT"
});
That's all you need to do really, but notice that you can always change the center of the map at anytime...
map.setCenter(position);
For more info visit the Developer's Site API Reference
function initialize() {
var map_canvas = document.getElementById('map_canvas');
var map_options = {
center: new google.maps.LatLng(51.515727, -0.141388),
zoom: 16,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
var map = new google.maps.Map(map_canvas, map_options);
var point = new google.maps.LatLng(51.515727, -0.141388);
var marker = new google.maps.Marker({
position:point,
map: map,
});
}

Google Map not loaded in second time in bootstrap modal

This script is creating a problem that when i used to load google map in bootstrap modal.
First time map is loaded but with second time map is not loaded fully.
<script>
var map = '';
function showmap(){
if(!map){
var mapOptions = {
zoom: 4,
center: new google.maps.LatLng(23.6459, 81.9217),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById('map_canvas'), mapOptions);
var marker = new google.maps.Marker({
position: map.getCenter(),
map: map
});
google.maps.event.addListener(map, "click", function(){
document.getElementById("latitude").value = map.getCenter().lat();
document.getElementById("longitude").value = map.getCenter().lng();
marker.setPosition(map.getCenter());
//document.getElementById("zoom").value = map.getZoom();
});
google.maps.event.addListener(map, "center_changed", function(){
document.getElementById("latitude").value = map.getCenter().lat();
document.getElementById("longitude").value = map.getCenter().lng();
marker.setPosition(map.getCenter());
//document.getElementById("zoom").value = map.getZoom();
});
}
}
</script>
<script>
var map = '';
function showmap(){
if(!map){
var mapOptions = {
zoom: 4,
center: new google.maps.LatLng(23.6459, 81.9217),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById('map_canvas'), mapOptions);
^^^^ Remove var from here and it works fine
var marker = new google.maps.Marker({
position: map.getCenter(),
map: map
});
google.maps.event.addListener(map, "click", function(){
document.getElementById("latitude").value = map.getCenter().lat();
document.getElementById("longitude").value = map.getCenter().lng();
marker.setPosition(map.getCenter());
});
}
}
</script>
in function when assigning map variable again in modal is creating problem so to remove conflict just remove var map when assingin it to google.maps
This is meant to be a comment but I am not allowed to add comments at this time.
I also experience the same in an MVC app. Modal content (resource title and map) is loaded as partial view from a controller action. First map loads nicely but next map(s) are clipped and only top left part shows. Using Bootstrap 3.
It is worth mentioning that if you refresh the page, the map loads well but that's not practical.

How to create Google Maps API Marker with device's geolocation (after its async callback)

Please help. Trying to create a map of Chicago, and have my current known location appear as a marker on that map. The problem is (though I can find no explicit mention of this in any tutorial or doc), it seems I have to declare the marker var in the same scope as (perhaps right after?) I declare the map---global variables don't seem to work. This is difficult, since I'm making an asynchronous call, and thus only have a verified position for my marker in the callback function I've defined. Thus the following code doesn't work...
(function() {
var chicago = new google.maps.LatLng(41.87811, -87.62980);
var info = document.getElementById("info");
var map;
function showError(error)
{
info.innerHTML += "Error: " + error.message;
}
function getLocation(position)
{
current_location = new google.maps.LatLng(
position.coords.latitude, position.coords.longitude);
var marker = new google.maps.Marker({
position: current_location,
map: map
});
}
window.onload = function() {
var mapOptions = {
zoom: 10,
center: chicago,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
if (navigator.geolocation)
{
navigator.geolocation.getCurrentPosition(getLocation, showError);
}
}
})();
I can see no clean way out of this, but would love to be shown otherwise.
If I'm understanding you correctly, than this should work, this is how I handle the asynchronous creation of the marker at the found position in my own app, and it works great! If this isn't what you meant then let me know!
function initialize() {
var mapOptions = {
zoom: 10,
center: new google.maps.LatLng(lat, lon),
mapTypeId: google.maps.MapTypeId.ROADMAP,
zoomControl: true,
zoomControlOptions: {
style: google.maps.ZoomControlStyle.LARGE
}
};
map = new google.maps.Map(document.getElementById('gmaps'), mapOptions);
locateMe();
}
function locateMe() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
initialLocation = new google.maps.LatLng(position.coords.latitude,position.coords.longitude);
map.setCenter(initialLocation);
map.setZoom(15);
setMarkerPosition(position.coords.latitude, position.coords.longitude);
updateLocation();
}, function() {
handleNoGeolocation(browserSupportFlag);
});
} else {
}
}
function setMarkerPosition(lati, longi) {
var latLongMarker = new google.maps.LatLng(lati,longi);
marker = new google.maps.Marker({
position: latLongMarker,
map: map,
draggable: false,
title: "Your Location"
});
}

Google maps API marker - mouseover instead of click - using kml

I wanna simply get markers from a kml file and show them on a map, but add "mouseover" for tooltip, not click
using this code, but it don't work (works if i use click)
function initialize() {
var latlng = new google.maps.LatLng(53.477876, -2.471289);
var myOptions = {
zoom: 5,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
//kml begin
var nyLayer = new google.maps.KmlLayer('http://code.nebtron.com/kml2.kml', {suppressInfoWindows: false});
nyLayer.setMap(map);
google.maps.event.addListener(nyLayer, "mouseover", function(kmlEvent) {
var text = kmlEvent.featureData.description;
showInDiv(text);
});
function showInDiv(text) {
var sidediv = document.getElementById('contentWindow');
sidediv.innerHTML = text;
}//kml end
}
Demo: http://code.nebtron.com/map3.php
As pointed out here, there is no mouseover event for KMLLayers. But maybe you could use a polygon. Here's a link.
Hope this helps!