Using dropDown menu to assign values to variables with knockout - javascript

My goal is to use an if statement to give a value from another variable on my code.
HTML
<div id="countryContainer">
<div class="label">
Country:
</div>
<select id="countryDropDown"
data-bind="options: availableCountries,
optionsText: 'countryName',
value: selectedCountry">
</select>
</div>
Javascript
var mxLocations = [
{title: 'Monterrey', location: {lat: 25.6475262, lng: -100.4524278 }},
{title: 'Tulum, Quintana Roo', location: {lat: 20.2114185, lng: -87.4653502 }},
{title: 'Tijuana', location: {lat: 32.5335808, lng: -117.1236801 }},
{title: 'Guadalajara', location: {lat: 20.676856, lng: -103.344773 }}
];
var usLocations = [
{title: 'Laredo', location: {lat: 30.3079827, lng: -97.8934848 }},
{title: 'Venice Beach', location: {lat: 33.9799948, lng: -118.478614 }},
{title: 'Miami', location: {lat: 25.7825453, lng: -80.2994983 }},
{title: 'Wichita', location: {lat: 37.6647979, lng: -97.5837763 }}
];
var home = [
{title: 'Laredo', location: {lat: 30.3079827, lng: -97.8934848 }}
];
var allLocations = (mxLocations.concat(usLocations)).concat(home);
var locations = ""
function getData(dropdown) {
var value = dropdown.options[dropdown.selectedIndex].value;
alert(this.value);
}
// Knockout Constructor
var Country = function(name) {
this.countryName = ko.observable(name);
};
var viewModel = {
availableCountries : ko.observableArray([
new Country("All Locations"),
new Country("Home"),
new Country("Mexico"),
new Country("USA")
]),
selectedCountry : ko.observable() // Nothing selected by default
};
ko.applyBindings(viewModel);
This is what I want to accomplish, if a value from the dropDown menu is selected I want to give the value of a variavle to another variable
function locations() {
if (dropDownValue == "All Locations") {
var locations = allLocations;
} else if (dropDownValue == "Home") {
var locations = home;
} else if (dropDownValue == "Mexico") {
var locations = mxLocations;
} else if (dropDownValue == "USA") {
var locations = usLocations;
I've been looking in all over the place to accomplish this with no result I hope you can address me to the right dirrection

You can subscribe to the selectedCountry observable. The callback function passed as a parameter to the subscribe will be called every time selectedCountry changes.
Here's a working snippet:
var mxLocations = [
{title: 'Monterrey', location: {lat: 25.6475262, lng: -100.4524278 }},
{title: 'Tulum, Quintana Roo', location: {lat: 20.2114185, lng: -87.4653502 }},
{title: 'Tijuana', location: {lat: 32.5335808, lng: -117.1236801 }},
{title: 'Guadalajara', location: {lat: 20.676856, lng: -103.344773 }}
];
var usLocations = [
{title: 'Laredo', location: {lat: 30.3079827, lng: -97.8934848 }},
{title: 'Venice Beach', location: {lat: 33.9799948, lng: -118.478614 }},
{title: 'Miami', location: {lat: 25.7825453, lng: -80.2994983 }},
{title: 'Wichita', location: {lat: 37.6647979, lng: -97.5837763 }}
];
var home = [
{title: 'Laredo', location: {lat: 30.3079827, lng: -97.8934848 }}
];
var allLocations = (mxLocations.concat(usLocations)).concat(home);
var locations = ""
var Country = function(name) {
this.countryName = ko.observable(name);
};
var viewModel = {
availableCountries: ko.observableArray([
new Country("All Locations"),
new Country("Home"),
new Country("Mexico"),
new Country("USA")
]),
selectedCountry: ko.observable()
};
viewModel.selectedCountry.subscribe(function(selectedValue) {
if (selectedValue.countryName() == "All Locations") {
locations = allLocations;
} else if (selectedValue.countryName() == "Home") {
locations = home;
} else if (selectedValue.countryName() == "Mexico") {
locations = mxLocations;
} else if (selectedValue.countryName() == "USA") {
locations = usLocations;
}
console.log(locations);
});
ko.applyBindings(viewModel);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<div class="label">
Country:
</div>
<select id="countryDropDown" data-bind="options: availableCountries,
optionsText: 'countryName',
value: selectedCountry">
</select>
Click on Run code snippet to test it out.

Related

Toggle groups of markers in Google Maps API

I have several groups ("state") of markers on a map which I want to be able to toggle their visibility without reloading the page.
I'm finding lots of variations of having markergroups but they all seem to be not working with this google api version.
Here is the HTML
<input type="checkbox" id="state" name="Backlog" checked> Backlog
<input type="checkbox" id="state" name="Breached" checked> Breached
<input type="checkbox" id="state" name="Active" checked> Active
<input type="checkbox" id="state" name="Scheduled" checked> Scheduled
<div id="map" style="height:800px;"></div>
Here is the javascript
<script>
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 6,
center: {lat: 54.3266311, lng: -2.7585563},
mapTypeId: 'roadmap'
});
var infoWin = new google.maps.InfoWindow();
var markers = locations.map(function(location, i) {
var marker = new google.maps.Marker({
position: location,
icon: 'https://maps.google.com/mapfiles/kml/'+location.type,
});
google.maps.event.addListener(marker, 'click', function(evt) {
infoWin.setContent(location.info);
infoWin.open(map, marker);
})
return marker;
});
var markerCluster = new MarkerClusterer(map, markers, {
imagePath: 'https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m',
minimumClusterSize: 2,
maxZoom: 4,
zoomOnClick: false
}
);
}
var locations = [{lat:53.750503,lng:-2.429168,type:'/paddle/ylw-square-lv.png',state:'Backlog',info:"<strong>Order ID:</strong> 75199925"},{lat:51.290162,lng:-0.833112,type:'/paddle/ylw-square-lv.png',state:'Backlog',info:"<strong>Order ID:</strong> 76669845"},{lat:51.301737,lng:0.051969,type:'/paddle/ylw-square-lv.png',state:'Backlog',info:"<strong>Order ID:</strong> 75199930"},{lat:50.525378,lng:-3.594341,type:'/paddle/ylw-square-lv.png',state:'Backlog',info:"<strong>Order ID:</strong> 78875603"},{lat:51.581895,lng:-0.724800,type:'/paddle/ylw-square-lv.png',state:'Backlog',info:"<strong>Order ID:</strong> 78581052"},{lat:50.391133,lng:-4.072097,type:'/paddle/ylw-square-lv.png',state:'Backlog',info:"<strong>Order ID:</strong> 78106941"},{lat:51.318527,lng:-1.021035,type:'/paddle/ylw-square-lv.png',state:'Backlog',info:"<strong>Order ID:</strong> 78396115"},{lat:50.443925,lng:-3.561630,type:'/paddle/ylw-square-lv.png',state:'Backlog',info:"<strong>Order ID:</strong> 78875582"},{lat:53.625107,lng:-2.337432,type:'/paddle/blu-square-lv.png',state:'Active',info:"<strong>Order ID:</strong> 80444510"},{lat:52.432582,lng:-2.026563,type:'/paddle/blu-square-lv.png',state:'Active',info:"<strong>Order ID:</strong> 80423141"}]
Any help would be great :) I don't mind getting rid of the clusters, I just can't figure out how to!
HTML element ids must be unique, all your checkboxes currently have the same id.
<input type="checkbox" id="state" name="Backlog" checked> Backlog
<input type="checkbox" id="state" name="Breached" checked> Breached
<input type="checkbox" id="state" name="Active" checked> Active
<input type="checkbox" id="state" name="Scheduled" checked> Scheduled
typically that is what "name" is used for (it is allowed to be the same), so you can do this:
<input type="checkbox" name="state" id="Backlog" checked> Backlog
<input type="checkbox" name="state" id="Breached" checked> Breached
<input type="checkbox" name="state" id="Active" checked> Active
<input type="checkbox" name="state" id="Scheduled" checked> Scheduled
then when the checkboxes are clicked, process through the array of markers, setting the visible property appropriately:
google.maps.event.addDomListener(document.getElementById('Backlog'), 'click', clickListener);
google.maps.event.addDomListener(document.getElementById('Breached'), 'click', clickListener);
google.maps.event.addDomListener(document.getElementById('Active'), 'click', clickListener);
google.maps.event.addDomListener(document.getElementById('Scheduled'), 'click', clickListener);
function clickListener() {
var typeId = this.id;
var type;
for (var i=0; i<iconMapping.length;i++) {
if (iconMapping[i].state==typeId)
type = iconMapping[i].icon;
}
var markers = markerCluster.getMarkers();
for (var i=0; i<markers.length; i++) {
if (markers[i].getIcon().includes(type)) {
markers[i].setVisible(this.checked);
}
}
}
}
// your example doesn't include examples for Active/Scheduled, if they are
// duplicates of existing marker icons, a different approach will need to be used.
var iconMapping = [
{icon:'ylw-square-lv.png',state:'Backlog'},
{icon:'blu-square-lv.png',state:'Active'}
];
proof of concept fiddle
(if you want the clusters to reflect the currently visible icons, you will need to update the markers array passed in to it, rather than the visible property of the markers).
code snippet:
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 6,
center: {
lat: 54.3266311,
lng: -2.7585563
},
mapTypeId: 'roadmap'
});
var infoWin = new google.maps.InfoWindow();
var markers = locations.map(function(location, i) {
var marker = new google.maps.Marker({
position: location,
icon: 'https://maps.google.com/mapfiles/kml/' + location.type,
});
google.maps.event.addListener(marker, 'click', function(evt) {
infoWin.setContent(location.info);
infoWin.open(map, marker);
})
return marker;
});
var markerCluster = new MarkerClusterer(map, markers, {
imagePath: 'https://unpkg.com/#google/markerclustererplus#4.0.1/images/m',
minimumClusterSize: 2,
maxZoom: 4,
zoomOnClick: false
});
google.maps.event.addDomListener(document.getElementById('Backlog'), 'click', clickListener);
google.maps.event.addDomListener(document.getElementById('Breached'), 'click', clickListener);
google.maps.event.addDomListener(document.getElementById('Active'), 'click', clickListener);
google.maps.event.addDomListener(document.getElementById('Scheduled'), 'click', clickListener);
function clickListener() {
var typeId = this.id;
var type;
for (var i = 0; i < iconMapping.length; i++) {
if (iconMapping[i].state == typeId)
type = iconMapping[i].icon;
}
var markers = markerCluster.getMarkers();
for (var i = 0; i < markers.length; i++) {
if (markers[i].getIcon().includes(type)) {
markers[i].setVisible(this.checked);
}
}
}
}
var iconMapping = [{
icon: 'ylw-square-lv.png',
state: 'Backlog'
},
{
icon: 'blu-square-lv.png',
state: 'Active'
}
];
var locations = [{
lat: 53.750503,
lng: -2.429168,
type: '/paddle/ylw-square-lv.png',
state: 'Backlog',
info: "<strong>Order ID:</strong> 75199925"
}, {
lat: 51.290162,
lng: -0.833112,
type: '/paddle/ylw-square-lv.png',
state: 'Backlog',
info: "<strong>Order ID:</strong> 76669845"
}, {
lat: 51.301737,
lng: 0.051969,
type: '/paddle/ylw-square-lv.png',
state: 'Backlog',
info: "<strong>Order ID:</strong> 75199930"
}, {
lat: 50.525378,
lng: -3.594341,
type: '/paddle/ylw-square-lv.png',
state: 'Backlog',
info: "<strong>Order ID:</strong> 78875603"
}, {
lat: 51.581895,
lng: -0.724800,
type: '/paddle/ylw-square-lv.png',
state: 'Backlog',
info: "<strong>Order ID:</strong> 78581052"
}, {
lat: 50.391133,
lng: -4.072097,
type: '/paddle/ylw-square-lv.png',
state: 'Backlog',
info: "<strong>Order ID:</strong> 78106941"
}, {
lat: 51.318527,
lng: -1.021035,
type: '/paddle/ylw-square-lv.png',
state: 'Backlog',
info: "<strong>Order ID:</strong> 78396115"
}, {
lat: 50.443925,
lng: -3.561630,
type: '/paddle/ylw-square-lv.png',
state: 'Backlog',
info: "<strong>Order ID:</strong> 78875582"
}, {
lat: 53.625107,
lng: -2.337432,
type: '/paddle/blu-square-lv.png',
state: 'Active',
info: "<strong>Order ID:</strong> 80444510"
}, {
lat: 52.432582,
lng: -2.026563,
type: '/paddle/blu-square-lv.png',
state: 'Active',
info: "<strong>Order ID:</strong> 80423141"
}]
/* Always set the map height explicitly to define the size of the div
* element that contains the map. */
#map {
height: 90%;
}
/* Optional: Makes the sample page fill the window. */
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
<!DOCTYPE html>
<html>
<head>
<title>Marker Clustering</title>
<script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
<script src="https://unpkg.com/#google/markerclustererplus#4.0.1/dist/markerclustererplus.min.js"></script>
<!-- jsFiddle will insert css and js -->
</head>
<body>
<input type="checkbox" name="state" id="Backlog" checked> Backlog
<input type="checkbox" name="state" id="Breached" checked> Breached
<input type="checkbox" name="state" id="Active" checked> Active
<input type="checkbox" name="state" id="Scheduled" checked> Scheduled
<div id="map"></div>
<!-- Async script executes immediately and must be after any DOM elements used in callback. -->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap" async></script>
</body>
</html>
If you want the clusters to reflect the number of visible markers, you need to change the code to update the markers array in the MarkerClusterer:
function clickListener() {
var typeId = this.id;
var type;
var visibleMarkers = [];
for (var i=0; i<iconMapping.length;i++) {
if (iconMapping[i].state==typeId)
type = iconMapping[i].icon;
}
for (var i=0; i<markers.length; i++) {
if (markers[i].getIcon().includes(type)) {
markers[i].setVisible(this.checked);
}
if (markers[i].getVisible())
visibleMarkers.push(markers[i]);
}
markerCluster.clearMarkers();
markerCluster.addMarkers(visibleMarkers);
}
proof of concept fiddle
code snippet:
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 6,
center: {
lat: 54.3266311,
lng: -2.7585563
},
mapTypeId: 'roadmap'
});
var infoWin = new google.maps.InfoWindow();
var markers = locations.map(function(location, i) {
var marker = new google.maps.Marker({
position: location,
icon: 'https://maps.google.com/mapfiles/kml/' + location.type,
});
google.maps.event.addListener(marker, 'click', function(evt) {
infoWin.setContent(location.info);
infoWin.open(map, marker);
})
return marker;
});
var markerCluster = new MarkerClusterer(map, markers, {
imagePath: 'https://unpkg.com/#google/markerclustererplus#4.0.1/images/m',
minimumClusterSize: 2,
maxZoom: 4,
zoomOnClick: false
});
google.maps.event.addDomListener(document.getElementById('Backlog'), 'click', clickListener);
google.maps.event.addDomListener(document.getElementById('Breached'), 'click', clickListener);
google.maps.event.addDomListener(document.getElementById('Active'), 'click', clickListener);
google.maps.event.addDomListener(document.getElementById('Scheduled'), 'click', clickListener);
function clickListener() {
var typeId = this.id;
var type;
var visibleMarkers = [];
for (var i = 0; i < iconMapping.length; i++) {
if (iconMapping[i].state == typeId)
type = iconMapping[i].icon;
}
console.log("click type=" + type)
for (var i = 0; i < markers.length; i++) {
console.log("markers[" + i + "] icon=" + markers[i].getIcon() + " map=" + markers[i].getMap() + "visible=" + markers[i].getVisible());
if (markers[i].getIcon().includes(type)) {
markers[i].setVisible(this.checked);
console.log("markers[" + i + "] map=" + markers[i].getMap() + " visible=" + markers[i].getVisible())
}
if (markers[i].getVisible())
visibleMarkers.push(markers[i]);
}
markerCluster.clearMarkers();
console.log("after clear:" + markerCluster.getMarkers().length)
markerCluster.addMarkers(visibleMarkers);
console.log("after add:" + markerCluster.getMarkers().length)
}
}
var iconMapping = [{
icon: 'ylw-square-lv.png',
state: 'Backlog'
},
{
icon: 'blu-square-lv.png',
state: 'Active'
}
];
var locations = [{
lat: 53.750503,
lng: -2.429168,
type: '/paddle/ylw-square-lv.png',
state: 'Backlog',
info: "<strong>Order ID:</strong> 75199925"
}, {
lat: 51.290162,
lng: -0.833112,
type: '/paddle/ylw-square-lv.png',
state: 'Backlog',
info: "<strong>Order ID:</strong> 76669845"
}, {
lat: 51.301737,
lng: 0.051969,
type: '/paddle/ylw-square-lv.png',
state: 'Backlog',
info: "<strong>Order ID:</strong> 75199930"
}, {
lat: 50.525378,
lng: -3.594341,
type: '/paddle/ylw-square-lv.png',
state: 'Backlog',
info: "<strong>Order ID:</strong> 78875603"
}, {
lat: 51.581895,
lng: -0.724800,
type: '/paddle/ylw-square-lv.png',
state: 'Backlog',
info: "<strong>Order ID:</strong> 78581052"
}, {
lat: 50.391133,
lng: -4.072097,
type: '/paddle/ylw-square-lv.png',
state: 'Backlog',
info: "<strong>Order ID:</strong> 78106941"
}, {
lat: 51.318527,
lng: -1.021035,
type: '/paddle/ylw-square-lv.png',
state: 'Backlog',
info: "<strong>Order ID:</strong> 78396115"
}, {
lat: 50.443925,
lng: -3.561630,
type: '/paddle/ylw-square-lv.png',
state: 'Backlog',
info: "<strong>Order ID:</strong> 78875582"
}, {
lat: 53.625107,
lng: -2.337432,
type: '/paddle/blu-square-lv.png',
state: 'Active',
info: "<strong>Order ID:</strong> 80444510"
}, {
lat: 52.432582,
lng: -2.026563,
type: '/paddle/blu-square-lv.png',
state: 'Active',
info: "<strong>Order ID:</strong> 80423141"
}]
/* Always set the map height explicitly to define the size of the div
* element that contains the map. */
#map {
height: 90%;
}
/* Optional: Makes the sample page fill the window. */
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
<!DOCTYPE html>
<html>
<head>
<title>Marker Clustering</title>
<script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
<script src="https://unpkg.com/#google/markerclustererplus#4.0.1/dist/markerclustererplus.min.js"></script>
<!-- jsFiddle will insert css and js -->
</head>
<body>
<input type="checkbox" name="state" id="Backlog" checked> Backlog
<input type="checkbox" name="state" id="Breached" checked> Breached
<input type="checkbox" name="state" id="Active" checked> Active
<input type="checkbox" name="state" id="Scheduled" checked> Scheduled
<div id="map"></div>
<!-- Async script executes immediately and must be after any DOM elements used in callback. -->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap&v=weekly&channel=2" async></script>
</body>
</html>
You can use the setVisible function in marker class like this:
for (var i in markersToHide) {
markersToHide[i].setVisible(true);
}
// if markers are inside a cluster
markerCluster.repaint();

