I am new to js and know very little about Knockout. I have tried some tutorials but it still makes no sense. Anyway, I want to know how I would get the same results as the HTML below using Knockout.
<!DOCTYPE html>
<html>
<head>
<style>
#map {
width: 100%;
height: 800px;
}
</style>
</head>
<body>
<h3>Map</h3>
<div id="map"></div>
<script type='text/javascript' src='knockout-3.3.0.js'></script>
<script>
function initMap() {
var mapDiv = document.getElementById('map');
var map = new google.maps.Map(mapDiv, {
center: {lat: 39.962386, lng: -82.999563},
zoom: 14
});
var marker1 = new google.maps.Marker({
position: {lat: 39.969819, lng: -83.01012},
animation: google.maps.Animation.BOUNCE,
map: map,
title: 'EXPRESS LIVE!'
});
var marker2 = new google.maps.Marker({
position: {lat: 39.969424, lng: -83.005915},
animation: google.maps.Animation.BOUNCE,
map: map,
title: 'Nationwide Arena'
});
var marker3 = new google.maps.Marker({
position: {lat: 39.964425, lng: -82.987804},
animation: google.maps.Animation.BOUNCE,
map: map,
title: 'Columbus Museum of Art'
});
var marker4 = new google.maps.Marker({
position: {lat: 39.959688, lng: -83.007202},
animation: google.maps.Animation.BOUNCE,
map: map,
title: 'COSI'
});
var marker5 = new google.maps.Marker({
position: {lat: 39.969161, lng: -82.987289},
animation: google.maps.Animation.BOUNCE,
map: map,
title: 'Columbus State College'
});
var marker6 = new google.maps.Marker({
position: {lat: 39.946266, lng: -82.991023},
animation: google.maps.Animation.BOUNCE,
map: map,
title: "Schmidt's Sausage Haus und Restaurant"
});
}
</script>
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyAzDEepTI6qMIoZ3OGMe03ZWpmrIakZCwc&callback=initMap">
</script>
</body>
</html>
I have looked at multiple posts on this site on the topic but I cannot get any of the answers to work for me.
I would make a binding handler that did all the referencing to the external library and template manipulation.
/**
* Decorates a div with a map and adds marker points
*/
ko.bindingHandlers.googleMap = {
init(mapDiv, valueAccessor) {
let bindingData = ko.unwrap(valueAccessor()) || {},
map = new google.maps.Map(mapDiv, {
center: {
lat: bindingData.centerX,
lng: bindingData.centerY
},
zoom: bindingData.zoom
}),
markers = _.map(bindingData.markers,function (data) {
return new google.maps.Marker(data);
});
// do some more stuff or hook into markers
// you might want to subscribe to the markers collection
// if you make it an observable array
}
};
Referencing it in the template would be something like:
<html>
<body>
<div class='map-div' data-bind="googleMap:googleMapData"></div>
</body>
</html>
Then in the viewModel specify something like:
var ViewModel = function() {
this.googleMapData = ko.observable({
centerX: 39.962386,
centerY: -82.999563,
zoom: 14,
markers: [{
position: {lat: 39.964425, lng: -82.987804},
animation: google.maps.Animation.BOUNCE,
map: map,
title: 'Columbus Museum of Art'
},
...
]
});
}
ko.applyBindings(new ViewModel());
Added a Fiddle to help - just replace your API key in the maps API library included.
Related
I'm using the Google Maps Javascript API, and I've defined a polygon and attached it to a map:
const region = new google.maps.Polygon({
map: map,
paths: [
{ lat: 40.5577151228437, lng: -74.15980859374997 },
{ lat: 40.599436503265856, lng: -74.27516503906247 },
{ lat: 40.67030312529891, lng: -74.25319238281247 },
{ lat: 40.72548139969253, lng: -74.26079167357881 },
],
});
I have a click handler that adds a marker on it when the user clicks:
google.maps.event.addListener(map, 'click', function (e) {
const marker = new google.maps.Marker({
map: map,
position: e.latLng,
});
});
I see the marker when I click on areas outside of the polygon, but I don't see the marker when I click inside the polygon.
I've tried hard-coding a zIndex on each, but no luck. Any ideas?
Two options:
add a click listener to the polygon
google.maps.event.addListener(region, 'click', function (e) {
const marker = new google.maps.Marker({
map: map,
position: e.latLng,
});
});
proof of concept fiddle
function initialize() {
var map = new google.maps.Map(
document.getElementById("map_canvas"), {
center: new google.maps.LatLng(37.4419, -122.1419),
zoom: 13,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
const region = new google.maps.Polygon({
map: map,
paths: [
{ lat: 40.5577151228437, lng: -74.15980859374997 },
{ lat: 40.599436503265856, lng: -74.27516503906247 },
{ lat: 40.67030312529891, lng: -74.25319238281247 },
{ lat: 40.72548139969253, lng: -74.26079167357881 },
],
});
var bounds = new google.maps.LatLngBounds();
for (var i = 0; i < region.getPath().getLength(); i++) {
bounds.extend(region.getPath().getAt(i));
}
map.fitBounds(bounds);
function addMarker(e) {
const marker = new google.maps.Marker({
map: map,
position: e.latLng,
});
}
google.maps.event.addListener(map, 'click', addMarker);
google.maps.event.addListener(region, 'click', addMarker);
}
google.maps.event.addDomListener(window, "load", initialize);
html,
body,
#map_canvas {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js"></script>
<div id="map_canvas"></div>
make the polygon not capture clicks (clickable: false);
const region = new google.maps.Polygon({
map: map,
clickable: false,
paths: [
{ lat: 40.5577151228437, long: -74.15980859374997 },
{ lat: 40.599436503265856, long: -74.27516503906247 },
{ lat: 40.67030312529891, long: -74.25319238281247 },
{ lat: 40.72548139969253, long: -74.26079167357881 },
],
}
proof of concept fiddle
function initialize() {
var map = new google.maps.Map(
document.getElementById("map_canvas"), {
center: new google.maps.LatLng(37.4419, -122.1419),
zoom: 13,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
const region = new google.maps.Polygon({
map: map,
clickable: false,
paths: [
{ lat: 40.5577151228437, lng: -74.15980859374997 },
{ lat: 40.599436503265856, lng: -74.27516503906247 },
{ lat: 40.67030312529891, lng: -74.25319238281247 },
{ lat: 40.72548139969253, lng: -74.26079167357881 },
],
});
var bounds = new google.maps.LatLngBounds();
for (var i = 0; i < region.getPath().getLength(); i++) {
bounds.extend(region.getPath().getAt(i));
}
map.fitBounds(bounds);
google.maps.event.addListener(map, 'click', function(e) {
const marker = new google.maps.Marker({
map: map,
position: e.latLng,
});
});
}
google.maps.event.addDomListener(window, "load", initialize);
html,
body,
#map_canvas {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js"></script>
<div id="map_canvas"></div>
I created some markers on google maps and want to open the country's php page when I click on it(marker) but I don't know why it doesn't do that. Here is the layout of my code:
<script>
function initMap() {
var germany = {lat: 51.268917, lng: 9.591616};
var russia = {lat: 55.765237, lng: 37.582553};
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 2,
center: germany
});
var marker = new google.maps.Marker({
position: germany,
map: map,
title:'Germany',
url:'Germany.php',
animation:google.maps.Animation.DROP
});
var marker = new google.maps.Marker({
position: russia,
map: map,
title:'Russia',
animation:google.maps.Animation.DROP
});
google.maps.event.addListener(marker, 'click', function()
{window.location.href = marker.url;});
}
</script>
<script async defer
src="https://maps.googleapis.com/maps/api/js?
key=My_API_Key&callback=initMap">
</script>
I can't actually add comments, but you can try this. I have working for mine. You can tidy it up too.
<script>
function callMyUrl(element){
alert('I am from ' + element.title);
}
function initMap() {
var germany = {lat: 51.268917, lng: 9.591616};
var russia = {lat: 55.765237, lng: 37.582553};
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 2,
center: germany
});
var location = [
{title: 'Germany', lat: 51.268917, lng: 9.591616 },
{title: 'Russia', lat: 55.765237, lng: 37.582553 }
]
location.forEach(function(element){
var marker;
marker = new google.maps.Marker({
position: new google.maps.LatLng(element.lat, element.lng),
title: element.title,
map: map
});
return google.maps.event.addListener(marker, 'click', function() {
callMyUrl(element);
});
});
}
</script>
My map worked fine when I had it in the script tags on my index page, however when I tried to move it to my js file so that I could use a variable in it, nothing worked.
Any help is appreciated, thanks
HTML
<div id="map"></div>
<script async defer src="https://maps.googleapis.com/maps/api/js?key=AIzaSyD9utzeckd8pV-IwFik5jVgTtG84QhDjfI&callback=" type="text/javascript"></script>
<script type="text/javascript" src="js/index.js"></script>
JavaScript
var im = 'http://i.imgur.com/aCONaAI.png';
function initMap(position) {
var map = new google.maps.Map(document.getElementById('map'),
mapOptions);
var myLatLng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
var mapOptions = {
zoom: 16,
center: {
lat: 43.4678683,
lng: -79.7006069
},
mapTypeId: google.maps.MapTypeId.SATELLITE,
}
var userMarker = new google.maps.Marker({
position: myLatLng,
map: map,
icon: im,
scaledSize: new google.maps.Size(50,50)
});
var stageIcon = {
url: 'http://s31.postimg.org/i1fox68uz/bathroomicon.png',
scaledSize: new google.maps.Size(50,50)
}
var stage1 = new google.maps.Marker({
position: { lat: 43.469222,
lng: -79.698804},
map: map,
title: 'Stage 1',
icon: stageIcon
});
}
When you use "defer" you need to use it on all the scripts that are dependent on each other. If you defer loading the Google Maps Javascript API, you need to defer the loading of the scripts that are dependent on it.
working example (your code)
HTML:
<div id="map"></div>
<script async defer type="text/javascript" src="scripts/SO_20160419.js"></script>
<script async defer type="text/javascript" src="https://maps.googleapis.com/maps/api/js?callback=initMap" type="text/javascript"></script>
CSS:
html, body, #map {
height: 100%;
width: 100%;
}
Javascript (contents of scripts/SO_20160419.js):
var im = 'http://maps.google.com/mapfiles/ms/micons/blue.png';
var default_position = {coords: {latitude:42, longitude: -72}};
function initMap(position) {
if (!position) position = default_position;
var myLatLng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
var mapOptions = {
zoom: 16,
center: {
lat: 43.4678683,
lng: -79.7006069
},
mapTypeId: google.maps.MapTypeId.SATELLITE,
}
var map = new google.maps.Map(document.getElementById('map'),
mapOptions);
var userMarker = new google.maps.Marker({
position: myLatLng,
map: map,
icon: im,
scaledSize: new google.maps.Size(50,50)
});
var stageIcon = {
url: 'http://maps.google.com/mapfiles/ms/micons/green.png',
scaledSize: new google.maps.Size(50,50)
}
var stage1 = new google.maps.Marker({
position: { lat: 43.469222,
lng: -79.698804},
map: map,
title: 'Stage 1',
icon: stageIcon
});
}
Take a look at this one -> fiddle
var map;
(function() {
'use strict';
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
center: {lat: -34.397, lng: 150.644},
zoom: 8
});
document.add
}
initMap();
})();
I'm planning to use google map "containsLocation()" API in one of my application. The doc link is - https://goo.gl/4BFHCz
I'm following the same example. Here is my code.
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<title>Polygon arrays</title>
<style>
html, body {
height: 100%;
margin: 0;
padding: 0;
}
#map {
height: 100%;
}
</style>
</head>
<body>
<div id="map"></div>
<script>
// This example requires the Geometry library. Include the libraries=geometry
// parameter when you first load the API. For example:
// <script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=geometry">
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
//center: {lat: 24.886, lng: -70.269},
center: {lat: 12.9629277, lng: 77.7178972},
zoom: 30,
});
/*var triangleCoords = [
{lat: 25.774, lng: -80.19},
{lat: 18.466, lng: -66.118},
{lat: 32.321, lng: -64.757}
];*/
var triangleCoords = [
{lat: 12.96301273, lng: 77.71785952},
{lat: 12.96314857, lng: 77.71784072},
{lat: 12.96316124, lng: 77.71784037},
{lat: 12.96295465, lng: 77.71788993},
{lat: 12.96293329, lng: 77.7179345},
];
var bermudaTriangle = new google.maps.Polygon({paths: triangleCoords});
google.maps.event.addListener(map, 'click', function(e) {
var curPosition = {"lat":12.9629277,"lng":77.7178972};
//var curPosition = e.latLng;
console.log("e content : "+JSON.stringify(e.latLng));
console.log("curPosition content : "+JSON.stringify(curPosition));
var resultColor =
google.maps.geometry.poly.containsLocation(curPosition, bermudaTriangle) ?
'red' :
'green';
new google.maps.Marker({
position: curPosition,
map: map,
icon: {
path: google.maps.SymbolPath.CIRCLE,
fillColor: resultColor,
fillOpacity: .2,
strokeColor: 'white',
strokeWeight: .5,
scale: 10
}
});
});
}
</script>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCiAur6ANJsV776iVmMDJcHYjQkXrXyu8s&libraries=geometry&callback=initMap"
async defer></script>
</body>
</html>
If you see I've created a curPosition variable which holds the latLng data. My problem at here is as long as var curPosition = e.latLng; it works fine but, the moment I changed that to var curPosition = {"lat":12.9629277,"lng":77.7178972}; it's started showing error "Uncaught TypeError: a.lng is not a function".
Can't able to understand why it's happening? Any clue...?
Console.log screen shot attached
Regards
the containsLocation method requires a google.maps.LatLng as the "point" (at least at present), you can't use a google.maps.LatLngLiteral for currentLocation.
from the documentation:
containsLocation(point:LatLng, polygon:Polygon) | Return Value: boolean
Computes whether the given point lies inside the specified polygon.
var curPosition = new google.maps.LatLng(12.9629277,77.7178972);
code snippet:
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
center: {
lat: 12.9629277,
lng: 77.7178972
},
zoom: 30,
});
var triangleCoords = [
{lat: 12.96301273,lng: 77.71785952}, {lat: 12.96314857, lng: 77.71784072}, {lat: 12.96316124, lng: 77.71784037}, {lat: 12.96293329, lng: 77.7179345}, {lat: 12.96295465, lng: 77.71788993}];
var bermudaTriangle = new google.maps.Polygon({
paths: triangleCoords,
map: map
});
var curPosition = new google.maps.LatLng(12.9629277, 77.7178972);
console.log("curPosition content : " + JSON.stringify(curPosition));
var resultColor =
google.maps.geometry.poly.containsLocation(curPosition, bermudaTriangle) ?
'red' :
'green';
new google.maps.Marker({
position: curPosition,
map: map,
icon: {
path: google.maps.SymbolPath.CIRCLE,
fillColor: resultColor,
fillOpacity: .2,
strokeColor: 'white',
strokeWeight: .5,
scale: 10
}
});
var curPositionB = new google.maps.LatLng(12.963, 77.71788993);
var resultColorB = google.maps.geometry.poly.containsLocation(curPositionB, bermudaTriangle) ?
'red' :
'green';
new google.maps.Marker({
position: curPositionB,
map: map,
icon: {
path: google.maps.SymbolPath.CIRCLE,
fillColor: resultColorB,
fillOpacity: .2,
strokeColor: 'white',
strokeWeight: .5,
scale: 10
}
});
}
google.maps.event.addDomListener(window, 'load', initMap);
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
#map {
height: 100%;
}
<script src="https://maps.googleapis.com/maps/api/js?libraries=geometry&key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
<div id="map"></div>
I am trying achieve multiple markers on a Google map to mark access points for a river. So far I have one marker (myLatlng) that displays and anotehr that shows after a button is clicked, however when I have tried adding more than one (accessPoint1), it will not appear. Does anyone know how to fix this? Thanks in advance.
function initialize() {
var myLatlng=new google.maps.LatLng(51.843143, -2.643555),
map = new google.maps.Map(document.getElementById('map'), {
zoom: 12,
center: myLatlng}),
marker = new google.maps.Marker({
position: myLatlng,
map: map,
title:"We are here!"
});
var accessPoint1 = new google.maps.LatLng(51.840913, -2.638603),
map = new google.maps.Map(document.getElementById('map'), {
zoom: 12,
center: accessPoint1}),
marker = new google.maps.Marker({
position: accessPoint1,
map: map,
title:"Access Point 1"
});
map.controls[google.maps.ControlPosition.TOP_CENTER].push($("#findButton")[0]);
function successCallback(position) {
var latlng = new google.maps.LatLng( position.coords.latitude,
position.coords.longitude),
myOptions = {
zoom: 3,
center: latlng,
mapTypeControl: false,
navigationControlOptions: {style: google.maps.NavigationControlStyle.SMALL},
mapTypeId: google.maps.MapTypeId.ROADMAP
},
bounds=new google.maps.LatLngBounds(latlng);
bounds.extend(marker.getPosition());
map.setOptions(myOptions);
map.fitBounds(bounds);
new google.maps.Marker({
position: latlng,
map: map,
title:"You are here!",
icon:'http://maps.gstatic.com/mapfiles/markers2/boost-marker-mapview.png'
});
}
function errorCallback() {
alert("I'm afraid your browser does not support geolocation.");
}
function findMe(){
$(this).hide();
if (navigator.geolocation){
navigator.geolocation
.getCurrentPosition(successCallback,errorCallback,{timeout:10000});
}
else{
alert("I'm afraid your browser does not support geolocation.");
}
}
$("#findButton").click(findMe);
}
google.maps.event.addDomListener(window,'load',initialize);
You are recreating the map for the second access point, which means you have two maps, each having one marker on it, the first of which is overwritten and not visible. You are also overwriting the marker variable (which shouldn't cause an issue):
Unless you have multiple <div>'s with maps in them, only create one map.
function initialize() {
var myLatlng = new google.maps.LatLng(51.843143, -2.643555),
map = new google.maps.Map(document.getElementById('map'), {
zoom: 12,
center: myLatlng
}),
marker = new google.maps.Marker({
position: myLatlng,
map: map,
title: "We are here!"
});
var accessPoint1 = new google.maps.LatLng(51.840913, -2.638603),
marker1 = new google.maps.Marker({
position: accessPoint1,
map: map,
title: "Access Point 1"
});
map.controls[google.maps.ControlPosition.TOP_CENTER].push($("#findButton")[0]);
function successCallback(position) {
var latlng = new google.maps.LatLng(position.coords.latitude,
position.coords.longitude),
myOptions = {
zoom: 3,
center: latlng,
mapTypeControl: false,
navigationControlOptions: {
style: google.maps.NavigationControlStyle.SMALL
},
mapTypeId: google.maps.MapTypeId.ROADMAP
},
bounds = new google.maps.LatLngBounds(latlng);
bounds.extend(marker.getPosition());
map.setOptions(myOptions);
map.fitBounds(bounds);
new google.maps.Marker({
position: latlng,
map: map,
title: "You are here!",
icon: 'http://maps.gstatic.com/mapfiles/markers2/boost-marker-mapview.png'
});
}
function errorCallback() {
alert("I'm afraid your browser does not support geolocation.");
}
function findMe() {
$(this).hide();
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(successCallback, errorCallback, {
timeout: 10000
});
} else {
alert("I'm afraid your browser does not support geolocation.");
}
}
$("#findButton").click(findMe);
}
google.maps.event.addDomListener(window, 'load', initialize);
html, body, #map {
height: 500px;
width: 500px;
margin: 0px;
padding: 0px
}
<script src="http://maps.google.com/maps/api/js"></script>
<div id="map" style="border: 2px solid #3872ac;"></div>