How to remove Google Map Markers without blinking? - javascript

I am trying to populate multiple markers via ajax request on 5 sec interval. Every thing is working fine, but markers blinks on each interval call.
I am clearing all markers & regenerating again on each interval call. I just want to re-generate markers without blinking.
Also, it's possible that ajax request can return different result set on each interval call.
Following is the code:
var map;
var places;
var markers = [];
var iw_map;
var markers_map = new Array();
function initialize() {
geocoder = new google.maps.Geocoder();
var latlngCenter = new google.maps.LatLng(25.1999721, 66.8354386);
iw_map = new google.maps.InfoWindow();
var mapOptions = {
center: latlngCenter,
zoom: 7,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
fetchPlaces();
fitMapToBounds_map();
}
function fetchPlaces(cityId = null, hubId = null, riderId = null) {
clearMarkers();
$.ajax({
url: '{{ route('get-markers') }}',
method:'POST',
data: {'city_id': cityId, hub_id: hubId, rider_id: riderId},
dataType: 'json',
cache: false,
success: function(data) {
// console.log(markers);
var markerz = data.markers;
// clearMarkers();
$.each(markerz, function (i, dt) {
var marker_icon = {url: dt.icon};
var position = new google.maps.LatLng(dt.lat,dt.lng);
var marker = new google.maps.Marker({
map: map,
position: position,
icon: marker_icon
});
// newcoordinate = new google.maps.LatLng(dt.lat,dt.lng);
google.maps.event.addListener(marker, "click", function(event) {
$.ajax({
url: '{{ route('get-marker-info') }}',
method:'POST',
data: JSON.parse(dt.params),
success: function(data) {
iw_map.setContent(data.infoBox);
iw_map.open(map, marker);
}
});
});
markers.push(marker.getPosition());
markers_map.push(marker);
});
// fitMapToBounds_map();
}
});
}
function fitMapToBounds_map() {
var bounds = new google.maps.LatLngBounds();
if (markers.length>0) {
for (var i=0; i<markers.length; i++) {
console.log(markers[i]);
bounds.extend(markers[i]);
}
map.fitBounds(bounds);
}
}
function clearMarkers() {
for (var i = 0; i < markers_map.length; i++) {
markers_map[i].setMap(null);
}
markers_map = [];
}
function loadScript_map() {
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "http://maps.googleapis.com/maps/api/js?key=API_KEY&sensor=false&v=3&libraries=places&callback=initialize";
document.body.appendChild(script);
}
window.onload = loadScript_map;
setInterval(fetchPlaces, 5000);

This is untested code so it might need a few adjustments.
I renamed your variables with meaningful names and changed the logic to first add the new markers, then remove the old markers.
When you get your markers with AJAX, first empty the new_markers array, then plot the markers on the map, and add them to the new_markers array. Then clear the old markers from the map (markers array). The first time, this array will be empty so nothing will happen. Copy new_markers array to markers array. Repeat.
Here is the code:
var map;
var places;
var markers_positions = [];
var markers = [];
var new_markers = [];
var iw_map;
function initialize() {
geocoder = new google.maps.Geocoder();
var latlngCenter = new google.maps.LatLng(25.1999721, 66.8354386);
iw_map = new google.maps.InfoWindow();
var mapOptions = {
center: latlngCenter,
zoom: 7,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
fetchPlaces();
fitMapToBounds_map();
}
function fetchPlaces(cityId = null, hubId = null, riderId = null) {
new_markers = [];
$.ajax({
url: '{{ route('get-markers') }}',
method: 'POST',
data: {
city_id: cityId,
hub_id: hubId,
rider_id: riderId
},
dataType: 'json',
cache: false,
success: function(data) {
$.each(data.markers, function(i, dt) {
var marker_icon = {
url: dt.icon
};
var position = new google.maps.LatLng(dt.lat, dt.lng);
var marker = new google.maps.Marker({
map: map,
position: position,
icon: marker_icon
});
google.maps.event.addListener(marker, "click", function(event) {
$.ajax({
url: '{{ route('get-marker-info') }}',
method: 'POST',
data: JSON.parse(dt.params),
success: function(data) {
iw_map.setContent(data.infoBox);
iw_map.open(map, marker);
}
});
});
markers_positions.push(marker.getPosition());
new_markers.push(marker);
clearMarkers();
});
}
});
}
function fitMapToBounds_map() {
var bounds = new google.maps.LatLngBounds();
for (var i = 0; i < markers_positions.length; i++) {
console.log(markers_positions[i]);
bounds.extend(markers_positions[i]);
}
map.fitBounds(bounds);
}
function clearMarkers() {
for (var i = 0; i < markers.length; i++) {
markers[i].setMap(null);
}
markers = new_markers;
}
function loadScript_map() {
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "http://maps.googleapis.com/maps/api/js?key=API_KEY&sensor=false&v=3&libraries=places&callback=initialize";
document.body.appendChild(script);
}
window.onload = loadScript_map;
setInterval(fetchPlaces, 5000);

Related

Sending AJAX response to Google Maps location markers with JSON

Upon clicking a button, an AJAX response is called to output JSON based on a search query. I would like to use the variable all_locations from the AJAX response, to output into the Google map markers. Not too sure how this can be done. I researched into using async as false but to no success.
Form
<form id="filter">
<span class="ek-search-address col-xs-8">
<label for="address">Location</label>
<input id="address" name="property_location" value="New York" placeholder="Input Address" type="text"/>
</span>
<span class="ek-search-radius live-search col-xs">
<select id="radius_km">
<option value=1>1km</option>
<option value=2>2km</option>
<option value=5>5km</option>
<option value=30>30km</option>
</select>
</span>
<button onClick="showCloseLocations()">Search</button>
<input type="hidden" name="action" value="ek_search">
</form>
<div id="map_canvas">
AJAX call
jQuery(function($){
$('#filter').submit(function(){
var filter = $('#filter');
var ajaxurl = '<?php echo admin_url("admin-ajax.php", null); ?>';
data = { action: "ek_search"};
var all_locations = $.ajax({
url: ajaxurl,
data:data,
async:false,
type: 'POST', // POST
dataType: 'json',
success: function(response) {
console.log(response);
}
});
return false;
});
});
map.js
jQuery(function($) {
var map = null;
var radius_circle;
var markers_on_map = [];
var geocoder;
var infowindow;
new google.maps.places.Autocomplete(
(document.getElementById('address')), {
types: ['geocode']
});
//initialize map on document ready
$(document).ready(function() {
var latlng = new google.maps.LatLng(50.927978, -5.408908);
var myOptions = {
zoom: 17,
center: latlng,
mapTypeControl: true,
mapTypeControlOptions: {
style: google.maps.MapTypeControlStyle.DROPDOWN_MENU
},
navigationControl: true,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
geocoder = new google.maps.Geocoder();
google.maps.event.addListener(map, 'click', function() {
if (infowindow) {
infowindow.setMap(null);
infowindow = null;
}
});
});
function showCloseLocations() {
var i;
var radius_km = $('#radius_km').val();
var address = $('#address').val();
//remove all radii and markers from map before displaying new ones
if (radius_circle) {
radius_circle.setMap(null);
radius_circle = null;
}
for (i = 0; i < markers_on_map.length; i++) {
if (markers_on_map[i]) {
markers_on_map[i].setMap(null);
markers_on_map[i] = null;
}
}
if (geocoder) {
geocoder.geocode({
'address': address
}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
if (status != google.maps.GeocoderStatus.ZERO_RESULTS) {
var address_lat_lng = results[0].geometry.location;
radius_circle = new google.maps.Circle({
center: address_lat_lng,
radius: radius_km * 1000,
clickable: false,
map: map
});
if (radius_circle) map.fitBounds(radius_circle.getBounds());
for (var j = 0; j < all_locations.length; j++) {
(function(location) {
var marker_lat_lng = new google.maps.LatLng(location.lat, location.lng);
var distance_from_location = google.maps.geometry.spherical.computeDistanceBetween(address_lat_lng, marker_lat_lng); //distance in meters between your location and the marker
if (distance_from_location <= radius_km * 1000) {
var new_marker = new google.maps.Marker({
position: marker_lat_lng,
map: map,
title: location.name
});
google.maps.event.addListener(new_marker, 'click', function() {
if (infowindow) {
infowindow.setMap(null);
infowindow = null;
}
infowindow = new google.maps.InfoWindow({
content: '<div style="color:red">' + location.name + '</div>' + " is " + distance_from_location + " meters from my location",
size: new google.maps.Size(150, 50),
pixelOffset: new google.maps.Size(0, -30),
position: marker_lat_lng,
map: map
});
});
markers_on_map.push(new_marker);
}
})(all_locations[j]);
}
} else {
alert("No results found while geocoding!");
}
} else {
alert("Geocode was not successful: " + status);
}
});
}
}
});
Ajax is an asynchronous process, so you need to send all locations as an parameter inside success callback function
Try this:
Ajax:
jQuery(function($){
$('#filter').submit(function(e){
e.preventDefault();//preventing form to submit with page reload
var filter = $('#filter');
var ajaxurl = '<?php echo admin_url("admin-ajax.php", null); ?>';
data = { action: "ek_search"};
$.ajax({
url: ajaxurl,
data:data,
async:false,
type: 'POST', // POST
dataType: 'json',
success: function(response) {
console.log(response);
showCloseLocations(response.all_locations);
}
});
return false;
});
});
Update function showCloseLocations to accept all_locations as parameter
function showCloseLocations(all_locations) {
//show location function code here
}
Question: I would like to know how you are submitting your form with #filter? because there is no submit type button in your html, make sure to change type of search button to submit instead of button so that first form can submit with search input to get all locations
<button type="submit">Search</button>

Uncaught TypeError: Cannot read property 'targetLat' of undefined

well i just put some markers on google map and it works as i want and marker is displayed as required on the map but i get this error in the console i don't know why which makes the app runs on android but not on windows phone
function initMap() {
var map;
var faisalabad = { lat: 30.044281, lng: 31.340002 };
$('#locaitonBtn').click(function () {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function (position) {
var latlng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
map.setCenter(latlng);
});
}
})
map = new google.maps.Map(document.getElementById('map'), {
zoom: 10,
center: faisalabad,
disableDefaultUI: true
});
$.ajax({
async:false,
url: "https://someUrl",
method: "GET",
dataType: 'json',
success: function (data) {
var infowindow = new google.maps.InfoWindow();
for (i = 0; i <= data.targets.length; i++) {
var myLatLng = new google.maps.LatLng(data.targets[i].targetLat, data.targets[i].targetLong);
myMarker = new google.maps.Marker({
map: map,
animation: google.maps.Animation.DROP,
position: myLatLng
});
google.maps.event.addListener(myMarker, 'click', (function (myMarker, i) {
return function () {
infowindow.setContent(data.targets[i].targetName);
infowindow.open(map, myMarker);
}
})(myMarker, i));
}
}
})
}
$.ajax({
async:false,
url: "https://someUrl",
method: "GET",
dataType: 'json',
success: function (data) {
var infowindow = new google.maps.InfoWindow();
for (var i = 0; i <= data.targets.length; i++) {
var myLatLng = new google.maps.LatLng(data.targets[i].targetLat, data.targets[i].targetLong);
var myMarker = new google.maps.Marker({
map: map,
animation: google.maps.Animation.DROP,
position: myLatLng
});
google.maps.event.addListener(myMarker, 'click', (function (myMarker, i, data) {
return function () {
infowindow.setContent(data.targets[i].targetName);
infowindow.open(map, myMarker);
}
})(myMarker, i, data));
}
}
});
changed 3 things:
var i = 0 in for statement
var myMarker = new google.maps.Marker ... (it's not a global)
injecting data to the anonymous click listener function because it has no scope on the data object.
i'm not sure this works because i have no test envoirement for it. but hope it helps you to figure out the failure.
i think the first point was the failure because you tried to use a global i in your for loop and reset it anywhere else in your code. so the array index returns undefined
Well I couldn't solve the problem or find an answer to it anywhere so i added the success function to a try catch block so it don't console the error and i can run the app now on windows phone

How to update map data throug ajax

I am trying to update map data through ajax but ist's not working here is my code:
$(document).ready(function() {
function makeRequest(){
$.ajax({
url:"<?php echo Url::base(true).'/users/online-peoples'; ?>",
type:"POST",
})
.done(function(result){
var icon1 = 'https://mt.googleapis.com/vt/icon/name=icons/onion/27-cabs.png&scale=1.0';
if(result){
var map;
function initMap() {
var infowindow = new google.maps.InfoWindow();
var mapOptions = {
zoom: 12,
center: new google.maps.LatLng('30.7333','76.7794'),
mapTypeControlOptions: {
mapTypeIds: ['roadmap']
}
};
var map = new google.maps.Map(document.getElementById('map'), mapOptions);
var online =result;
var mapIcons = ['https://mt.googleapis.com/vt/icon/name=icons/onion/27-cabs.png&scale=1.0'];
var person = {3:"Customer1 : ", 4:"Driver1 : "};
var arr = [];
var marker, i;
for (i = 0; i < online.length; i++)
{
console.log(online[i]);
arr.push(new google.maps.LatLng(online[i][0], online[i][0]));
marker = new google.maps.Marker({
position: new google.maps.LatLng(online[i][0], online[i][1]),
icon:mapIcons[0],
suppressMarkers: true,
map: map
});
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infowindow.setContent(person[online[i][4]]+online[i][2]+', Phone : '+online[i][5]);
infowindow.open(map, marker);
}
})(marker, i));
}
}
}
});
}
setInterval(makeRequest, (10 * 1000));
});
The above code update map icons and date every 10 secondas but it's not working.Where i am doing wrong ?
This is my data :
[
["30.740395","76.7804482","Dbd Dbdhdh","1",4],
["30.740395","76.7804482","Sam Sam","1",4],
["30.7404344","76.7804032","Sumit Kumar","1",4],
["30.74041018","76.78060575","Chetan Nagrath","3",4],
["30.7403555","76.7804933","Sahil Kapoor","2",4],
["30.7403648","76.7805835","paras kumar",1,3]
]
You are not initializing your map. Since its inside initMap map function no one is calling it.
And there is no need to initialize every time when you got the data from the server. Just initialize once and use the same map object for your other works also.
And be careful while getting the data, You are trying to get the data in the index 5. But the array has only 0 to 4.
Try in the below fashion.
$(document).ready(function() {
function makeRequest() {
$.ajax({
url : "url",
type : "POST",
}).done(function(result) {
if (result) {
console.log("You Got your data", result);
}
});
};
var map = new google.maps.Map(document.getElementById('map'), {
zoom : 12,
center : new google.maps.LatLng('30.7333', '76.7794'),
mapTypeControlOptions : {
mapTypeIds : [ 'roadmap' ]
}
});
setInterval(makeRequest, (10 * 1000));
});
Here you will get data after 10 second. If you want at the first time itself means call makeRequest after initialization of map once.