Ways to handle more than 23 waypoints Google Maps

I followed the below reference posted by mikep to handle more than 23 waypoints with premier license, it does handle more than 23 waypoints however it's not considering the optimal route with 28 waypoints. Please find the snippet of code below. Please let me know, if I missed anything.
Reference: Exceed 23 waypoint per request limit on Google Directions API (Business/Work level)
<!DOCTYPE html>
<html>
<head>
<title>Distance Matrix service</title>
<style>
#right-panel {
font-family: 'Roboto','sans-serif';
line-height: 30px;
padding-left: 10px;
}
#right-panel select, #right-panel input {
font-size: 15px;
}
#right-panel select {
width: 100%;
}
#right-panel i {
font-size: 12px;
}
html, body {
height: 100%;
margin: 0;
padding: 0;
}
#map {
height: 100%;
width: 50%;
}
#right-panel {
float: right;
width: 48%;
padding-left: 2%;
}
#output {
font-size: 11px;
}
</style>
</head>
<body>
<div id="right-panel">
<div id="inputs">
<pre>
var origin1 = {lat: 55.930, lng: -3.118};
var origin2 = 'Greenwich, England';
var destinationA = 'Stockholm, Sweden';
var destinationB = {lat: 50.087, lng: 14.421};
</pre>
</div>
<div>
<strong>Results</strong>
</div>
<div id="output"></div>
</div>
<div id="map"></div>
<script>
function initMap() {
var service = new google.maps.DirectionsService;
var map = new google.maps.Map(document.getElementById('map'));
// list of points
// list of points
var stations = [
{lat: 42.304403, lng: -89.04231900000002, name: 'Station 1'},
{lat: 42.236168, lng: -88.54327699999999, name: 'Station 2'},
{lat: 42.234782, lng: -88.53974299999999, name: 'Station 3'},
{lat: 42.151208, lng: -88.47053599999998, name: 'Station 4'},
{lat: 42.159458, lng: -88.44529899999998, name: 'Station 5'},
{lat: 42.157442, lng: -88.45886899999999, name: 'Station 6'},
{lat: 42.187703, lng: -88.36313100000001, name: 'Station 7'},
{lat: 42.188238, lng: -88.34060099999999, name: 'Station 8'},
{lat: 42.185022, lng: -88.309731, name: 'Station 9'},
{lat: 42.17901, lng: -88.32207499999998, name: 'Station 10'},
{lat: 42.165468, lng: -88.322519, name: 'Station 11'},
{lat: 41.91145, lng: -88.30584899999997, name: 'Station 12'},
{lat: 41.903634, lng: -88.3133890000000, name: 'Station 13'},
{lat: 41.67167, lng: -88.548182, name: 'Station 14'},
{lat: 41.564786, lng: -88.600822, name: 'Station 15'},
{lat: 41.561587, lng: -88.60028599999998, name: 'Station 16'},
{lat: 41.560347, lng: -88.597355, name: 'Station 17'},
{lat: 41.582568, lng: -88.90418599999998, name: 'Station 18'},
{lat: 41.5849, lng: -88.90929499999999, name: 'Station 19'},
{lat: 41.584279, lng: -88.91100, name: 'Station 20'},
{lat: 41.794906, lng: -88.93928299999999, name: 'Station 21'},
{lat: 41.796471, lng: -88.94241299999999, name: 'Station 22'},
{lat: 41.849191, lng: -89.0242670000000, name: 'Station 23'},
{lat: 41.846972, lng: -89.020418, name: 'Station 24'},
{lat: 41.875845, lng: -88.45214199999998, name: 'Station 25'},
{lat: 42.030196, lng: -88.271702, name: 'Station 26'},
{lat: 42.304403, lng: -89.04231900000002, name: 'Station 27'},
// ... as many other stations as you need
];
// Zoom and center map automatically by stations (each station will be in visible map area)
var lngs = stations.map(function(station) { return station.lng; });
var lats = stations.map(function(station) { return station.lat; });
map.fitBounds({
west: Math.min.apply(null, lngs),
east: Math.max.apply(null, lngs),
north: Math.min.apply(null, lats),
south: Math.max.apply(null, lats),
});
// Show stations on the map as markers
for (var i = 0; i < stations.length; i++) {
new google.maps.Marker({
position: stations[i],
map: map,
title: stations[i].name
});
}
// Divide route to several parts because max stations limit is 25 (23 waypoints + 1 origin + 1 destination)
for (var i = 0, parts = [], max = 25 - 1; i < stations.length; i = i + max)
parts.push(stations.slice(i, i + max + 1));
// Service callback to process service results
var service_callback = function(response, status) {
if (status != 'OK') {
console.log('Directions request failed due to ' + status);
return;
}
var renderer = new google.maps.DirectionsRenderer;
renderer.setMap(map);
renderer.setOptions({ suppressMarkers: true, preserveViewport: true });
renderer.setDirections(response);
};
// Send requests to service to get route (for stations count <= 25 only one request will be sent)
for (var i = 0; i < parts.length; i++) {
// Waypoints does not include first station (origin) and last station (destination)
var waypoints = [];
for (var j = 1; j < parts[i].length - 1; j++)
waypoints.push({location: parts[i][j], stopover: false});
// Service options
var service_options = {
origin: parts[i][0],
destination: parts[i][parts[i].length - 1],
waypoints: waypoints,
optimizeWaypoints: true,
travelMode: 'DRIVING'
};
// Send request
service.route(service_options, service_callback);
}
}
</script>
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyABPfm9lb39EOvsKMyrdnwdTJSN8IjqVy0&callback=initMap">
</script>
</body>
</html>
Global minima is not possible in that case using Google's API. We have to have an approximation -
Iteratively, cluster 20-25 points together and generate route based on that; Select one master point from the 20-25 points from each cluster - it can be 1st point/one in the middle by comparing averages etc,.
Generate another calcRoute using cluster's master points. Based on this, try to generate a broad route between clusters and route between clusters.

