google map map.fitBounds() is not a function - javascript

I have error when I load my page: https://www.cupsubito.it/dove-siamo
I don't kwon because about this error. Thank you very much for helping.
Thanks for help me!
The code JS is:
let _locations = [];
var elenco;
google.maps.visualRefresh = true;
var slider, infowindow = null;
var bounds = new google.maps.LatLngBounds();
var current = 0;
var map = 0;
var icons = {
//'default': '/assets/img/marker.png'
};
function showMap() {
infowindow.close();
if (!map.slide) {
return;
}
var next, marker;
if (_locations.length == 0) {
return
} else if (_locations.length == 1) {
next = 0;
}
if (_locations.length > 1) {
do {
next = Math.floor(Math.random() * _locations.length);
} while (next == current)
}
current = next;
marker = _locations[next];
setInfo(marker);
//infowindow.open(map, marker);
}
function initialize() {
var bounds = new google.maps.LatLngBounds();
var mapOptions = {
zoom: 7,
center: new google.maps.LatLng(42.4053848, 12.4276547),
scrollwheel: false,
mapTypeId: google.maps.MapTypeId.ROADMAP,
};
map = new google.maps.Map(document.getElementById('map'), mapOptions);
map.slide = true;
//setMarkers(map, _locations);
infowindow = new google.maps.InfoWindow({
content: "loading..."
});
google.maps.event.addListener(infowindow, 'closeclick', function () {
infowindow.close();
});
slider = window.setTimeout(showMap, 3000);
}
function setInfo(marker) {
var content =
'<div class="profile-widget" style="width: 100%; display: inline-block;">' +
'<div class="doc-img">' +
'<a href="' + marker.profile_link + '" tabindex="0" target="_blank">' +
'<img class="img-fluid" alt="' + marker.doc_name + '" src="' + marker.image + '">' +
'</a>' +
'</div>' +
'<div class="pro-content">' +
'<h4 class="text-center">' +
'' + marker.doc_name + '' +
'</h4>' +
'<ul class="available-info pt-5">' +
'<li><i class="fas fa-map-marker-alt"></i> ' + marker.address + ' </li>' +
'</ul>' +
'</div>' +
'</div>';
infowindow.setContent(content);
}
function setMarkers(map, markers) {
for (var i = 0; i < markers.length; i++) {
var item = markers[i];
var latlng = new google.maps.LatLng(item.lat, item.lng);
var marker = new google.maps.Marker({
position: latlng,
map: map,
doc_name: item.doc_name,
address: item.address,
speciality: item.speciality,
profile_link: item.profile_link,
animation: google.maps.Animation.DROP,
icon: icons[item.icons],
image: item.image
});
bounds.extend(marker.position);
markers[i] = marker;
google.maps.event.addListener(marker, "click", function () {
setInfo(this);
infowindow.open(map, this);
window.clearTimeout(slider);
});
}
map.fitBounds(bounds);
google.maps.event.addListener(map, 'zoom_changed', function () {
if (map.zoom > 16) map.slide = false;
});
// Add a marker clusterer to manage the markers.
new markerClusterer.MarkerClusterer({ markers, map });
}
google.maps.event.addDomListener(window, 'load', initialize);
$(document).ready(function () {
$.ajax({
url: "?handler=ElencoStrutture",
type: "POST",
beforeSend: function (xhr) {
xhr.setRequestHeader("XSRF-TOKEN",
$('input:hidden[name="__RequestVerificationToken"]').val());
},
data: elenco,
contentType: "application/json; charset=utf-8",
success: function (data) {
//console.error(data.ElencoStrutture);
_locations = data.ElencoStrutture;
setMarkers(map, _locations);
slider = window.setTimeout(showMap, 3000);
//alert("done ELENCO STRUTTURE");
}
});
});
Sometimes it works and sometimes it doesn't, I don't understand why it doesn't always work.
The problem is that it usually works the first time, so I don't understand where I'm wrong on the code side.
The map should display all pointers correctly and instead it sometimes shows me a blank map with this error.
I added part of code where I load setMarkers(map, _locations) for to have more informations.
thank you very much for answers.
I hope I have added useful information to my problem, I don't understand why it sometimes works and sometimes it doesn't.

Related

Changing and saving content inside info window after close