Refresh JavaScript and Ajax call to controller after 3 seconds without any click in Razor View in MVC 4

Controller Action :
public ActionResult googlemap()
{
return View();
}
It will call the googlemap.cshtml View.
So Ajax Call and JavaScript code in googlemap.cshtml View :
#{
ViewBag.Title = "Google Map";
}
<script src="~/Scripts/jquery-1.8.2.min.js"></script>
<script src="http://maps.googleapis.com/maps/api/js?key=AIzaSyCM7G5ruvunb0K7qxm6jb1TssJUwROqs-g" type="text/javascript"></script>
<script type="text/javascript">
var myMarkers = [];
window.onload = function () {
$.ajax({
async: false,
type: "POST",
dataType: "json",
url: '#Url.Action("googlemapfindlatlon", "Home")',
data: '{}',
success: function (data) {
$.each(data, function (i, v) {
myMarkers.push(v);
});
var mapOptions = {
center: new google.maps.LatLng(myMarkers[0].Latitude, myMarkers[0].Langitude),
zoom: 10,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
//alert(myMarkers[0].Latitude)
//alert(myMarkers[0].Langitude)
var infoWindow = new google.maps.InfoWindow();
var map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
var lat_lng = new Array();
var latlngbounds = new google.maps.LatLngBounds();
for (i = 0; i < myMarkers.length; i++) {
var data = myMarkers[i]
var myLatlng = new google.maps.LatLng(data.Latitude, data.Langitude);
lat_lng.push(myLatlng);
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
title: data.title
});
latlngbounds.extend(marker.position);
(function (marker, data) {
google.maps.event.addListener(marker, "click", function (e) {
infoWindow.setContent(data.Address);
infoWindow.open(map, marker);
});
})(marker, data);
}
//map.setCenter(latlngbounds.getCenter());
//map.fitBounds(latlngbounds);
}
});
//init google map
}
</script>
<div id="map_canvas" style="border-top: none; width: 100%; margin-top: -1px;
height: 250px; background-color: #FAFAFA; margin-top: 0px;">
</div>
Action in Controller :
public JsonResult googlemapfindlatlon()
{
Models.Vehicle_Tracking_SystemEntities entities = new Vehicle_Tracking_SystemEntities();
var latlon = entities.LatLangs.ToList();
//var latlon = entities.LatLangs.OrderByDescending(x => x.Id).Take(1).ToList();
return Json(latlon, JsonRequestBehavior.AllowGet);
}
So here I wants that my Ajax call is done repeatedly after each 3 seconds automatically to the JsonResult action in controller , and controller get the latest values and send back to the Ajax.
var myMarkers = [];
window.onload = function () {
DisplayMap();
}
function DisplayMap() {
$.ajax({
async: false,
type: "POST",
dataType: "json",
url: '#Url.Action("googlemapfindlatlon", "Home")',
data: '{}',
success: function (data) {
$.each(data, function (i, v) {
myMarkers.push(v);
});
var mapOptions = {
center: new google.maps.LatLng(myMarkers[0].Latitude, myMarkers[0].Langitude),
zoom: 10,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
//alert(myMarkers[0].Latitude)
//alert(myMarkers[0].Langitude)
var infoWindow = new google.maps.InfoWindow();
var map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
var lat_lng = new Array();
var latlngbounds = new google.maps.LatLngBounds();
for (i = 0; i < myMarkers.length; i++) {
var data = myMarkers[i]
var myLatlng = new google.maps.LatLng(data.Latitude, data.Langitude);
lat_lng.push(myLatlng);
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
title: data.title
});
latlngbounds.extend(marker.position);
(function (marker, data) {
google.maps.event.addListener(marker, "click", function (e) {
infoWindow.setContent(data.Address);
infoWindow.open(map, marker);
});
})(marker, data);
}
//map.setCenter(latlngbounds.getCenter());
//map.fitBounds(latlngbounds);
}
});
//init google map
}
setTimeout(function () {
DisplayMap();
}, 3000);// JavaScript source code
Try this:
var searchActiveTVInterval = null;
$(document).ready(function () {
clearInterval(searchActiveTVInterval);
searchActiveTVInterval = setInterval("SearchActiveTV()", 3000);
});
function SearchActiveTV() {
console.log(1);
//your AJAX Call
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
window.setInterval(function(){
/// call your ajax function here
}, 3000);

how to remove the old marker from google map place new one?

I have load the default google map with markers and have to remove the previous markers with the current one. I have used googolle mpa and initiazlie the function before the page load
Please check with my below code and adivse on me how to achieve this.
$(document).ready(function() {
var markers = [];
//var markers = [];
var track_click = 0; //track user click on "load more" button, righ now it is 0 click
var total_pages = 4;
var page;
$.ajax({
url:"<?php echo base_url('search_jobs/fetch_jobs')?>",
type: "POST",
dataType: 'json',
beforeSend: function(){
$('#loader-icon').show();
},
complete: function(){
$('#loader-icon').hide();
},
success: function (result) {
//alert("hi");
$('#jobsfound').html(result.search_results);
var list = result.map_array;
var image = "<?php echo base_url(); ?>assets/images/pros_marker.png";
$.each(list, function(index, value) {
var newLatLng = new google.maps.LatLng(list[index].latitude, list[index].longitude);
console.log(list[index].latitude, list[index].longitude);
markers [index] = new google.maps.Marker({
map: map
});
markers[index].setPosition(newLatLng);
//markers.push(marker);
})
//initialize();
}
})
$.ajax({
url:"<?php echo base_url('search_jobs/fetch_jobs')?>",
type: "POST",
data:'location_checkboxes='+ values + '&budget_value=' + budget_value +
'&job_dates=' + job_date + '&page='+track_click,
dataType: 'json',
beforeSend: function(){
$('#loader-icon').show();
},
complete: function(){
$('#loader-icon').hide();
},
success: function (result) {
$('#jobsfound').html(result.search_results);
//alert($("#test").text());
//initialize();
var list = result.map_array;
var image = "<?php echo base_url(); ?>assets/images/pros_marker.png";
$.each(list, function(index, value) {
var lat = parseFloat(value.latitude);
var lng = parseFloat(value.longitude);
var newLatLng = new google.maps.LatLng(list[index].latitude, list[index].longitude);
//markers[index] = new google.maps.Marker({
// position: newLatLng,
// icon:image,
// map: map,
// draggable: false
// });
markers [index] = new google.maps.Marker({
map: map
});
markers[index].setPosition(newLatLng);
//markers.push(marker);
})
}
})
google.maps.event.addDomListener(window, 'load', initialize);
set the markers as global array before initialize function (please refer http://www.w3schools.com/googleapi/google_maps_basic.asp)
var markers = [];
$(document).ready(function() {
//var markers = [];
//var markers = [];
var track_click = 0; //track user click on "load more" button, righ now it is 0 click
var total_pages = 4;
var page;
$.ajax({
url:"<?php echo base_url('search_jobs/fetch_jobs')?>",
type: "POST",
dataType: 'json',
beforeSend: function(){
$('#loader-icon').show();
},
complete: function(){
$('#loader-icon').hide();
},
success: function (result) {
//alert("hi");
$('#jobsfound').html(result.search_results);
var list = result.map_array;
var image = "<?php echo base_url(); ?>assets/images/pros_marker.png";
$.each(list, function(index, value) {
var contentString = '<div id="content">'+list[index].title+'</div>';
var infowindow = new google.maps.InfoWindow({
content: contentString
});
var newLatLng = new google.maps.LatLng(list[index].latitude, list[index].longitude);
console.log(list[index].latitude, list[index].longitude);
markers [index] = new google.maps.Marker({
icon:image,
map: map
});
markers[index].setPosition(newLatLng);
markers[index].addListener('mouseover', function() {
infowindow.open(map, marker);
});
//markers.push(marker);
})
//initialize();
}
})
});

Categories