AngularJS, NgMap and GoogleMaps Api (infowindow function error)

I'm going to initalize infowindows (for google map markers) through angular controller (i'm using ng-map module)
NgMap.getMap().then (map) ->
$scope.map = map
for marker in markers
latLng = new (google.maps.LatLng)(marker.latitude, marker.longitude)
#initialize infoWindows through google map api, not ng-map module
contentString = 'is an example string'
infoWindow = new (google.maps.InfoWindow)(content: contentString)
$scope.dynMarkers.push new (google.maps.Marker)(position: latLng)
marker.addListener 'click', ->
infoWindow.open map, marker
$scope.markerClusterer = new MarkerClusterer(map,$scope.dynMarkers, {})
I have an error in console:
marker.addListener is not a function
I can't use an ng-map 'infowindow' DOM element in my view.
What's wrong?
marker object needs to be of google.maps.Marker type, try to replace:
$scope.dynMarkers.push new (google.maps.Marker)(position: latLng)
marker.addListener 'click', ->
infoWindow.open map, marker
with
markerObject = new (google.maps.Marker)(position: latLng) #<-Marker object
$scope.dynMarkers.push markerObject
markerObject.addListener 'click', ->
infoWindow.open map, markerObject
Example
angular.module('mapApp', ['ngMap'])
.controller('mapController', function ($scope, NgMap) {
NgMap.getMap().then(function (map) {
$scope.map = map;
$scope.dynMarkers = [];
$scope.markers.forEach(function (marker) {
var latLng = new google.maps.LatLng(marker.latitude, marker.longitude);
var contentString = 'is an example string'
var infoWindow = new (google.maps.InfoWindow)({ content: contentString });
var dynMarker = new google.maps.Marker({ position: latLng });
$scope.dynMarkers.push(dynMarker);
google.maps.event.addListener(dynMarker, 'click', function () {
infoWindow.open(map,dynMarker);
});
});
var mcOptions = { imagePath: 'https://cdn.rawgit.com/googlemaps/js-marker-clusterer/gh-pages/images/m' };
$scope.markerClusterer = new MarkerClusterer(map, $scope.dynMarkers, mcOptions)
});
$scope.markers = [
{ id: 1, name: 'Oslo', latitude: 59.923043, longitude: 10.752839 },
{ id: 2, name: 'Stockholm', latitude: 59.339025, longitude: 18.065818 },
{ id: 3, name: 'Copenhagen', latitude: 55.675507, longitude: 12.574227 },
{ id: 4, name: 'Berlin', latitude: 52.521248, longitude: 13.399038 },
{ id: 5, name: 'Paris', latitude: 48.856127, longitude: 2.346525 }
];
});
<script src="https://code.angularjs.org/1.4.8/angular.js"></script>
<script src="https://maps.googleapis.com/maps/api/js"></script>
<script src="https://rawgit.com/allenhwkim/angularjs-google-maps/master/build/scripts/ng-map.js"></script>
<script src="https://googlemaps.github.io/js-marker-clusterer/src/markerclusterer.js"></script>
<div ng-app="mapApp" ng-controller="mapController">
<ng-map default-style="true" zoom="3" center="59.339025, 18.065818">
</ng-map>
</div>

