I have included google map for the project that I'm working with. I have few checkboxes which are dynamic and when click on a checkbox according to that those locations will be displayed on google map. As follows: The thing is it is not refreshing and remove the previous markers when I check or uncheck those checkboxes again and again.
Vue Component:
<div v-for="vnos in vehicle_nos">
<input class="" type="checkbox" name="vehicle_num" :value="vnos.name" v-model="vehicle_nums" #change="getVehicleNumbers(vehicle_nums)">
<label for="vehicle_num">{{vnos.name}}</label><br>
</div>
functions I trigger:
getVehicleNumbers(vehicle_num){
this.allSelectedVehicles = vehicle_num;
axios.post('gps/get-gps-location/'+this.allSelectedVehicles)
.then(response => {
for (let i = 0; i < response.data.data.length; i++) {
this.all_data = JSON.parse(response.data.data[i]);
this.longtitudes = this.all_data.item.pos.x;
this.latitudes = this.all_data.item.pos.y;
let longlatitude = this.latitudes+','+this.longtitudes;
this.geocoder = new google.maps.Geocoder;
this.infowindow = new google.maps.InfoWindow;
//here I pass those coordinates to geocodeLatLng() function
this.geocodeLatLng(this.geocoder, this.map, this.infowindow, longlatitude);
}
}).catch(Erors => {
console.log('errors');
});
},
geocodeLatLng(geocoder, map, infowindow, longlatitude = null) {
var input = longlatitude;
var latlngStr = input.split(',', 2);
var latlng = {lat: parseFloat(latlngStr[0]), lng: parseFloat(latlngStr[1])};
//latlng looks like '6.916333,79.861018' this
geocoder.geocode({'location': latlng}, function(results, status) {
if (status === 'OK') {
if (results[0]) {
map.setZoom(11);
var marker = new google.maps.Marker({
position: latlng,
map: map,
});
infowindow.setContent(results[0].formatted_address);
infowindow.open(map, marker);
} else {
// alert('No results found');
}
} else {
// alert('Geocoder failed due to: ' + status);
}
});
},
In my controller I pass the data as an array to the response in axios.post('gps/get-gps-location/'+this.allSelectedVehicles) this one.
Then I loop all those and set markers one by one. But what I need is to remove all markers from the google map and display the upcoming response data. It's not removing and shows the upcoming markers as well as existing markers also. So there are few markers on same point.
I tried most of the given examples and links on stackoverfow also but couldn't able to find a better solution. Your help is appreciated a lot.
Finally changed the previous code and can be used it as follows
getVehicleNumbers(vehicle_num){
this.loading = false;
if (vehicle_num.length == 0) {
this.allSelectedVehicles = 0;
} else {
this.allSelectedVehicles = vehicle_num;
}
axios.post('gps/get-gps-location/'+this.allSelectedVehicles)
.then(response => {
this.deleteMarkers();
for (let i = 0; i < response.data.data.length; i++) {
this.all_data = JSON.parse(response.data.data[i]);
this.longtitudes = this.all_data.item.pos.x;
this.latitudes = this.all_data.item.pos.y;
let longlatitude = {lat: this.latitudes, lng: this.longtitudes};
this.addMarker(longlatitude);
this.loading = true;
}
}).catch(Erors => {
this.loading = true;
});
},
addMarker(location) {
let marker = new google.maps.Marker({
position: location,
map: this.map,
});
this.markersArray.push(marker);
},
setMapOnAll(map) {
for (var i = 0; i < this.markersArray.length; i++) {
this.markersArray[i].setMap(map);
}
},
clearMarkers() {
this.setMapOnAll(null);
},
deleteMarkers() {
this.clearMarkers();
this.markersArray = [];
},
Once check the checkbox then it'll trigger getVehicleNumbers function. and through that the markers will be shown in the map. And if the checkbox is unchecked again the function will trigger and reset the map. then it'll show the new markers only.
Related
This is the updated final code that I got it to work. I use the get.zoom and center.change to ensure that no matter the view of the map, there will always be 10 markers on the map! (original question below
'''
// Declare map and markers array globally
var map, markers = [];
function initMap() {
var myLatLng = {
lat: 0,
lng: 0
};
map = new google.maps.Map(document.getElementById('map'), {
zoom: 2,
center: myLatLng,
zoomControl: true
});
// Moved this out of the AJAX success and declared variable correctly
var infowindow = new google.maps.InfoWindow();
// Listen for zoom change event
// Handle markers display
google.maps.event.addListener(map, 'zoom_changed', handleMarkersDisplay);
$.ajax({
type: 'GET',
url: 'https://us-central1-cloud-calendar-project.cloudfunctions.net/InfoWindow',
success: function(data) {
data = JSON.parse(data);
for (var element in data) {
var marker = new google.maps.Marker({
position: {
lat: data[element].lat,
lng: data[element].lon
},
map: map,
title: element,
visible: false, // Default visibility is false
marker_celsius: data[element].celsius // Add celsius as marker property
});
console.log("marker#" + marker.getPosition().toUrlValue());
// Push this marker to the markers array
markers.push(marker);
google.maps.event.addListener(marker, 'click', (function(marker, element) {
return function() {
var content = 'Country: ' + data[element].country;
content += '<br>Temperature (°C): ' + data[element].celsius;
content += '<br>Day: ' + data[element].day;
content += '<br>Month: ' + data[element].month;
infowindow.setContent(content);
infowindow.open(map, marker);
}
})(marker, element));
}
// All markers have been added, sort the markers array by celsius value
markers.sort(function(a, b) {
return b.marker_celsius - a.marker_celsius;
});
map.addListener('center_changed', function() {
window.setTimeout(handleMarkersDisplay() , 3000);
});
// Handle markers display
handleMarkersDisplay();
}
});
}
function handleMarkersDisplay() {
console.log("handleMarkerDisplay zoom=" + map.getZoom());
// Check if map current zoom <= 2
if (map.getZoom() <= 2) {
hideAllMarkers();
displayMarkers();
} else if (map.getZoom() == 3) {
hideAllMarkers();
displayMarkers();
} else if (map.getZoom() == 4) {
hideAllMarkers();
displayMarkers();
} else if (map.getZoom() == 5) {
hideAllMarkers();
displayMarkers();
}
}
function hideAllMarkers() {
for (i = 0; i < markers.length; i++) {
markers[i].setVisible(false);
}
}
function displayMarkers() {
// add new markers to map
var shownMarkers = 10;
for (var i = 0; i < markers.length; i++) {
// Only show the first 10 markers in the viewport
if (shownMarkers > 0) {
if (map.getBounds().contains(markers[i].getPosition())) {
markers[i].setVisible(true);
shownMarkers--;
}
} else {
markers[i].setVisible(false);
}
}
}
function displayAllMarkers() {
// Zoom is greater than 3, show all markers
for (var i = 0; i < markers.length; i++) {
markers[i].setVisible(true);
}
}
'''
I am working on a web application whereby I want to show markers on a map based on the highest temperature recorded (from a JSON file I parse through). Currently, I am able to get the 10 highest temperatures markers on the map but when I zoom in it does not get updated to add new markers. So when I zoom in one I go from 10 markers to 8 markers in view(you need to scroll to see the other two markers). I would like to add two new markers that correspond to the next highest markers for that view so that whatever view/zoom you have you always see 10 markers! (probably not possible at some level, eg only see one country). The picture below demonstrates that at zoom 3, two markers are left out of view.
I found this implementation (https://github.com/endiliey/cs50/blob/master/pset8/mashup/static/scripts.js) by endiliey. However the implementation is not working..
If you want to show the highest 10 markers in the viewport, you need to count those:
function displayMarkers() {
// add new markers to map
var shownMarkers = 10;
for (var i = 0; i < markers.length; i++) {
// Only show the first 10 markers in the viewport
if (shownMarkers > 0) {
if (map.getBounds().contains(markers[i].getPosition())) {
markers[i].setVisible(true);
shownMarkers--;
} else {
markers[i].setVisible(false);
}
} else {
markers[i].setVisible(false);
}
}
}
Then call that function, when you load new markers or update the zoom:
proof of concept fiddle
code snippet:
// Declare map and markers array globally
var map, markers = [];
function initMap() {
var myLatLng = {
lat: 0,
lng: 0
};
map = new google.maps.Map(document.getElementById('map'), {
zoom: 2,
center: myLatLng,
zoomControl: true
});
// Moved this out of the AJAX success and declared variable correctly
var infowindow = new google.maps.InfoWindow();
// Listen for zoom change event
// Handle markers display
google.maps.event.addListener(map, 'zoom_changed', handleMarkersDisplay);
$.ajax({
type: 'GET',
url: 'https://us-central1-cloud-calendar-project.cloudfunctions.net/InfoWindow',
success: function(data) {
removeMarkers();
data = JSON.parse(data);
for (var element in data) {
var marker = new google.maps.Marker({
position: {
lat: data[element].lat,
lng: data[element].lon
},
map: map,
title: element,
visible: false, // Default visibility is false
marker_celsius: data[element].celsius // Add celsius as marker property
});
console.log("marker#" + marker.getPosition().toUrlValue());
// Push this marker to the markers array
markers.push(marker);
google.maps.event.addListener(marker, 'click', (function(marker, element) {
return function() {
var content = 'Country: ' + data[element].country;
content += '<br>Temperature (°C): ' + data[element].celsius;
content += '<br>Day: ' + data[element].day;
content += '<br>Month: ' + data[element].month;
infowindow.setContent(content);
infowindow.open(map, marker);
}
})(marker, element));
}
// All markers have been added, sort the markers array by celsius value
markers.sort(function(a, b) {
return b.marker_celsius - a.marker_celsius;
});
console.log("loaded "+markers.length+" markers");
// Handle markers display
handleMarkersDisplay();
}
});
}
function handleMarkersDisplay() {
console.log("handleMarkerDisplay zoom=" + map.getZoom());
// Check if map current zoom <= 2
if (map.getZoom() <= 5) {
displayMarkers();
} else {
displayAllMarkers();
}
}
function removeMarkers() {
for (i = 0; i < markers.length; i++) {
markers[i].setMap(null);
}
markers = [];
}
function hideAllMarkers() {
for (i = 0; i < markers.length; i++) {
markers[i].setVisible(false);
}
}
function displayMarkers() {
// add new markers to map
var shownMarkers = 10;
for (var i = 0; i < markers.length; i++) {
// Only show the first 10 markers in the viewport
if (shownMarkers > 0) {
if (map.getBounds().contains(markers[i].getPosition())) {
markers[i].setVisible(true);
shownMarkers--;
} else {
markers[i].setVisible(false);
}
} else {
markers[i].setVisible(false);
}
}
}
function displayAllMarkers() {
// Zoom is greater than 3, show all markers
for (var i = 0; i < markers.length; i++) {
markers[i].setVisible(true);
}
}
/* Always set the map height explicitly to define the size of the div
* element that contains the map. */
#map {
height: 100%;
}
/* Optional: Makes the sample page fill the window. */
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="map"></div>
<!-- Replace the value of the key parameter with your own API key. -->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap" async defer></script>
I am trying to toggle a button which will hide/show the google marker placed in the map. I have been searching for an answer on SOF but all offered array method. I am wondering if it is possible to do it without array.
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
zoom: 12,
center: {lat: 1.3420894594991328, lng: 103.83490918886719},
});
var ntuc = {
lat: 1.32805676,
lng: 103.9216584
};
var ntucmap = new google.maps.Marker({
position: ntuc,
map: map,
icon: 'https://maps.google.com/mapfiles/kml/paddle/blu-stars.png'
});
}
function toggleNTUCmap() {
if (!ntucmap.getVisible()) {
ntucmap.setVisible(true);
} else {
ntucmap.setVisible(false);
}
}
Button
<button class="button-oj pure-button" onclick="toggleNTUCmap()">
<i class="fas fa-hospital"></i> NTUC</button>
For function toggleNTUCmap(), I have tried the following which still won't work.
ntucmap.setMap(ntucmap.getMap() ? null : map);
Can't you do something like this?
function clearMap(map) {
for(var i = 0; i<ntucmap.length; i++){
ntucmap[i].setMap(null);
}
}
and for the show part
function setMapOnAll(map) {
for (var i = 0; i < ntucmap.length; i++) {
ntucmap[i].setMap(map);
}
}
Then to have it in one button you can keep a counter with your button and when it's even do one function when it's odd do the other?
// Adds a marker at the center of the map.
var ntuc = {lat: 1.32805676, lng: 103.9216584};
addMarker(ntuc);
setMapOnAll(null);
// Adds a marker to the map and push to the array.
function addMarker(location) {
var marker = new google.maps.Marker({
position: location,
map: map,
icon: 'https://maps.google.com/mapfiles/kml/paddle/blu-stars.png'
});
markers.push(marker);
}
// Sets the map on all markers in the array.
function setMapOnAll(map) {
for (var i = 0; i < markers.length; i++) {
markers[i].setMap(map);
}
}
// Show/Hide Markers
var counter = 0;
function toggleMarkers() {
if (counter == 0) {
setMapOnAll(map);
counter = 1;
} else {
setMapOnAll(null);
counter = 0;
}
}
In the end, I used array to save all the markers. Based on the button which user used to toggle, it will determine whether it marker(s) will be shown on the map or not.
I am trying to make google maps project, I was showing my marker on my map.
But now I want to make show/hide marker when I click checkbox,
this my code for showing marker in my maps, data for my marker I get from MySQL,
function initialize() {
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 18,
center: (lat,long)
});
var infowindow = new google.maps.InfoWindow({});
var latArea = new Array();
var longArea = new Array();
for (i = 0; i < $$; i++) //looping until all data from mysql
{
marker = new google.maps.Marker({
position: new google.maps.LatLng(latArea[i], longArea[i]),
map: map
});
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infowindow.setContent('<b>Coordinat : </b>'+String(latArea[i])+' , '+
String(longArea[i]));
infowindow.open(map, marker);
}
})(marker, i));
}
}
I was successfully displaying all data to marker in maps and add function for hide/show marker but only one marker is hide/show not all,
this my code for show/hide function
function toggleMarker() {
if (!marker.getVisible()) {
marker.setVisible(true);
} else {
marker.setVisible(false);
}
}
Thank you.
i was solving this problem,
this is correct code,
<script>
var markers = new Array();
function initialize() {
var latArea = new Array();
var longArea = new Array();
var i, newMarker;
for (i = 0; i < $$; i++)
{
newMarker = new google.maps.Marker({
position: new google.maps.LatLng(latArea[i], longArea[i]),
map: map,
icon: icon,
newMarker.category = 'show';
newMarker.setVisible(false);
markers.push(newMarker);
}
}
function displayMarkers(obj,category) {
var i;
for (i = 0; i < $$; i++)
{
if (markers[i].category === category) {
if ($(obj).is(":checked")) {
markers[i].setVisible(true);
} else {
markers[i].setVisible(false);
}
} else {
markers[i].setVisible(false);
}
}
}
and this checkbox in html for show/hidden marker
<input type="checkbox" onclick="displayMarkers(this,'area');" />
JS FIDDLE HERE:
http://jsfiddle.net/useyourillusiontoo/g77np63c/1/
I've created a google map that plants markers down and allows my to filter then with checkboxes without the page or map reloading. Yay!
Next I added marker cluster which worked too. However, when I now click on my markers the cluster doesn't update. That is.. the number inside the cluster doesnt change to reflect markers that are being hidden/displayed.
When I zoom in the markers are still being hidden/displayed but its just the cluster doesn't show this when zoomed out.
I've pasted my code below and would love any advice because i've been scratching my head.
var map;
var infowindow;
var image = [];
var gmarkers = [];
var clusterMarkers = [];
function mapInit(){
var centerCoord = new google.maps.LatLng(53.01265600000,-1.466105200000);
var mapOptions = {
zoom: 6,
center: centerCoord,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);
google.maps.event.addListener(map, 'click', function() {
infowindow.close();
});
addLocation();
var markerCluster = new MarkerClusterer(map, clusterMarkers);
function addLocation(place,category) {
for (var x in points){
var development = points[x];
var location = new google.maps.LatLng(development.lat, development.lng);
storeMarker(location, development);
}
}
function storeMarker(location, development){
var latLng = location;
var storedmarker = new google.maps.Marker({
position: latLng
});
storedmarker.mycategory = development.tid;
google.maps.event.addListener(storedmarker, 'click', function() {
if(typeof infowindow != 'undefined') infowindow.close();
infowindow = new google.maps.InfoWindow({
content: "<h3>"+ development.name +"</h3><a href='http://www.bbc.co.uk'>Show more!</a>"
});
infowindow.open(map, storedmarker);
});
clusterMarkers.push(storedmarker);
}
function show(category) {
for (var i=0; i<clusterMarkers.length; i++) {
if (clusterMarkers[i].mycategory == category) {
clusterMarkers[i].setVisible(true);
}
}
document.getElementById(category+"box").checked = true;
}
function hide(category) {
for (var i=0; i<clusterMarkers.length; i++) {
if (clusterMarkers[i].mycategory == category) {
clusterMarkers[i].setVisible(false);
}
}
document.getElementById(category+"box").checked = false;
infowindow.close();
}
function boxclick(box,category) {
if (box.checked) {
show(category);
} else {
hide(category);
}
}
jQuery(document).ready(function($) {
$('.b2bfilter').click(function () {
boxclick(this, this.value);
});
});
}
jQuery(document).ready(function(){
mapInit();
});
added markers as requested. They are a basic JSON object
var points = [
{"name":"House","lat":"53.341265600000","lng":"- 1.466105200000","tid":"1"},
{"name":"Old house","lat":"53.361066200000","lng":"-1.465752700000","tid":"2"}]
setting the visible-property will not have an effect when a marker is inside a cluster, you must also remove/add the marker from/to the markerclusterer.
Possible solution:
observe the visible_changed -event of the markers:
google.maps.event.addListener(storedmarker,'visible_changed',function(){
markerCluster[(this.getVisible())?'addMarker':'removeMarker'](this)
});
http://jsfiddle.net/doktormolle/g77np63c/4/
another(possibly better) approach(especially whene there are a lot of markers, because the solution above will force a redraw of the clusters for each affected marker):
First collect all affected markers and then use addMarkers/showMarkers to toggle them:
function toggle(category, show) {
var markers = [];
for (var i = 0; i < clusterMarkers.length; i++) {
if (clusterMarkers[i].mycategory == category) {
markers.push(clusterMarkers[i]);
clusterMarkers[i].setVisible(show);
}
}
if (markers.length) {
markerCluster[(show) ? 'addMarkers' : 'removeMarkers'](markers);
}
if (!show && infowindow) infowindow.close();
}
function boxclick(box, category) {
toggle(category, box.checked);
}
jQuery(document).ready(function ($) {
$('.b2bfilter').click(function () {
boxclick(this, this.value);
});
});
http://jsfiddle.net/doktormolle/g77np63c/5/
In the example fiddle, how can I get the total number of markers displayed on the map? I'm pushing each of the markers into an array like this:
markers.push(marker)
And attempting to get the total number of markers like this:
$('.marker-count span').html(markers.length);
Unfortunately, "markers.length" is returning 0 when it should be returning at least 3.
I have example code here: http://jsfiddle.net/287C7/
How can I display the total number of markers? Is it not possible to add each marker to my array?
I need to know the amount of markers shown so that I can alert the user if there are none.
Thanks,
In case you don't want to view the code on jsfiddle.net, here it is:
var map, places, tmpLatLng, markers = [];
var pos = new google.maps.LatLng(51.5033630,-0.1276250);
var mapOptions = {
zoom: 8,
center: new google.maps.LatLng(51.5033630,-0.1276250)
};
map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
// create the map and reference the div#map-canvas container
var markerBounds = new google.maps.LatLngBounds();
var service = new google.maps.places.PlacesService(map);
// fetch the existing places (ajax)
// and put them on the map
var request = {
location: pos,
radius: 48000, // Max radius
name: "mc donalds"
};
function callback(results, status) {
if (status == google.maps.places.PlacesServiceStatus.OK) {
for (var i = 0; i < results.length; i++) {
createMarker(results[i]);
}
$('#map-canvas').attr("data-markers",results.length);
$('.marker-count span').html(markers.length);
} else {
console.log("Places request failed: "+status);
}
} // end callback
function createMarker(place) {
var prequest = {
reference: place.reference
};
var tmpLatLng = place.geometry.location;
var marker = new google.maps.Marker({
map: map,
position: place.geometry.location
});
markers.push(marker);
markerBounds.extend( tmpLatLng );
} // end createMarker
service.nearbySearch(request, callback);
the placesSearch call is asynchronous, when you run your code:
$('.marker-count span').html(markers.length);
the result hasn't come back from the server yet. You need to do that in the call back after you update the markers array.
function callback(results, status) {
if (status == google.maps.places.PlacesServiceStatus.OK) {
for (var i = 0; i < results.length; i++) {
createMarker(results[i]);
}
$('#map-canvas').attr("data-markers",results.length);
$('.marker-count span').html(markers.length);
} else {
console.log("Places request failed: "+status);
}
} // end callback
working fiddle