I am bringing in 100 maps to post on the same page, with some markers on each page, and average of 5 markers per map. However when loading the page it takes close to a minute before the google maps load. Here is the code that I have now, I am just not sure of how to get the maps to loader quicker.
window.onload = function () {
initialize();
}
var coords = [
{lat: 40.88589, lng: -73.892110, zoom: 10}
];
var maps = [];
var markers = [
MARKER DATA IN HERE
];
var counter=100;
function initialize() {
for(var i = 0, length = counter; i < length; i++)
{
var point = coords;
var latlng = new google.maps.LatLng(point.lat, point.lng);
maps[i] = new google.maps.Map(document.getElementById('map-canvas' + (i + 1)), {
zoom: point.zoom,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var infoWindow = new google.maps.InfoWindow();
for (var j = 0; j < markers.length; j++) {
var data = markers[j];
if(data.Rank==(i+1)){
var myLatlng = new google.maps.LatLng(data.lat, data.lng);
var marker = new google.maps.Marker({
position: myLatlng,
map: maps[i],
title: data.officer
});
//Attach click event to the marker.
(function (marker, data) {
google.maps.event.addListener(marker, "click", function (e) {
//Wrap the content inside an HTML DIV in order to set height and width of InfoWindow.
infoWindow.setContent("<div style = 'width:200px;min-height:40px'>" + data.officer + "</div>");
infoWindow.open(maps[i], marker);
});
})(marker, data);
}
}
}
}
If initializing ~100 JavaScript maps is too inefficient / slow, I would try starting with the Static Maps API [1] and loading static images which show the markers but aren't dynamic to give the appearance of your page loading quickly.
Asynchronously, perhaps when you detect the user is getting ready to interact with one of these maps, you could replace the static map with a dynamic JavaScript map.
You could even get more clever and only load the maps which are visible to the user. If you only see the top 20 maps at a time and the user has to scroll to see the rest, perhaps it only makes sense to load the first ~40 maps so there's content when the user scrolls but you don't waste your time loading 100 maps right off the bat.
[1] https://developers.google.com/maps/documentation/static-maps/intro
Related
I'm using the lastest version of google maps, and trying to print the markers in the map.
To do that, I'm using:
function initmap2() {
map2 = new google.maps.Map(document.getElementById('map-scan'), {
zoom: 16,
styles: style,
center: { lat: 13.7218501, lng: -89.2039192 }
});
for (i = 0; i < positions.length; i++) {
markers = new google.maps.Marker({
position: new google.maps.LatLng(positions[i]),
map: map2
});
}
var markers = positions.map(function (location, i) {
return new google.maps.Marker({
position: location,
});
});
for (var i = 0; i < markers.length; i++) {
markers[i].info = new google.maps.InfoWindow({
content: '<b>' + positions[i]["title"].toUpperCase() + '</b>'
});
markers[i].info.open(map2, markers[i]);
}
}
The markers are displayed in the right position, but the InfoWindws are very distanced of them.
Why I'm using map2 instead of map. I have preloaded another googlemap and the map2 is loaded in a dialog (on demand, when the dialog is open)
How to fix this behavior?
Your problem is this... you loop over positions, creating a marker for each of your positions:
for (i = 0; i < positions.length; i++) {
markers = new google.maps.Marker({
position: new google.maps.LatLng(positions[i]),
map: map2
});
}
You then do the same thing again:
var markers = positions.map(function (location, i) {
return new google.maps.Marker({
position: location,
});
});
And at the end of this 2nd way of doing it, markers is an array of markers. Which you then loop over to setup the infowindows.
However, the first time you created the marker, you specified the map attribute. So those markers show up on the map.
The second time you didn't bother, so these markers aren't on the map.
You've got markers visible thanks to your first way of doing it. But then you're attaching the infowindows to the non-visible markers created the second way! :-/
The code's a bit of a mess, you can do it all in just the one loop over positions, and make sure you specify the map property for each marker. I'd just do:
var markers = [];
for (i = 0; i < positions.length; i++) {
markers.push(new google.maps.Marker({
position: new google.maps.LatLng(positions[i]),
map: map2
}));
markers[i].info = new google.maps.InfoWindow({
content: '<b>' + positions[i]["title"].toUpperCase() + '</b>'
});
markers[i].info.open(map2, markers[i]);
}
I'm designing a little webapp that includes Google Maps API in Full Screen. The webapp is intended to be used successfuly in mobile devices (even small devices). Actually I fetch some coordinates from my Database using AJAX and place them in the map.
I push the coordinates in an array locations using AJAX and then I do the following:
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 11,
center: new google.maps.LatLng(37.262577, -115.8314989),
mapTypeId: google.maps.MapTypeId.ROADMAP,
mapTypeControlOptions: {
style: google.maps.MapTypeControlStyle.HORIZONTAL_BAR,
position: google.maps.ControlPosition.BOTTOM_LEFT
}
});
var infowindow = new google.maps.InfoWindow();
var marker, i;
for (i = 0; i < locations.length; i++) {
marker = new google.maps.Marker({
//locations[i][1] is lang
//locations[i][2] is lng
position: new google.maps.LatLng(locations[i][1], locations[i][2]),
map: map
});
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infowindow.setContent(locations[i][0]);
infowindow.open(map, marker);
}
})(marker, i));
}
How can I convert this script in responsive? I want to see all my Markers on the screen, mobile screens <= 768px (width), I can't find any generic handler to smartly resize (zoom in/out) the map in order to view all markers in the screen.
Thanks for reading!
Your best bet is making a LatLngBounds object and extending it with every couple of coordinates you want to show. Then, just call fitBounds() on your map object, with your bounds as argument, like follows :
var marker, i;
var bounds = new google.maps.LatLngBounds()
for (i = 0; i < locations.length; i++) {
var coords = new google.maps.LatLng(parseFloat(locations[i][1]), parseFloat(locations[i][2]))
marker = new google.maps.Marker({
//locations[i][1] is lang
//locations[i][2] is lng
position: coords,
map: map
});
bounds.extend(coords);
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infowindow.setContent(locations[i][0]);
infowindow.open(map, marker);
}
})(marker, i));
}
map.fitBounds(bounds);
If you want to apply only if needed, then you have to compare the variable bounds you created with map.getBounds(), by comparing their extremities : getNorthEast() and getSouthWest() coordinates.
All of my markers are coming from an AJAX call and are accurately placed on the map. However, the initial view is fully zoomed out, along the equator, in North America.
I know the solution lays somewhere with bounds.extend and map.fitBounds but apparently I'm doing it wrong.
I've always had an issue with this, so hopefully someone can help elevate this thorn in my side:
var map;
var markers = [];
var home_marker;
function initialize() {
// Display a map on the page
if ( document.contains(document.getElementById("map_canvas")) ) {
bounds = new google.maps.LatLngBounds();
map = new google.maps.Map(document.getElementById("map_canvas"), {
zoom: 12,
center: new google.maps.LatLng(48.4222, -123.3657)
});
// a new Info Window is created
infoWindow = new google.maps.InfoWindow();
// Event that closes the InfoWindow with a click on the map
google.maps.event.addListener(map, 'click', function() {
infoWindow.close();
});
// Add Home Marker
home_marker = new google.maps.Marker({
position: new google.maps.LatLng(user_address_lat, user_address_lng),
map: map,
icon: '/images/map-icon-your-home.png'
});
}
}
function displayMarkers( properties ) {
// this variable sets the map bounds and zoom level according to markers position
var bounds = new google.maps.LatLngBounds();
// For loop that runs through the info on markersData making it possible to createMarker function to create the markers
for (var i = 0; i < properties.length; i++){
var latlng = new google.maps.LatLng(properties[i]['latitude'], properties[i]['longitude']);
var price_current = properties[i]['price_current'];
var bedrooms = properties[i]['bedrooms'];
var total_baths = properties[i]['total_baths'];
var listing_id = properties[i]['listing_id'];
createMarker( latlng, price_current, bedrooms, total_baths, matrix_unique_ID );
// Marker’s Lat. and Lng. values are added to bounds variable
bounds.extend(latlng);
}
// Finally the bounds variable is used to set the map bounds
// with API’s fitBounds() function
map.fitBounds(bounds);
}
function createMarker( latlng, price, bedrooms, bathrooms, matrix_id ) {
var formatted_price = accounting.formatMoney(price, '$', 0);
var marker = new google.maps.Marker({
map: map,
position: latlng,
icon: '/images/map-icon.png'
});
google.maps.event.addListener(marker, 'click', function() {
// Variable to define the HTML content to be inserted in the infowindow
var iwContent = '<div class="row"><div class="small-12 columns"><img src="http://www.mywebsite.com/properties/'+listing_id+'/image-'+matrix_id+'-1.jpg"></div></div>' +
'<div class="row"><div class="small-12 columns"><p class="price-current text-center">'+formatted_price+'</p></div></div><hr>' +
'<div class="row"><div class="small-6 columns"><p class="bedrooms"><span class="fw-semi-bold">Beds:</span> '+bedrooms+'</p></div>' +
'<div class="small-6 columns"><p class="total-baths"><span class="fw-semi-bold">Baths:</span> '+bathrooms+'</p></div></div>';
// including content to the infowindow
infoWindow.setContent(iwContent);
// opening the infowindow in the current map and at the current marker location
infoWindow.open(map, 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);
}
}
// Removes the markers from the map, but keeps them in the array.
function clearMarkers() {
setMapOnAll(null);
}
// Deletes all markers in the array by removing references to them.
function deleteMarkers() {
clearMarkers();
markers = [];
}
Make a new Part to your script or make a new one, and code it specificly to change zoom in camera ammount and, add ui button for it.
I am building a Google Maps based web app on which I plot a moving dot of the user location. I am fetching continuously the user location from a server and would like to use the current user location when loading the map to center the window around it, meaning, when the user loads the site, the map will be centered around the first lat/long fetched from the server but enable the user to pan the map afterwards without re-centering it around where the user is. I was able to keep the map centered constantly around the user location but can't figure out how to use the first fetched location to center the map during initialization. My code is below, any help would be greatly appreciated. Thanks!
<script>
var locations = [
['location a', 37.771678, -122.469357],
['location b', 37.768557, -122.438458],
['location c', 37.755121, -122.438973],
['location d', 37.786127, -122.433223]
];
var map;
var i;
var marker;
var google_lat = 37.722066;
var google_long = -122.478541;
var myLatlng = new google.maps.LatLng(google_lat, google_long);
var image_dot = new google.maps.MarkerImage(
'images/red_dot.png',
null, // size
null, // origin
new google.maps.Point( 8, 8 ), // anchor (move to center of marker)
new google.maps.Size( 8, 8 ) // scaled size (required for Retina display icon)
);
function initialize() {
var mapOptions = {
zoom: 12,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
setMarkers(map, locations);
} //initialize();
function setMarkers(map, locations) {
for (var i = 0; i < locations.length; i++) {
var beach = locations[i];
var myLatLng1 = new google.maps.LatLng(beach[1], beach[2]);
marker = new google.maps.Marker({
position: myLatLng1,
icon: image_dot,
map: map
});
}
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
<script type="text/javascript">
var Tdata;
var image = new google.maps.MarkerImage(
'images/bluedot_retina.png',
null, // size
null, // origin
new google.maps.Point( 8, 8 ), // anchor (move to center of marker)
new google.maps.Size( 17, 17 ) // scaled size (required for Retina display icon)
);
var userMarker = new google.maps.Marker({icon: image});
$.ajax({
method : "GET",
url: "get_location.php",
success : function(data){
Tdata=JSON.parse(data);
myFunction();
}
});
function myFunction(){
var interval = setInterval(function() {
$.get("get_location.php", function(Tdata) {
var JsonObject= JSON.parse(Tdata);
google_lat = JsonObject.lat;
google_long = JsonObject.long;
myLatlng = new google.maps.LatLng(google_lat, google_long);
userMarker.setPosition(myLatlng);
userMarker.setMap(map);
//map.setCenter(myLatlng); --> this is not what I want since it will always keep the map centerd around the user
});
}, 1000);
}
</script>
Only set the map center the first time. One way of detecting the first time would be to create the "userMarker" the first time the data is loaded.
var userMarker;
$.ajax({
method : "GET",
url: "get_location.php",
success : function(data){
Tdata=JSON.parse(data);
myFunction();
}
});
function myFunction(){
var interval = setInterval(function() {
$.get("get_location.php", function(Tdata) {
var JsonObject= JSON.parse(Tdata);
google_lat = JsonObject.lat;
google_long = JsonObject.long;
myLatlng = new google.maps.LatLng(google_lat, google_long);
if (!userMarker || !userMarker.setPosition) {
// create the marker
userMarker = new google.maps.Marker({
icon: image,
position: myLatlng,
map:map
});
// center the map the first time, when the marker is created
map.setCenter(myLatlng);
} else { // marker aleady exists
userMarker.setPosition(myLatlng);
}
});
}, 1000);
}
proof of concept fiddle
I have a map that has checkboxes for users to select what they would like displayed on the map. Everything works well with the exception of the following two items.
When a user selects an item from the list the marker does display on the map, however the map does not re-center on the marker. This is needed for a marker that is outside the viewable area of the map when the page loads.
When I have multiple markers open on the map I would like to have only 1 infowindow open at a time, currently if I click on 10 markers there will be 10 infowindows open. I would like to have it where if an infowindow is open and another marker is clicked then the first infowindow closes.
I have pasted a snippet of the code for one of the markers below, any help would be greatly appreciated!
jQuery(document).ready(function(){
/**
* The Map object.
* #type {google.maps.Map}
*/
var mapOptions = {
center: new google.maps.LatLng(36.812946,-119.746953),
zoom: 16,
mapTypeId: google.maps.MapTypeId.SATELLITE
};
var map = new google.maps.Map(document.getElementById("map"), mapOptions);
/**
* The markers array.
* #type {Object}
*/
var markers = {};
markers.building37 = [];
var marker0237 = new google.maps.Marker({
visible: false,
icon: new google.maps.MarkerImage("images/website/brown_Marker.png",new google.maps.Size(32,37),null,null),
title: 'Building',
position: new google.maps.LatLng(36.80694607313768,-119.73590791225433),
center: position,
map: map
});
markers.building37.push(marker0237);
var info_window0237 = new google.maps.InfoWindow({
content: '<div id="infobubble"><div id="img"><img src="images/buildings/Foundation001.jpg" alt="Foundation Building"></div><div id="desc"><h3>Foundation</h3></div></div>',
maxWidth:350,
});
google.maps.event.addListener(marker0237, "click", function() {
info_window0237.open(map,marker0237);
});
var showBuilding37 = false;
var mgrBuilding37 = null;
/**
* Toggles Building 37 Marker Group visibility.
*/
function toggleBuilding37()
{
showBuilding37 = !showBuilding37;
if (showBuilding37)
for (var i=0; i < markers.building37.length; i++)
markers.building37[i].setVisible(true);
if (mgrBuilding37)
{
if (showBuilding37)
{
mgrBuilding37.addMarkers(markers.building37, 0);
mgrBuilding37.refresh();
}
else
{
mgrBuilding37.clearMarkers();
mgrBuilding37.refresh();
}
}
else
{
mgrBuilding37 = new MarkerManager(map, {trackMarkers: true, maxZoom: 15});
google.maps.event.addListener(mgrBuilding37, "loaded", function() {
if (showBuilding37)
{
mgrBuilding37.addMarkers(markers.building37, 0);
mgrBuilding37.refresh();
}
else
{
mgrBuilding37.clearMarkers();
mgrBuilding37.refresh();
}
});
}
}
google.maps.event.addDomListener(
document.getElementById("building37-cb"),"click", toggleBuilding37);
});
I don't see where you are setting the map center.
You should do something like map.setCenter(location); when you add a marker.
You should keep a list of info windows and when you display one, loop through the others and hide their info windows.
//Declare your info window array
var infoWindows = new Array();
var info_window0237 = new google.maps.InfoWindow({
content: '<div id="infobubble"><div id="img"><img src="images/buildings/Foundation001.jpg" alt="Foundation Building"></div><div id="desc"><h3>Foundation</h3></div></div>',
maxWidth:350,
});
//After you make an infowindow, add it to the array
infoWindows.push(info_window0237);
google.maps.event.addListener(marker0237, "click", function() {
//When you show an infowindow on click, hide the rest
for(i = 0; i < indowWindows.length; i++)
{
//this will close all the infowindows you added to the array
infoWindows[i].close();
}
info_window0237.open(map,marker0237);
});