create a line between markers using ngmap

I am using ngmap and angular js to show a set of markers in a map without problem. I need paint a line that join these markers.
My code:
In view:
<map center="{{markers[0].lat}},{{markers[0].lng}}" zoom="12">
<marker ng-repeat="pos in markers" position="{{pos.lat}}, {{pos.lng}}"></marker>
</map>
in my controller:
var app = angular.module('Items', ['ngMap'])
app.controller('CICtrl', function($scope){
$scope.markers = [{id:1, lat:37.772323, lng: -122.214897}, {id:2, lat:21.291982, lng: -157.821856}, {id:3, lat:-27.46758, lng: 153.027892}];
});
For that purpose you could utilize shape directive, for example:
<shape name="polyline" path="{{path}}" geodesic="true" stroke-color="#FF0000" stroke-opacity="1.0" stroke-weight="2"></shape>
where path property is initialized from markers like this:
$scope.path = $scope.markers.map(function(marker){
return [marker.lat,marker.lng];
});
Working example
var app = angular.module('appMaps', ['ngMap']);
app.controller('mainCtrl', function ($scope) {
$scope.markers = [{ id: 1, lat: 37.772323, lng: -122.214897 }, { id: 2, lat: 21.291982, lng: -157.821856 }, { id: 3, lat: -27.46758, lng: 153.027892 }];
$scope.path = $scope.markers.map(function(marker){
return [marker.lat,marker.lng];
});
});
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&libraries=weather,visualization,panoramio"></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 id="map_canvas" ng-app="appMaps" ng-controller="mainCtrl" >
<map center="{{markers[0].lat}},{{markers[0].lng}}" zoom="5">
<marker ng-repeat="pos in markers" position="{{pos.lat}}, {{pos.lng}}"></marker>
<shape name="polyline" path="{{path}}" geodesic="true" stroke-color="#FF0000" stroke-opacity="1.0" stroke-weight="2">
</shape>
</map>
</div>
Plunker
For those who are looking to show driving directions between markers and customize the appearance of the line between each marker:
Working Example:
In your controller:
$scope.directions = [
{
origin:"Salt Lake City, Utah",
destination:"West Valley City, Utah",
panelName:"p1",
renderingOptions: {
polylineOptions: {
strokeColor: 'red'
}
},
wayPoints: [
{
location: {lat:40.6812675, lng: -111.9622787},
stopover: true
},
{
location: {lat:40.6812675, lng: -110.9622787},
stopover: true
},
]
},
{
origin:"West Valley City, Utah",
destination:"West Jordan, Utah",
panelName:"p1",
renderingOptions: {
polylineOptions: {
strokeColor: 'blue'
}
},
wayPoints: [
{
location: {lat:40.6812675, lng: -111.9622787},
stopover: true
},
{
location: {lat:40.6812675, lng: -109.9622787},
stopover: true
},
]
},
{
origin:"West Jordan, Utah",
destination:"Salt Lake City, Utah",
panelName:"p2",
renderingOptions: {
polylineOptions: {
strokeColor: 'green'
}
},
wayPoints: [
{
location: {lat:40.6812675, lng: -111.9622787},
stopover: true
},
{
location: {lat:40.6812675, lng: -108.9622787},
stopover: true
},
]
}
];
HTML:
Pass an object of the form:
renderingOptions: {polylineOptions: {strokeColor: 'red'}}
into the options attribute of the <directions> element
<div style="width: 100%; float:left; height:70%" >
<ng-map zoom="3" center="current-location" default-style="false" style="height: 450px; display:block; ">
<directions ng-repeat="dir in directions"
draggable="true"
options="{{dir.renderingOptions}}"
travel-mode="DRIVING"
waypoints="{{dir.wayPoints}}"
panel="{{dir.panelName}}"
origin="{{dir.origin}}"
destination="{{dir.destination}}">
</directions>
</ng-map>
</div>

