Ways to handle more than 23 waypoints Google Maps - javascript

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.

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();

Showing map markers by location in list outside map

I have a number of markers and I want to show the markers in a list outside of the map. How can this be achieved using javascript? I am new to Javascript so help is appreciated. Code I have currently below, this is all working as expected apart from listing the map marker information.
I idea is that a list will appear depending on the option chosen in the dropdown for counties.
//List of Counties
var counties = [{
name: "Armagh",
code: "am",
zoom : 8,
center: {
lat: 54.274911,
lng: -6.626583
}
}, {
name: "Cork",
code: "c",
zoom : 8,
center: {
lat: 51.904246,
lng: -8.474038
}
}];
//List of Practices
var practice = [{
name: "Cross Veterinary Clinic",
position: {
lat: 54.07531,
lng: -6.60590
},
code: "am",
address: "8 Dundalk Road, Crossmaglen, Co. Armagh",
vet: "Carol Peterson",
programme: ['bvd', 'jd']
}, {
name: "Keltic Veterinary",
position: {
lat: 52.35386,
lng: -8.68204
},
code: "c",
address: "Charleville Town Centre, Bakers Road, Charleville, Co. Cork",
vet: "Gerald Gonzales",
programme: ['cck', 'bvd']
}];
var countyselect = document.getElementById('county')
countyselect.addEventListener("change", onCountySelect);
//render map
function initialize() {
var options = {
center: {
lat: 53.2734,
lng: -7.77832031
},
zoom: 6.5
};
map = new google.maps.Map(document.getElementById('map'), options);
marker = renderMarker();
}
function renderMarker() {
for (var i = 0; i < practice.length; i++) {
var marker = new google.maps.Marker({
position: practice[i].position,
title: practice[i].name,
map: map,
});
inforwindow(marker, map);
}
}
function inforwindow(marker, map) {
var infowindow = new google.maps.InfoWindow(); {
google.maps.event.addListener(marker, 'click', function(renderMarker) {
infowindow.setContent(marker.getTitle());
infowindow.open(map, marker);
});
}
}
function onCountySelect() {
let countySelect = document.getElementById("county");
let selectedCounty = countySelect.options[countySelect.selectedIndex];
let countyFound = (counties.find(({ name }) => name === selectedCounty.value));
if (selectedCounty.value === "all") {
map.setCenter({ lat: 53.2734, lng: -7.77832031 });
map.setZoom(6.5);
} else {
map.setCenter(countyFound.center);
map.setZoom(countyFound.zoom);
}
}
function resultsList() {
if (selectedCounty.value === "all") {
let countySelect = document.write(`<h3>${practice.name}</h3><p>${practice.address}</p><p>${practice.vet}</p>`);
}
}
I'm not sure at all from your code what your plan is with markers, or whether you intend to make items in the list clickable so that they highlight a specific marker on the map. But in any case, here's code to do what you asked - to create a list of relevant practices when a county is selected. I've dropped in some hacky test HTML just as it's easier to test.
Hopefully this will get you on the right path.
A couple of notes - you have used the backtick, ie using ` and ${variable} approach to rendering some content - this may not work on older browsers directly.
Also, please excuse the mix of single and double quotes - that's a matter of taste but I didn't see the point in going back and changing everything you had done. Good luck!
<!doctype html>
<html>
<head>
<title>Map Thing</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<style type="text/css">
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html, body {
font-family: Helvetica;
min-height: 100vh;
display: flex;
flex-direction: column;
}
#container {
flex: 1;
display: flex;
}
#options {
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
#results {
margin-top: 40px;
padding: 40px;
}
.result {
padding: 30px;
border: 1px solid #ddd;
}
#map {
flex: 3;
}
</style>
</head>
<body>
<div id="container">
<div id="options">
<select id="county" name="county" value="">
<option value="">Please choose</option>
<option value="am">Armagh</option>
<option value="c">Cork</option>
</select>
<div id="results"><!-- will be populated --></div>
</div>
<div id="map"></div>
</div>
<script>
//List of Counties
var counties = [{
name: "Armagh",
code: "am",
zoom : 8,
center: {
lat: 54.274911,
lng: -6.626583
}
}, {
name: "Cork",
code: "c",
zoom : 8,
center: {
lat: 51.904246,
lng: -8.474038
}
}];
//List of Practices
var practices = [{
name: "Cross Veterinary Clinic",
position: {
lat: 54.07531,
lng: -6.60590
},
code: "am",
address: "8 Dundalk Road, Crossmaglen, Co. Armagh",
vet: "Carol Peterson",
programme: ['bvd', 'jd']
}, {
name: "Keltic Veterinary",
position: {
lat: 52.35386,
lng: -8.68204
},
code: "c",
address: "Charleville Town Centre, Bakers Road, Charleville, Co. Cork",
vet: "Gerald Gonzales",
programme: ['cck', 'bvd']
}];
function initialize() {
var options = {
center: {
lat: 53.2734,
lng: -7.77832031
},
zoom: 6.5
};
map = new google.maps.Map(document.getElementById('map'), options);
var countyselect = document.getElementById('county');
countyselect.addEventListener('change', onCountySelect);
renderMarkers();
}
function renderMarkers() {
for (var i = 0; i < practices.length; i++) {
var marker = new google.maps.Marker({
position: practices[i].position,
title: practices[i].name,
map: map,
});
}
}
function showInfoWindow(marker, map) {
var infowindow = new google.maps.InfoWindow();
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent(marker.getTitle());
infowindow.open(map, marker);
});
}
function onCountySelect() {
var countySelect = document.getElementById("county");
var countiesByCode = counties.map(function(c){
return c.code;
});
var index = countiesByCode.indexOf(countySelect.value)
if (index > -1) {
var selectedCounty = counties[index];
map.setCenter(selectedCounty.center);
map.setZoom(selectedCounty.zoom);
renderResultsList(selectedCounty);
} else {
map.setCenter({ lat: 53.2734, lng: -7.77832031 });
map.setZoom(6.5);
clearResultsList();
}
}
function renderResultsList(selectedCounty) {
var relevantPractices = practices.filter(function(p){
return p.code === selectedCounty.code;
});
var resultsArea = document.getElementById("results");
resultsArea.innerHTML = "";
for(var i = 0; i < relevantPractices.length; i++) {
var practice = relevantPractices[i];
var div = document.createElement("div");
div.className = "result";
div.innerHTML = `<h3>${practice.name}</h3><p>${practice.address}</p><p>${practice.vet}</p>`;
resultsArea.appendChild(div);
}
}
function clearResultsList() {
document.getElementById("results").innerHTML = "";
}
</script>
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_KEY_HERE&callback=initialize"
async defer></script>
</body>
</html>

Using dropDown menu to assign values to variables with knockout

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.

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

Load content with URL update and default content

I have a jQuery plugin that loads content into a certain div. Ignore the drawmap function at the beginning. It only serves in one of the pages. I'm trying to load content into the div while updating the url (not redirecting). For example, if I click on About Us the url will show: calstateautoparts.com/beta/aboutus.html. If I click on contact us the url will show calstateautoparts.com/beta/contactus.html.
Also, I would like to have the plugin load a page in the div by default, home.html. How do I make both of these changes in my code?
You can see the live site at: http://calstateautoparts.com/beta
<script type="text/javascript">
jQuery(function($){
function drawmap(){
new Maplace({
locations: [
{
lat: 33.8583,
lon: -117.8678,
title: 'Anaheim',
html: [
'<h3>Anaheim</h3>',
'<p>1361 N RedGum St, Anaheim CA 92806<br>(714) 630-5954</p>'
].join(''),
zoom: 8
},
{
lat: 34.2358,
lon: -118.5739,
title: 'Chatsworth',
html: [
'<h3>Chatsworth</h3>',
'<p>20233 Corisco St, Chatsworth CA 91311<br>(818) 998-3001</p>'
].join(''),
zoom: 8
},
{
lat: 32.8142,
lon: -117.1247,
title: 'San Diego',
html: [
'<h3>San Diego</h3>',
'<p>4000 Ruffin Road Suite K, San Diego CA 92123<br>(858) 292-1622</p>'
].join(''),
zoom: 8
}
,
{
lat: 34.9137,
lon: -120.4632,
title: 'Santa Maria',
html: [
'<h3>Santa Maria</h3>',
'<p>1459 W. Fairway Dr., Santa Maria CA 93455<br>(805) 922-4445</p>'
].join(''),
zoom: 8
}
,
{
lat: 34.5011,
lon: -117.3279,
title: 'Victorville',
html: [
'<h3>Victorville</h3>',
'<p>15400-B Tamarack Road, Victorville CA 92392<br>(760) 243-5666</p>'
].join(''),
zoom: 8
}
,
{
lat: 36.1605,
lon: -115.1050,
title: 'Las Vegas',
html: [
'<h3>Las Vegas</h3>',
'<p>3101 Builders Ave., Las Vegas, NV 89101<br>(702) 452-2440</p>'
].join(''),
zoom: 8
}
,
{
lat: 33.1677,
lon: -117.2202,
title: 'Vista',
html: [
'<h3>Vista</h3>',
'<p>2055 Thibodo Rd, Vista CA 92081<br>(760) 599-0791</p>'
].join(''),
zoom: 8
}
,
{
lat: 33.6224,
lon: -117.7194,
title: 'Laguna Hills',
html: [
'<h3>Laguna Hills</h3>',
'<p>23561 Ridge Route Suite P, Laguna Hills CA 92653<br>(949) 699-3308</p>'
].join(''),
zoom: 8
}
,
{
lat: 34.4245,
lon: -118.4998,
title: 'Santa Clarita',
html: [
'<h3>Santa Clarita</h3>',
'<p>26846 Oak Ave Unit R, Santa Clarita CA 91315<br>(661) 424-9396</p>'
].join(''),
zoom: 8
}
],
map_div: '#gmap-list',
controls_type: 'list',
controls_title: 'Choose a location:'
}).Load();
}
$('.menuitem').click(function(e){
$('#contentarea').load(this.href, $(this).data('loadfunc') || null);
e.preventDefault();
});
$('#contactus').data({loadfunc: drawmap});
});
</script>

Categories