I have a map that geocodes locations retrieved from JSON and sticks a marker on the map.
The markers also have an infowindow that shows the markers name and rating.
There's a button inside an infowindow that increments a rating counter when you click a button.
The initial counter is retrieved from JSON.
Annoyingly, when the info window closed and reopen, the counter value resets.
I tried populating an object with all of the marker ratings, updating the object when the button is clicked and then output the rating from the object inside the contentString for the infowindow. This didn't work and the same initial rating counter was shown after re-opening the infowindow.
My code is below, any help would be appreciated.
var map;
var geocoder;
var infowindow;
var rating;
function initMap() {
var mapElement = document.getElementById("map_canvas");
geocoder = new google.maps.Geocoder();
var mapOptions = {
center: new google.maps.LatLng(53.481949, -2.237430),
zoom: 7,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
infowindow = new google.maps.InfoWindow();
map = new google.maps.Map(mapElement, mapOptions);
}
$(document).on('click', '#been-there', function(event){
var entryID = $(this).data('entry-id');
var rating = $(this).data('rating');
var dataString = 'id='+ entryID;
rating++;
$.ajax({
type: "POST",
url: "db-been-there.php",
data: dataString,
cache: false,
}).success(function(html){
console.log(html);
}).fail(function(html){
console.log(html);
});
$('#rating').html(rating);
});
$.getJSON("db-output.php", function(dbJSON) {
$.each(dbJSON, function(key, data) {
var url = "https://maps.googleapis.com/maps/api/geocode/json?latlng=" + data.lat + "," + data.lng + "&result_type=sublocality|political&key=AIzaSyCsY-LOPL7dGbA1ShBEu7zMO8_GaSBA3Vg";
$.getJSON(url, function(reverseGeo) {
var postal_town = reverseGeo.results[0].formatted_address;
geocoder.geocode( { 'address': postal_town}, function(results, status) {
if (status == 'OK') {
var marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location,
title: data.name
});
var contentString = '<div id="content">'+
'<h1>' + data.name + '</h1>' +
'<button id="been-there" data-rating="' + data.rating + '" data-entry-id="' + data.id + '">Seen it</button>' +
'<p><strong>Rating: </strong><span id="rating">' + data.rating + '</span></p>' +
'</div>';
marker.addListener('click', function() {
infowindow.setContent(contentString);
infowindow.open(map, marker);
});
} else {
alert('Geocode was not successful for the following reason: ' + status);
}
});
});
});
});
EDIT: Resolved code and JSFiddle below
Resolved JSFiddle: https://jsfiddle.net/BleepyEvans/3czqmqav/
var locations = [
{
"id": "1",
"name": "Location 1",
"lat": "53.408371",
"lng": "-2.991573",
"rating": "17"
},
{
"id": "2",
"name": "Location 2",
"lat": "53.789528",
"lng": "-2.969411",
"rating": "8"
},
]
var map;
var geocoder;
var infowindow;
var rating;
var markers = [];
function initMap() {
var mapElement = document.getElementById("map_canvas");
geocoder = new google.maps.Geocoder();
var mapOptions = {
center: new google.maps.LatLng(53.481949, -2.237430),
zoom: 7,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
infowindow = new google.maps.InfoWindow();
map = new google.maps.Map(mapElement, mapOptions);
}
$(document).on('click', '#been-there', function(event){
var entryID = $(this).data('entry-id');
var dataString = 'id='+ entryID;
rating = markers[entryID].rating;
rating++;
markers[entryID].rating = rating;
console.log(markers[entryID].rating);
$('#rating').html(rating);
});
$.each(locations, function(key, data) {
var url = "https://maps.googleapis.com/maps/api/geocode/json?latlng=" + data.lat + "," + data.lng + "&result_type=sublocality|political&key=AIzaSyCsY-LOPL7dGbA1ShBEu7zMO8_GaSBA3Vg";
$.getJSON(url, function(reverseGeo) {
var postal_town = reverseGeo.results[0].formatted_address;
geocoder.geocode( { 'address': postal_town}, function(results, status) {
if (status == 'OK') {
var marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location,
title: data.name,
rating: data.rating
});
markers[data.id] = marker;
console.log(markers[data.id].rating);
marker.addListener('click', function() {
var contentString = '<div id="content">'+
'<h1>' + data.name + '</h1>' +
'<button id="been-there" data-rating="' + data.rating + '" data-entry-id="' + data.id + '">Been There</button>' +
'<p><strong>Rating: </strong><span id="rating">' + markers[data.id].rating + '</span></p>' +
'</div>';
infowindow.setContent(contentString);
infowindow.open(map, marker);
});
} else {
alert('Geocode was not successful for the following reason: ' + status);
}
});
});
});
Rather than just create an HTML string which includes the rating data that you assign to your infowindow, I'd add the rating value to the Marker object itself.
var marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location,
title: data.manufacturer_name,
rating: data.rating
});
Save those markers in an object keyed on their ID:
markers[data.id] = marker;
Then when the user clicks the button, update that value:
$(document).on('click', '#been-there', function(event){
var entryID = $(this).data('entry-id');
rating = markers[entryID].rating;
rating++;
And update the value on the Marker:
markers[entryID].rating = rating;
If it doesn't work directly accessing the rating property on the markers, you might need to use:
markers[entryID].get('rating');
markers[entryID].set('rating', rating);

Get place_id of address_components

I am using Google place autocomplete. And I don't know how to get place_id of address_components. In JSON there are only long_name, short_name, types.
My code is here:
var object_location = document.getElementById('object_location'),
autoComplete = new google.maps.places.Autocomplete(object_location);
autoComplete.addListener('place_changed', function() {
var place = autoComplete.getPlace();
console.log('place = ', place);
});
Here is my JSON (picture)
I don't need place_id of my place. I need especially place_ids of address_components
If you reverse geocode the result, it will return results (which include a place_id) for each of the address components that contain that location.
autoComplete.addListener('place_changed', function() {
var place = autoComplete.getPlace();
map.setZoom(11);
var marker = new google.maps.Marker({
position: place.geometry.location,
map: map
});
infowindow.setContent(place.formatted_address);
infowindow.open(map, marker);
geocoder.geocode({
latLng: place.geometry.location
},
function(results, status) {
if (status === 'OK') {
console.log("revGeo result=" + JSON.stringify(results));
var htmlStr = "<table border='1'>";
for (var i = 0; i < results.length; i++) {
htmlStr += "<tr><td>" + results[i].formatted_address + "</td><td>" + results[i].place_id + "</td></tr>";
}
htmlStr += "</table>";
infowindow.setContent(infowindow.getContent() + "<br>" + htmlStr);
} else {
window.alert('Geocoder failed due to: ' + status);
}
});
});
proof of concept fiddle
code snippet:
var geocoder;
var map;
var infowindow;
function initialize() {
geocoder = new google.maps.Geocoder();
infowindow = new google.maps.InfoWindow();
var map = new google.maps.Map(
document.getElementById("map_canvas"), {
center: new google.maps.LatLng(37.4419, -122.1419),
zoom: 13,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var object_location = document.getElementById('object_location'),
autoComplete = new google.maps.places.Autocomplete(object_location);
autoComplete.addListener('place_changed', function() {
var place = autoComplete.getPlace();
map.setZoom(11);
var marker = new google.maps.Marker({
position: place.geometry.location,
map: map
});
infowindow.setContent(place.formatted_address);
infowindow.open(map, marker);
geocoder.geocode({
latLng: place.geometry.location
},
function(results, status) {
if (status === 'OK') {
var htmlStr = "<table border='1'>";
for (var i = 0; i < results.length; i++) {
htmlStr += "<tr><td>" + results[i].formatted_address + "</td><td>" + results[i].place_id + "</td></tr>";
}
htmlStr += "</table>";
infowindow.setContent(infowindow.getContent() + "<br>" + htmlStr);
} else {
window.alert('Geocoder failed due to: ' + status);
}
});
});
}
google.maps.event.addDomListener(window, "load", initialize);
html,
body,
#map_canvas {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js?libraries=geometry,places&key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
<input id="object_location" />
<div id="map_canvas"></div>

Content window on marker

I try this code for plotting data on google map and I plot it successfully currently there is 2 marker when i click on marker then content window is open but second marker content window is not open
this is the result on console
{"response":[["B9","5",27.13197”,”34.95 "],["L330","5",”27.06688”,”34.864"]}"
image
image
when i click on second marker then content window not open
Here is my code :
success: function (result) {
var d = JSON.parse(result.d).response;
console.log(JSON.parse(result.d).response);
console.log(JSON.stringify(result.d));
$("#tabledata").empty();
if (d.length > 0) {
$("#tabledata").append(
"<thead><tr><th>RegNo</th><th>Status</th><th>Longitude</th><th>Latitude</th></tr></thead>");
for (var i = 0; i < d.length - 1; i++) {
if (d[i] !== null) {
$("#tabledata").append("<tbody><tr><td>" +
d[i][0] + "</td> <td>" +
d[i][1] + "</td> <td>" +
d[i][2] + "</td> <td>" +
d[i][3] + "</td></tr></tbody>");
Status = d[i][2];
debugger;
RegNo = d[i][0];
latit = d[i][4];
longi = d[i][3];
}
}
}
else {
$("#tabledata").hide();
}
alert(d.length);
var map;
//var markers;
debugger;
var latlng = new google.maps.LatLng(24.0895898, 67.0998546);
debugger;
var myOptions = {
zoom: 8,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
debugger;
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
debugger;
debugger;
for (i = 0; i < d.length - 1; i++) {
var data = d[i]
var myLatlng = new google.maps.LatLng(d[i][4], d[i][3]);
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
title: 'Click me'
});
}
debugger;
for (i = 0; i < d.length - 1; i++){
var infowindow = new google.maps.InfoWindow({
content: 'RegNo:' + d[i][0] + '<br>Status:' + d[i][2] + '<br>Lat:' + d[i][4] + 'Long:' + d[i][3]
});
}
debugger;
google.maps.event.addListener(marker, 'click', function () {
infowindow.open(map, marker, data);
});
}
Your problem is this line here:
infowindow.open(marker, data, map);
The InfoWindow open function takes 1 or 2 arguments, and it should be like this:
infowindow.open(map, marker);

Javascript shows only last markers

The following code grabs some JSON data from /home.json URL which contain 5 microposts by 6 users. However, only the last 4 markers are shown (not even the 5th !!). I have spend 2 days to find the bug but unfortunately I can't really get why this dosen't work. If anyone could help me I would really appreciate it!
I have tested all lon/Lat variables through alert! All of them have the appropriate data. The map should be ok since the last 4 are shown !! Most probably the problem lies with my closure definition but I really cannot understand what I am doing wrong..
var GMAPS = window.GMAPS || {};
GMAPS.mainMap = function() {
var map;
var infowindow = new google.maps.InfoWindow();
var jsonObject = {};
function addMarkers() {
var xhr = new XMLHttpRequest();
xhr.open( "GET", "/home.json", true );
xhr.onreadystatechange = function () {
if ( xhr.readyState == 4 && xhr.status == 200 ) {
jsonObject = JSON.parse( xhr.responseText );
for (var i=0; i<jsonObject.length; i++) {
for (var j=0; j<jsonObject[i].microposts.length; j++) {
(function(Name, Title, Content, Latitude, Longitude) {
return function() {
//alert(Name + "\n" + Title + "\n" + Content + "\n" + Latitude + "\n" + Longitude + "\n"); //<-- this works!
var position = new google.maps.LatLng(Latitude, Longitude);
var contentString = "<h4>" + Name.bold() + "</h4>" + "<br />" + Title.bold()
+ "<br />" + Content;
var marker = new google.maps.Marker({
position: position,
title: Title,
map: map
});
google.maps.event.addListener(marker, 'click', (function(marker, contentString) {
return function() {
infowindow.setContent(contentString);
infowindow.open(map, marker);
}
})(marker, contentString));
};
})(jsonObject[i].name, jsonObject[i].microposts[j].title,
jsonObject[i].microposts[j].content,
jsonObject[i].microposts[j].lat,
jsonObject[i].microposts[j].lon)();
}
}
}
};
xhr.send(null);
}
function createMap() {
map = new google.maps.Map(document.getElementById('main_map'), {
zoom: 10,
panControl: true,
zoomControl: true,
zoomControlOptions: {
style: google.maps.ZoomControlStyle.SMALL
},
mapTypeControl: true,
scaleControl: true,
streetViewControl: true,
overviewMapControl: true,
scrollwheel: false,
center: new google.maps.LatLng(37.975327,23.728701),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
}
function initAddress() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(showPosition);
}
else {
var position = new google.maps.LatLng(0, 0);
map.setCenter(position);
}
}
function showPosition(position) {
var position = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
map.setCenter(position);
}
return {
initMap : function() {
createMap();
initAddress();
addMarkers();
}
};
}();
document.addEventListener("DOMContentLoaded", GMAPS.mainMap.initMap, false);
** Note: you have an unnecessary extra set of parens at the end of your IIFE.
Before your IIFE (inside the innermost for-loop), try adding:
var jObj = jsonObject[i], mPost = jObj.microposts[j];
Then in replace the arguments to the IIFE with:
(function(Name, Title, Content, Latitude, Longitude) {
return function() {
//alert(Name + "\n" + Title + "\n" + Content + "\n" + Latitude + "\n" + Longitude + "\n"); //<-- this works!
var position = new google.maps.LatLng(Latitude, Longitude);
var contentString = "<h4>" + Name.bold() + "</h4>" + "<br />" + Title.bold()
+ "<br />" + Content;
var marker = new google.maps.Marker({
position: position,
title: Title,
map: map
});
google.maps.event.addListener(marker, 'click', (function(marker, contentString) {
return function() {
infowindow.setContent(contentString);
infowindow.open(map, marker);
}
})(marker, contentString));
};
})(jObj.name, mPost.title, mPost.content, mPost.lat, mPost.lon);
The following code should work. I still don't understand why you have the extra set of parentheses.
xhr.onreadystatechange = function() {
var i = 0, j = 0;
if ( xhr.readyState == 4 && xhr.status == 200 ) {
jsonObject = JSON.parse( xhr.responseText );
for (var ilen = jsonObject.length; i < ilen;) {
for (var jObj = jsonObject[i++], jlen = jObj.microposts.length; j < jlen;) {
var mPost = jObj.microposts[j++];
(function(Name, Title, Content, Latitude, Longitude) {
return function() {
//alert(Name + "\n" + Title + "\n" + Content + "\n" + Latitude + "\n" + Longitude + "\n"); //<-- this works!
var position = new google.maps.LatLng(Latitude, Longitude);
var contentString = "<h4>" + Name.bold() + "</h4>" + "<br />" + Title.bold()
+ "<br />" + Content;
var marker = new google.maps.Marker({
position: position,
title: Title,
map: map
});
google.maps.event.addListener(marker, 'click', (function(marker, contentString) {
return function() {
infowindow.setContent(contentString);
infowindow.open(map, marker);
}
})(marker, contentString));
};
})(
jObj.name, mPost.title, mPost.content, mPost.lat, mPost.lon
);
}
}
}
};

Multiple Markers, Single Info Window, Anchored to the bottom of the map

I am having trouble rendering a google map infowindow anchored with multiple markers.
I am using MVC 3 and javascript to render the map, the map renders fine, as well as relative info windows. But I want the info window to be displayed at the bottom of the map, rather than relative to the marker. The starting point for each map could be different based on the country used for search. My javascript is below (which is working)> i just don't know how to change the infowindow:
function initializeMap() {
var countryID = $("#CountryID :selected").val();
var cityID = $("#cities :selected").val();
var regionID = $("#regions :selected").val();
var locationtypeID = $("#LocationTypeID :selected").val();
var filtertype = $("#filtertype").val();
var latlng;
$.ajax({
type: "GET",
url: "/ajaxcalls/getCentre",
data: "cid=" + countryID,
datatype: "json",
success: function (result) {
var gpscoords = (result).split(",");
latlng = new google.maps.LatLng(gpscoords[0], gpscoords[1]);
},
error: function (req, status, error) {
}
});
var myOptions = {
zoom: 7,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
$.ajax({
type: "GET",
url: "/ajaxcalls/getmarkers",
data: "cid=" + countryID + "&rid=" + regionID + "&xid=" + cityID + "&tid=" + locationtypeID + "&filterType=" + filtertype,
datatype: "json",
success: function (result) {
var infowindow = null;
infowindow = new google.maps.InfoWindow({
content: "holding..."
});
$.each(result, function (i, item) {
var gpscoords = (item.GPSCoOrds.toString()).split(",");
var mpos = new google.maps.LatLng(gpscoords[1], gpscoords[0]);
var markerobject = "";
if (item.LocationTypeID == 2) {
markerobject = "atm.png";
}
else {
markerobject = "bank.png";
}
marker = new google.maps.Marker({
map: map,
position: mpos,
draggable: false,
icon: "/content/mapicons/" + markerobject,
title: item.Designation.toString() + " " + item.Address.toString()
});
google.maps.event.addListener(marker, 'mouseover', function () {
var windowcontent = "<div>Site Name: ";
windowcontent = windowcontent + item.Designation + "</div>";
windowcontent = windowcontent + "<div>Address: " + item.Address + "</div>";
windowcontent = windowcontent + "<div>Contact Number: " + item.contactNumber + "</div>";
windowcontent = windowcontent + "<div>Branch Type: " + item.BranchType + "</div>";
windowcontent = windowcontent + "<div>Network Provider: " + item.NetworkProvider + "</div>";
windowcontent = windowcontent + "<div>Network Capacity: " + item.NetworkCapacity + "</div>";
infowindow.setContent(windowcontent);
infowindow.open(map, this);
});
});
},
error: function (req, stats, error) {
alert(error);
}
});
}
$(document).ready(function () {
$("#mapupdater").click(function () {
initializeMap();
});
});
Any help would be appreciated.
Don't anchor the infowindow to the marker with infowindow.open(map, this);
Just do infowindow.open(map);
However you'll still have to tell the infowindow where to appear. Either use the position attribute when creating it, or setPosition() after it's been created.

Categories