JavaScript - leaflet, adding a bunch of markers

Let's say I have a bunch of markers (over 100) I want to add from this:
module.exports = [
{ value: 'Varrock', lng: 22.5, lat: -15.52249812756166, popular: 1 },
{ value: 'Lumbridge', lng: 25.9661865234375, lat: -43.644025847699496, popular: 1 },
{ value: 'Monastery', lng: -4.0924072265625, lat: -5.714379819235291 },
{ value: 'Edgeville', lng: 2.4884033203125, lat: -6.0094592380595495, popular: 1 },
{ value: 'Varrock Palace', lng: 22.412109375, lat: -6.882800241767556 },
{ value: 'Digsite', lng: 46.043701171875, lat: -17.266727823520508 },
{ value: 'River Salve', lng: 54.931640625, lat: -14.083301314706778 },
{ value: 'Morytania', lng: 64.610595703125, lat: -13.501814172428656 },
{ value: 'Mort Myre Swamp', lng: 59.820556640625, lat: -22.740723091194727 }
];
It uses browserify to get it. So, I do this:
var locations = require('./locations');
What would be the best way to add all of those into LayerGroup()? I mean, because doing var fairy = L.layerGroup([One, Two, Three...]); by hand would get tiresome.
So how would I go about adding all of those markers into a new layer (so I can toggle them on/off)
How about adding an empty L.LayerGroup, looping over your array and adding them to that layer?
var locations = [];
var layer = L.layerGroup().addTo(map);
locations.forEach(function (location) {
L.marker([location.lat, location.lng])
.bindPopup(location.value)
.addTo(layer);
});
Working example on Plunker: http://plnkr.co/edit/Q0DGqs?p=preview

Categories