i am trying to add clustering on my map, the code i am using is working fine but there is no clustring on it and can't figure out how should i add the cluster to this code.
(function (namespace, $, undefined) {
// map the namespace to that
var that = namespace;
var markers = [];
var dealers = [];
var googleMap;
var tmpDealer = "";
function AddMarkers(aar, map, show) {
if (aar.length > 0) {
var image = '/Files/Templates/Designs/Mobler/images/MapMarker.png';
for (var i = 0; i < aar.length; i++) {
markers.push( new google.maps.Marker({
position: new google.maps.LatLng(parseFloat( aar[i].Latitude),parseFloat(aar[i].Longitude)),
map: map,
title: aar[i].Name,
icon: image,
DealerId: aar[i].DealerId,
DealerPage: aar[i].Area
}));
}
for (var i = 0; i < markers.length; i++) {
if (show) {
google.maps.event.addListener(markers[i], "click", function () {
tmpDealer = this.DealerPage;
MoblerLandingPage.SetCookie("/Default.aspx" + tmpDealer, false);
MoblerLandingPage.SetAreaName("/Default.aspx?AreaID=" + this.DealerPage, function() {
setTimeout(function() {
var area = $.cookie("MoblerAreaName");
document.location = "http://" + document.domain + "/" + area;
}, 250);
});
});
} else {
google.maps.event.addListener(markers[i], "click", that.onMarkerClick)
}
}
}
}
var InfoBoxOptions2 = {
content: ""
, disableAutoPan: false
, maxWidth: 0
, pixelOffset: new google.maps.Size(-75, -5)
, zIndex: null
, boxClass: "DealerMapInfoBox"
, closeBoxMargin: "5px"
, closeBoxURL: "/Files/Templates/Designs/SmagOgBehag/images/infoBoxClose.png"
, infoBoxClearance: new google.maps.Size(1, 1)
, isHidden: false
, pane: "floatPane"
, enableEventPropagation: false
, alignBottom : true
};
var infoBox2 = new InfoBox(InfoBoxOptions2);
that.Initialize = function(mapId, dealerArray, show){
dealers = dealerArray;
var mapOptions = {
center: new google.maps.LatLng(56.22, 11.32),
zoom: 7,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
if(!show){
var mapOptions = {
center: new google.maps.LatLng(56.22, 11.32),
zoom: 5,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
}
googleMap = new google.maps.Map(document.getElementById(mapId), mapOptions);
if(dealerArray.constructor === Array && dealerArray.length > 0){
AddMarkers(dealers, googleMap, show);
}
if(!show){
google.maps.event.addListener(googleMap, 'click', function () {
infoBox2.close();
});
}
}
that.onMarkerClick = function(){
var marker = this;
infoBox2.content_ = $('#Dealer' + marker.DealerId + ' li a').html();
infoBox2.open(marker.map, marker);
}
that.ShowDealerOnMap = function(dealerId) {
for (var i = 0; i < markers.length; i++) {
if (markers[i].DealerId == dealerId) {
var marker = markers[i];
marker.map.setZoom(15);
marker.map.panTo(marker.getPosition())
infoBox2.content_ = $('#Dealer' + marker.DealerId).html()
infoBox2.open(marker.map, marker);
}
}
}
Did you take a look to this documentation ? You can see a working sample to use MarkerClusterer
//Create your map
var center = new google.maps.LatLng(37.4419, -122.1419);
var options = {
'zoom': 13,
'center': center,
'mapTypeId': google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map"), options);
//Create the clusterer and its options
var mcOptions = {gridSize: 50, maxZoom: 15};
var markers = [...]; // Create the markers you want to add and collect them into a array.
//Add the clusterer to the map, and the markers to the clusterer.
var mc = new MarkerClusterer(map, markers, mcOptions);
Please note that if you don't have a lot of markers, you'll have to change some options in order to see the clusterer working. Change the maxZoom where the clusterer works, and the size of the grid ( gridSize option).
For a complete list of all options, please refer to this document
See this:
http://www.appelsiini.net/2008/introduction-to-marker-clustering-with-google-maps
You can make clusters, rectangle based or square based.
Related
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?key=AIzaSyD83DW4cuDAMp0Zf2GkEXGFqnBAewN5qko"></script>
<script src="https://code.jquery.com/jquery-2.2.4.min.js" integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44=" crossorigin="anonymous"></script>
</head>
<body>
<div id="map" style="width: 100%; height: 400px;"></div>
<script type="text/javascript">
function init(locations){
var element = document.getElementById("map");
var mapTypeIds = [];
for(var type in google.maps.MapTypeId) {
mapTypeIds.push(google.maps.MapTypeId[type]);
}
mapTypeIds.push("OSM");
var map = new google.maps.Map(element, {
center: new google.maps.LatLng(parseInt(locations[0].lat), parseInt(locations[0].lng)),
zoom: 6,
mapTypeId: "OSM",
mapTypeControlOptions: {
mapTypeIds: mapTypeIds
}
});
var infoWindow = new google.maps.InfoWindow(), marker, i;
for (i = 0; i < locations.length; i++) {
marker = new google.maps.Marker({
position: new google.maps.LatLng(locations[i].lat, locations[i].lng),
map: map,
draggable:true,
// title: locations[i].lat
// icon: image
});
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infoWindow.setContent(locations[i].infowindow);
infoWindow.open(map, marker);
}
})(marker, i));
var mapTypeIds = [];
for(var type in google.maps.MapTypeId) {
mapTypeIds.push(google.maps.MapTypeId[type]);
}
mapTypeIds.push("OSM");
map.mapTypes.set("OSM", new google.maps.ImageMapType({
getTileUrl: function(coord, zoom) {
return "http://tile.openstreetmap.org/" + zoom + "/" + coord.x + "/" + coord.y + ".png";
},
tileSize: new google.maps.Size(256, 256),
name: "OpenStreetMap",
maxZoom: 18
}));
}
}
// long 77.4028193 lat 23.2243851
var locations = [{"lat":"21.2243851","lng":"77.4028193","infowindow":" information1 "},{"lat":"17.433282","lng":"78.426762","infowindow":" information2 "}];
var locations1 = [{"lat":"24.2243851","lng":"77.4028193","infowindow":" information1 "},{"lat":"17.434282","lng":"78.426762","infowindow":" information2 "}];
window.onload = init(locations);
window.setInterval( function(){console.log("first fn");change(locations1);}, 3500);
window.setInterval( function(){console.log("second fn");change(locations);}, 1500);
function change(locations){
console.log(locations);
var mapTypeIds = [];
for(var type in google.maps.MapTypeId) {
mapTypeIds.push(google.maps.MapTypeId[type]);
}
mapTypeIds.push("OSM");
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 6,
center: {lat: parseInt(locations[0].lat), lng: parseInt(locations[0].lng)},
mapTypeId: "OSM",
mapTypeControlOptions: {
mapTypeIds: mapTypeIds
}
});
// var map = google.maps.Map(document.getElementById("map"));
var infoWindow = new google.maps.InfoWindow(), marker, i;
for (i = 0; i < locations.length; i++) {
var marker = new google.maps.Marker({
position: new google.maps.LatLng(locations[i].lat, locations[i].lng),
});
marker.setMap(map);
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infoWindow.setContent(locations[i].infowindow);
infoWindow.open(map, marker);
}
})(marker, i));
var mapTypeIds = [];
for(var type in google.maps.MapTypeId) {
mapTypeIds.push(google.maps.MapTypeId[type]);
}
mapTypeIds.push("OSM");
map.mapTypes.set("OSM", new google.maps.ImageMapType({
getTileUrl: function(coord, zoom) {
return "http://tile.openstreetmap.org/" + zoom + "/" + coord.x + "/" + coord.y + ".png";
},
tileSize: new google.maps.Size(256, 256),
name: "OpenStreetMap",
maxZoom: 18
}));
}
}
</script>
</body>
</html>
without reloading/refreshing googlemap markers to be replaced. Tried all the ways provided by google-map api and other blogs. nothing helping me, atlast posting here hoping someone helps me with this part.
I have copied complete code here so that it helps to get on to the issue on which I am trying to solve.
Here I do.Is this right. I modified some of your code to make sure if this what you wish. I think you just miss some detail. If this is what you want, please let me know. PS :A lot of forloop in the function change-->not a good example.XD
<script type="text/javascript">
var map;
var markersArray=[];//put all markers into this
function init(locations){
var element = document.getElementById("map");
var mapTypeIds = [];
for(var type in google.maps.MapTypeId) {
mapTypeIds.push(google.maps.MapTypeId[type]);
}
mapTypeIds.push("OSM");
map = new google.maps.Map(element, {
center: new google.maps.LatLng(parseInt(locations[0].lat), parseInt(locations[0].lng)),
zoom: 6,
mapTypeId: "OSM",
mapTypeControlOptions: {
mapTypeIds: mapTypeIds
}
});
var infoWindow = new google.maps.InfoWindow(), marker, i;
for (i = 0; i < locations.length; i++) {
var mapTypeIds = [];
for(var type in google.maps.MapTypeId) {
mapTypeIds.push(google.maps.MapTypeId[type]);
}
mapTypeIds.push("OSM");
map.mapTypes.set("OSM", new google.maps.ImageMapType({
getTileUrl: function(coord, zoom) {
return "http://tile.openstreetmap.org/" + zoom + "/" + coord.x + "/" + coord.y + ".png";
},
tileSize: new google.maps.Size(256, 256),
name: "OpenStreetMap",
maxZoom: 18
}));
}
}
var locations = [{"lat":"21.2243851","lng":"77.4028193","infowindow":" information1 "},{"lat":"20.433282","lng":"78.426762","infowindow":" information2 "}];
var locations1 = [{"lat":"24.2243851","lng":"77.4028193","infowindow":" information1 "},{"lat":"22.434282","lng":"78.426762","infowindow":" information2 "}];
var counter=0;
window.onload = init(locations);
window.setInterval( function(){
if(counter%2==0)
{
change(locations1);
}
else
{
change(locations);
}
counter++;
}, 2000);
function change(locations){
for (i = 0; i < locations.length; i++)
{
if(markersArray[i]!=null)
{
markersArray[i].setMap(null);
if (i == locations.length - 1) {
markersArray = [];
}
}
}
for (i = 0; i < locations.length; i++)
{
var marker = new google.maps.Marker({
position: new google.maps.LatLng(locations[i].lat, locations[i].lng) });
markersArray.push(marker);
}
for (i = 0; i < markersArray.length; i++)
{
markersArray[i].setMap(map);
}
}
</script>
We had a similar problem to what you are experiencing. The way we solved it was by recalculating the bounds and recentering the map each time a new location is added. So basically we have a createMarker function that has this bit of code at the end:
const map_center = bounds.getCenter();
resultsMap.setCenter(map_center);
resultsMap.panToBounds(bounds);
resultsMap.fitBounds(bounds);
Where bounds here is your map boundaries, which can be found with the google.maps.LatLngBounds() method.
EDIT: I see you want to do it without refreshing the map, I don't think resetting the bounds refreshes the map but I could be wrong about that.
I'm doing an application with google maps API that have a JSON with the marker's coordinates. Then I draw polylines between the markers. I also implemented a function with a onclick event that creates a new marker inside the polyline. This marker has to show information of the previous marker in the polyline (the one taked of the JSON, not a clicked one). But I don't know how to take the previous vertex(marker) of a selected polyline.
Code:
(function() {
window.onload = function() {
var options = {
zoom: 3,
center: new google.maps.LatLng(37.09, -95.71),
mapTypeId: google.maps.MapTypeId.HYBRID,
noClear: true,
panControl: true,
scaleControl: false,
streetViewControl:false,
overviewMapControl:false,
rotateControl:false,
mapTypeControl: true,
zoomControl: false,
};
var map = new google.maps.Map(document.getElementById('map'), options);
// JSON
$.getJSON("loc.js", function(json) {
console.log(json);
});
//Marker type
var markers = [];
var arr = [];
var pinColor = "FE7569";
var pinImage = new google.maps.MarkerImage("http://labs.google.com/ridefinder/images/mm_20_red.png" + pinColor,
new google.maps.Size(21, 34),
new google.maps.Point(0,0),
new google.maps.Point(10, 34));
// JSON loop
for (var i = 0, length = json.length; i < length; i++) {
var data = json[i],
latLng = new google.maps.LatLng(data.lat, data.lng);
arr.push(latLng);
// Create markers
var marker = new google.maps.Marker({
position: latLng,
map: map,
icon: pinImage,
});
infoBox(map, marker, data);
//Polylines
var flightPath = new google.maps.Polyline({
path: json,
geodesic: true,
strokeColor: '#FF0000',
strokeOpacity: 1.0,
strokeWeight: 2,
map:map
});
infoPoly(map, flightPath, data);
//Calculate polylines distance
google.maps.LatLng.prototype.kmTo = function(a){
var e = Math, ra = e.PI/180;
var b = this.lat() * ra, c = a.lat() * ra, d = b - c;
var g = this.lng() * ra - a.lng() * ra;
var f = 2 * e.asin(e.sqrt(e.pow(e.sin(d/2), 2) + e.cos(b) * e.cos
(c) * e.pow(e.sin(g/2), 2)));
return f * 6378.137;
}
google.maps.Polyline.prototype.inKm = function(n){
var a = this.getPath(n), len = a.getLength(), dist = 0;
for (var i=0; i < len-1; i++) {
dist += a.getAt(i).kmTo(a.getAt(i+1));
}
return dist;
}
}
function infoBox(map, marker, data) {
var infoWindow = new google.maps.InfoWindow();
google.maps.event.addListener(marker, "click", function(e) {
salta(data.tm);
});
(function(marker, data) {
google.maps.event.addListener(marker, "click", function(e) {
salta(data.tm);
});
})(marker, data);
}
//Create onclick marker on the polyline
function infoPoly(map, flightPath, data){
google.maps.event.addListener(flightPath, 'click', function(event) {
mk = new google.maps.Marker({
map: map,
position: event.latLng,
});
markers.push(mk);
map.setZoom(17);
map.setCenter(mk.getPosition());
});
}
function drawPath() {
var coords = [];
for (var i = 0; i < markers.length; i++) {
coords.push(markers[i].getPosition());
}
flightPath.setPath(coords);
}
// Fit these bounds to the map
var bounds = new google.maps.LatLngBounds();
for (var i = 0; i < arr.length; i++) {
bounds.extend(arr[i]);
}
map.fitBounds(bounds);
//dist polylines
distpoly = flightPath.inKm();
distpolyround = Math.round(distpoly);
};
})();
If I click in the blue arrow, I create a marker on that point of the polyline. I that marker it takes the values of the previous one.
You can use the geometry library .poly namespace isLocationOnEdge method to determine which segment of the polyline the clicked point (new marker) is on.
//Create onclick marker on the polyline
function infoPoly(map, flightPath, data) {
google.maps.event.addListener(flightPath, 'click', function(event) {
mk = new google.maps.Marker({
map: map,
position: event.latLng,
});
markers.push(mk);
map.setZoom(17);
map.setCenter(mk.getPosition());
// find line segment. Iterate through the polyline checking each line segment.
// isLocationOnEdge takes a google.maps.Polyline as the second argument, so make one,
// then use it for the test. The default value of 10e-9 for the tolerance didn't work,
// a tolerance of 10e-6 seems to work.
var betweenStr = "result no found";
var betweenStr = "result no found";
for (var i=0; i<flightPath.getPath().getLength()-1; i++) {
var tempPoly = new google.maps.Polyline({
path: [flightPath.getPath().getAt(i), flightPath.getPath().getAt(i+1)]
})
if (google.maps.geometry.poly.isLocationOnEdge(mk.getPosition(), tempPoly, 10e-6)) {
betweenStr = "between "+i+ " and "+(i+1);
}
}
(function(mk, betweenStr) {
google.maps.event.addListener(mk, "click", function(e) {
infowindow.setContent(betweenStr+"<br>loc:" + this.getPosition().toUrlValue(6));
infowindow.open(map, mk);
// salta(data.tm);
});
})(mk, betweenStr);
google.maps.event.trigger(mk,'click');
});
proof of concept fiddle
code snippet:
var infowindow = new google.maps.InfoWindow();
(function() {
window.onload = function() {
var options = {
zoom: 3,
center: new google.maps.LatLng(37.09, -95.71),
mapTypeId: google.maps.MapTypeId.HYBRID,
};
var map = new google.maps.Map(document.getElementById('map'), options);
//Marker type
var markers = [];
var arr = [];
var pinColor = "FE7569";
var pinImage = "http://labs.google.com/ridefinder/images/mm_20_red.png";
// JSON loop
for (var i = 0, length = json.length; i < length; i++) {
var data = json[i],
latLng = new google.maps.LatLng(data.lat, data.lng);
arr.push(latLng);
// Create markers
var marker = new google.maps.Marker({
position: latLng,
map: map,
icon: pinImage,
});
infoBox(map, marker, data);
//Polylines
var flightPath = new google.maps.Polyline({
path: json,
geodesic: true,
strokeColor: '#FF0000',
strokeOpacity: 1.0,
strokeWeight: 2,
map: map
});
infoPoly(map, flightPath, data);
}
function infoBox(map, marker, data) {
var infoWindow = new google.maps.InfoWindow();
google.maps.event.addListener(marker, "click", function(e) {
infowindow.setContent("tm:" + data.tm + "<br>loc:" + this.getPosition().toUrlValue(6));
infowindow.open(map, marker);
// salta(data.tm);
});
(function(marker, data) {
google.maps.event.addListener(marker, "click", function(e) {
infowindow.setContent("tm:" + data.tm + "<br>loc:" + this.getPosition().toUrlValue(6));
infowindow.open(map, marker);
// salta(data.tm);
});
})(marker, data);
}
//Create onclick marker on the polyline
function infoPoly(map, flightPath, data) {
google.maps.event.addListener(flightPath, 'click', function(event) {
mk = new google.maps.Marker({
map: map,
position: event.latLng,
});
markers.push(mk);
map.setZoom(17);
map.setCenter(mk.getPosition());
// find line segment. Iterate through the polyline checking each line segment.
// isLocationOnEdge takes a google.maps.Polyline as the second argument, so make one,
// then use it for the test. The default value of 10e-9 for the tolerance didn't work,
// a tolerance of 10e-6 seems to work.
var betweenStr = "result no found";
for (var i = 0; i < flightPath.getPath().getLength() - 1; i++) {
var tempPoly = new google.maps.Polyline({
path: [flightPath.getPath().getAt(i), flightPath.getPath().getAt(i + 1)]
})
if (google.maps.geometry.poly.isLocationOnEdge(mk.getPosition(), tempPoly, 10e-6)) {
betweenStr = "between " + i + " and " + (i + 1);
}
}
(function(mk, betweenStr) {
google.maps.event.addListener(mk, "click", function(e) {
infowindow.setContent(betweenStr + "<br>loc:" + this.getPosition().toUrlValue(6));
infowindow.open(map, mk);
// salta(data.tm);
});
})(mk, betweenStr);
google.maps.event.trigger(mk, 'click');
});
}
function drawPath() {
var coords = [];
for (var i = 0; i < markers.length; i++) {
coords.push(markers[i].getPosition());
}
flightPath.setPath(coords);
}
// Fit these bounds to the map
var bounds = new google.maps.LatLngBounds();
for (var i = 0; i < arr.length; i++) {
bounds.extend(arr[i]);
}
map.fitBounds(bounds);
//dist polylines
distpoly = flightPath.inKm();
distpolyround = Math.round(distpoly);
};
})();
var json = [{
lat: 38.931808,
lng: -74.906606,
tm: 0
}, {
lat: 38.932442,
lng: -74.905147,
tm: 1
}, {
lat: 38.93311,
lng: -74.903473,
tm: 2
}, {
lat: 38.933777,
lng: -74.901671,
tm: 3
}, {
lat: 38.930739,
lng: -74.912528,
tm: 1000
}];
html,
body,
#map {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js?libraries=geometry"></script>
<div id="map"></div>
INITIALIZING
When you are creating those markers in the for loop, add them to a map [Data structure] that you define (empty) before the loop. In the map markers will be stored. Their keys - concatenated lat/lng.
var initial_markers = {}; //before for loop
initial_markers[data.lat+"-"+data.lng] = marker; //after each marker initialization
Count them, so you know how many there are initial_marker_count, because you cannot get length of size of a map[data structure]
DETECTION
When you have clicked on a polyline, I don't think you can get exactly the part of polyline that is clicked, so you need to get it yourself. The steps are:
Get the coordinate of click event
Loop through the markers
Take their coordinates
Check if the clicked point on the map is on the line between those two points
If is, take the first of those two points
DETECTION PSEUDOCODE
var prev_marker;
for (var i=initial_markers; i<initial_marker_count-2; i++) {
if( isPointOnLine(initial_markers[i], initial_markers[i+1], clicked_point) {
prev_marker = initial_markers[i];
break;
}
}
The only reason I am saying that this is pseudocode, is because I don't know hor to find if point is on the line between two points in Google maps. And you should write that isPointOnLine() functions. Apart from that - the idea is given. Hope You appreciate it.
I have a map toggle that when you open it isn't centered on the map marker. I've searched everything, and tried bunch but cannot solve this issue. The HTML markup looks like this:
<div class="hidden_map_wrapper" data-map_height="450px">
<div class="hidden_map_heading">
<h3>Locate us on map</h3>
</div>
<div id="google_map_1" data-map_type="ROADMAP" data-auto_center_zoom="0" data-lat="40.7782201" data-lng="-73.9733317" data-zoom="13" data-scrollwheel="0" data-maptypecontrol="1" data-pancontrol="1" data-zoomcontrol="1" data-scalecontrol="1" class="google_map" style="height: 450px; width: 100%; position: relative; overflow: hidden; transform: translateZ(0px); background-color: rgb(229, 227, 223);">
//bunch of map HTML data here
</div>
<div class="google_map_marker" data-title="Our Company" data-icon="map_marker.png" data-lat="40.7782201" data-lng="-73.9733317">
</div>
</div>
Inside .google_map there is a map that is generated by api already. Now on click I have:
$(".hidden_map_heading").click(function () {
var $current_map = $(this).next(".google_map");
var map_object = document.getElementById($current_map.attr('id'));
$current_map.slideToggle({
duration : 400,
progress : function () {
google.maps.event.trigger(map_object, 'resize');
}
});
$('html, body').animate({ scrollTop: '+=' + $current_map.parent().data('map_height') }, 400);
});
This works, only I don't have my marker centered. I tried with the entire re initializing of the map, but that totally didn't work. I tried adding
var centerofmap = map_object.getCenter();
google.maps.event.trigger(map_object, 'resize');
map_object.setCenter(centerofmap);
In my progress, but that didn't work (got errors about non existing functions).
I'm a bit confused. Everywhere I look the map_object is something like this:
map = new google.maps.Map(document.getElementById($current_map.attr('id')),
myOptions);
But this would mean that I am initializing the map, and the map is already there, initialized and ready. If I don't hide it, it works perfectly. The code for initializing the map looks like this:
function initialize_gmap($element) {
var myLatlng = new google.maps.LatLng($element.data('lat'),$element.data('lng'));
var auto_center_zoom = ($element.data('auto_center_zoom') == 1 ? true : false);
var scrollwheel = ($element.data('scrollwheel') == 1 ? true : false);
var mapTypeControl = ($element.data('maptypecontrol') == 1 ? true : false);
var panControl = ($element.data('pancontrol') == 1 ? true : false);
var zoomControl = ($element.data('zoomcontrol') == 1 ? true : false);
var scaleControl = ($element.data('scalecontrol') == 1 ? true : false);
var styles = (typeof options !== 'undefined') ? options.custom_map_style : '';
var map_type = google.maps.MapTypeId.ROADMAP;
if ($element.data('map_type') == 'SATELLITE') map_type = google.maps.MapTypeId.SATELLITE;
if ($element.data('map_type') == 'HYBRID') map_type = google.maps.MapTypeId.HYBRID;
if ($element.data('map_type') == 'TERRAIN') map_type = google.maps.MapTypeId.TERRAIN;
var mapOptions = {
zoom: parseInt($element.data('zoom'),10),
center: myLatlng,
mapTypeId: map_type,
styles: jQuery.parseJSON(styles),
scrollwheel: scrollwheel,
mapTypeControl: mapTypeControl,
mapTypeControlOptions: {
style: google.maps.MapTypeControlStyle.HORIZONTAL_BAR,
position: google.maps.ControlPosition.BOTTOM_CENTER
},
panControl: panControl,
panControlOptions: {
position: google.maps.ControlPosition.RIGHT_CENTER
},
zoomControl: zoomControl,
zoomControlOptions: {
style: google.maps.ZoomControlStyle.LARGE,
position: google.maps.ControlPosition.RIGHT_CENTER
},
scaleControl: scaleControl,
scaleControlOptions: {
position: google.maps.ControlPosition.BOTTOM_LEFT
},
streetViewControl: false,
streetViewControlOptions: {
position: google.maps.ControlPosition.RIGHT_CENTER
}
};
var elemnt_id = $element.attr('id');
var bounds = new google.maps.LatLngBounds();
var map = new google.maps.Map(document.getElementById(elemnt_id), mapOptions);
var c = 0;
var markers = [];
var infoWindowContent = [];
var marker_icons = [];
$element.siblings('.google_map_marker').each(function(){
var $marker = $(this);
markers[c] = [$marker.data('title'), $marker.data('lat'),$marker.data('lng'),$marker.data('icon')];
infoWindowContent[c] = ['<div class="info_content">' + '<h3>' + $marker.data('title') + '</h3>' + '<p>' + $marker.html() + '</p>' + '</div>'];
c++;
});
// Display multiple markers on a map
var infoWindow = new google.maps.InfoWindow(), marker, i;
// Loop through our array of markers & place each one on the map
for( i = 0; i < markers.length; i++ ) {
var position = new google.maps.LatLng(markers[i][1], markers[i][2]);
bounds.extend(position);
marker = new google.maps.Marker({
position: position,
map: map,
title: markers[i][0],
icon: markers[i][3]
});
// Allow each marker to have an info window
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infoWindow.setContent(infoWindowContent[i][0]);
infoWindow.open(map, marker);
}
})(marker, i));
}
if(auto_center_zoom){
map.fitBounds(bounds);
}
}
$('.google_map').each(function(){
google.maps.event.addDomListener(window, 'load', initialize_gmap($(this)));
});
So, what am I missing here? How to make map centered on marker on resize?
Solution
The trick is to put the map as a global object, as sabotero mentioned. This way I can use
$(".hidden_map_heading").click(function () {
var $current_map = $(this).next(".google_map");
$current_map.slideToggle({
duration : 400,
progress : function () {
var centerofmap = map.getCenter();
google.maps.event.trigger(map, 'resize');
map.setCenter(centerofmap);
}
});
$('html, body').animate({ scrollTop: '+=' + $current_map.parent().data('map_height') }, 400);
});
And it will work on resize.
First of all made var map global
var map;
function initialize_gmap($element) {
var myLatlng = new google.maps.LatLng($element.data('lat'),$element.data('lng'));
var auto_center_zoom = ($element.data('auto_center_zoom') == 1 ? true : false);
var scrollwheel = ($element.data('scrollwheel') == 1 ? true : false);
var mapTypeControl = ($element.data('maptypecontrol') == 1 ? true : false);
var panControl = ($element.data('pancontrol') == 1 ? true : false);
var zoomControl = ($element.data('zoomcontrol') == 1 ? true : false);
var scaleControl = ($element.data('scalecontrol') == 1 ? true : false);
var styles = (typeof options !== 'undefined') ? options.custom_map_style : '';
var map_type = google.maps.MapTypeId.ROADMAP;
if ($element.data('map_type') == 'SATELLITE') map_type = google.maps.MapTypeId.SATELLITE;
if ($element.data('map_type') == 'HYBRID') map_type = google.maps.MapTypeId.HYBRID;
if ($element.data('map_type') == 'TERRAIN') map_type = google.maps.MapTypeId.TERRAIN;
var mapOptions = {
zoom: parseInt($element.data('zoom'),10),
center: myLatlng,
mapTypeId: map_type,
styles: jQuery.parseJSON(styles),
scrollwheel: scrollwheel,
mapTypeControl: mapTypeControl,
mapTypeControlOptions: {
style: google.maps.MapTypeControlStyle.HORIZONTAL_BAR,
position: google.maps.ControlPosition.BOTTOM_CENTER
},
panControl: panControl,
panControlOptions: {
position: google.maps.ControlPosition.RIGHT_CENTER
},
zoomControl: zoomControl,
zoomControlOptions: {
style: google.maps.ZoomControlStyle.LARGE,
position: google.maps.ControlPosition.RIGHT_CENTER
},
scaleControl: scaleControl,
scaleControlOptions: {
position: google.maps.ControlPosition.BOTTOM_LEFT
},
streetViewControl: false,
streetViewControlOptions: {
position: google.maps.ControlPosition.RIGHT_CENTER
}
};
var elemnt_id = $element.attr('id');
var bounds = new google.maps.LatLngBounds();
////////////////////////
////// map is global ///
////////////////////////
/////////////////////////
map = new google.maps.Map(document.getElementById(elemnt_id), mapOptions);
var c = 0;
var markers = [];
var infoWindowContent = [];
var marker_icons = [];
$element.siblings('.google_map_marker').each(function(){
var $marker = $(this);
markers[c] = [$marker.data('title'), $marker.data('lat'),$marker.data('lng'),$marker.data('icon')];
infoWindowContent[c] = ['<div class="info_content">' + '<h3>' + $marker.data('title') + '</h3>' + '<p>' + $marker.html() + '</p>' + '</div>'];
c++;
});
// Display multiple markers on a map
var infoWindow = new google.maps.InfoWindow(), marker, i;
// Loop through our array of markers & place each one on the map
for( i = 0; i < markers.length; i++ ) {
var position = new google.maps.LatLng(markers[i][1], markers[i][2]);
bounds.extend(position);
marker = new google.maps.Marker({
position: position,
map: map,
title: markers[i][0],
icon: markers[i][3]
});
// Allow each marker to have an info window
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infoWindow.setContent(infoWindowContent[i][0]);
infoWindow.open(map, marker);
}
})(marker, i));
}
if(auto_center_zoom){
map.fitBounds(bounds);
}
}
$('.google_map').each(function(){
google.maps.event.addDomListener(window, 'load', initialize_gmap($(this)));
});
then in your progress function :
$(".hidden_map_heading").click(function () {
var $current_map = $(this).next(".google_map");
var map_object = document.getElementById($current_map.attr('id'));
$current_map.slideToggle({
duration : 400,
progress : function () {
google.maps.event.addListener(map, 'resize', function(){
var center = new google.maps.latLng(marker.lat(),marker.lng());
map.setCenter(center);
});
google.maps.event.trigger(map_object, 'resize');
}
});
$('html, body').animate({ scrollTop: '+=' + $current_map.parent().data('map_height') }, 400);
});
Im trying to load around 600 googlemap markers on page load using the function addMarker.
The page takes a lot of time to load.
Is there anything I can do to make it load faster while keep using the addMarker function?
Thanks.
var map
var myLatlng = new google.maps.LatLng(35.9531719,14.3712201);
var markerBounds = new google.maps.LatLngBounds();
var markers = {};
function HomeControl(controlDiv, map)
{
google.maps.event.addDomListener(zoomout, "click", function() {
var currentZoomLevel = map.getZoom();
if(currentZoomLevel != 0)
{
map.setZoom(currentZoomLevel - 1);
}
});
google.maps.event.addDomListener(zoomin, "click", function() {
var currentZoomLevel = map.getZoom();
if(currentZoomLevel != 21)
{
map.setZoom(currentZoomLevel + 1);
}
});
}
function initialize()
{
var googleMapOptions = {
center: new google.maps.LatLng(35.9531719,14.3712201),
zoom: 11,
mapTypeId: google.maps.MapTypeId.ROADMAP,
zoomControl: false,
streetViewControl: false,
panControl: false,
draggable: true
};
map = new google.maps.Map(document.getElementById("map-canvas"), googleMapOptions);
google.maps.event.addListener(map, "idle", function() {
addMarker(latitude,longitude,id,'Title','url');
});
var homeControlDiv = document.createElement("div");
var homeControl = new HomeControl(homeControlDiv, map);
}
var infowindow = new google.maps.InfoWindow({
content: ""
});
function addMarker(lat,long,id,desc,url)
{
var myIcon = new google.maps.MarkerImage("/images/pips/"+id+".png", null, null, null, new google.maps.Size(28,38));
var myLatlng = new google.maps.LatLng(lat,long);
var marker = new google.maps.Marker({
map: map,
title: desc,
position: myLatlng,
icon: myIcon,
id: id
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent('' + desc + '');
infowindow.setPosition(marker.getPosition());
infowindow.open(map, marker);
});
markers[id] = marker;
markerBounds.extend(myLatlng);
google.maps.event.addListener(marker, "click", function() {
infowindow.open(map,marker);
});
}
google.maps.event.addDomListener(window, "load", initialize);
</script>
You can use clustering, it joins neighbor markers into one, and expand only on zoom
You can do clustering in client side, as well as server side, depending the amount of markers...
I would suggest to use server clustering if amount is more than 4000, otherwise client should look fine
function disp_initialize()
{
var bike=<?php echo $_GET['bike_id']; ?>;
$.ajax({
"dataType": "json",
"type": "POST",
"url": "home.php?bike_id="+bike,
success: function(data) {
if(data.sMsg==0)
{
$("#map-canvas").hide();
}
else if(data.sBlankMsg==0){
$("#map-canvas").hide();
}
else
{
initialize(data);
}
}
});
}
function initialize(flightPlanCoordinates_arr)
{
var flightPlanCoordinates_arr = flightPlanCoordinates_arr.mapData;
var flightPlanCoordinates_arr_p = new Array();
var j = 0;var k = 0;
var store = new Array();
for(var i in flightPlanCoordinates_arr)
{
if(j==0)
{
flightPlanCoordinates_arr_p[j] = flightPlanCoordinates_arr[i];
j++;
}
else if(flightPlanCoordinates_arr_p[j-1]['state']==1 && flightPlanCoordinates_arr[i]['state']==0)
{
flightPlanCoordinates_arr_p[j] = flightPlanCoordinates_arr[i];
j++;
}
else if(flightPlanCoordinates_arr_p[j-1]['state']==0 && flightPlanCoordinates_arr[i]['state']==1)
{
store[k]=j;
flightPlanCoordinates_arr_p[j] = flightPlanCoordinates_arr[i];
j++;k++;
}
}
//console.log(store);
var flightPlanCoordinates = new Array();
for(var i in flightPlanCoordinates_arr_p)
{
flightPlanCoordinates[i] = new google.maps.LatLng(flightPlanCoordinates_arr_p[i]["latitude"],flightPlanCoordinates_arr_p[i]["longitude"]);
}
if(flightPlanCoordinates_arr != '')
{
var mapOptions = {
zoom: 10,
center: new google.maps.LatLng(flightPlanCoordinates_arr[0]["latitude"],flightPlanCoordinates_arr[0]["longitude"]),
mapTypeId: google.maps.MapTypeId.TERRAIN
};
}
var map = new google.maps.Map(document.getElementById('map-canvas'),mapOptions);
var Colors = ["#FF0000", "#00FF00", "#0000FF", "#FFFFFF", "#000000", "#FFFF00", "#00FFFF", "#FF00FF"];
for (var i = 0; i < flightPlanCoordinates.length; i++)
{
if(jQuery.inArray(i+1,store)===-1)
{
var colour = Colors[i];
var flightPath = new google.maps.Polyline({
path: [flightPlanCoordinates[i], flightPlanCoordinates[i+1]],
geodesic: true,
strokeColor: '#FFFF00',
strokeOpacity: 2.0,
strokeWeight: 10,
map: map
});
}
}
flightPath.setMap(map);
var location = "";
var location_details = "";
var speed="";
for(var i in flightPlanCoordinates_arr)
{
location = flightPlanCoordinates_arr[i]["location"];
location_details = flightPlanCoordinates_arr[i]["location_details"];
speed = flightPlanCoordinates_arr[i]["speed"];
var marker = new google.maps.Marker({
position: new google.maps.LatLng(flightPlanCoordinates_arr[i]["latitude"],flightPlanCoordinates_arr[i]["longitude"]),
map: map
});
marker.setIcon('images/bike.png');
}
new google.maps.event.addListener(flightPath, 'mouseover', function(event) {
var populationOptions = {
strokeColor: '#11C111',
strokeOpacity: 0.8,
strokeWeight: 4,
fillColor: 'transparent',
fillOpacity: 4,
map: map,
center: event.latLng,
position: event.latLng,
radius: 40
};
// Add the circle for this city to the map.
cityCircle = new google.maps.Circle(populationOptions);
attachSecretMessage(marker, contentHtml,map);
});
new google.maps.event.addListener(flightPath, 'mouseout', function(event) {
var marker = new google.maps.Marker({
position: event.latLng,
});
// Add the circle for this city to the map.
cityCircle.setMap(null);
});
}
function attachSecretMessage(marker, contentHtml, map) {
var infowindow = new google.maps.InfoWindow({
position: marker.position,
content: contentHtml
});
google.maps.event.addListener(marker, 'mouseover', function() {
infowindow.open(map);
});
google.maps.event.addListener(marker, 'mouseout', function() {
infowindow.close();
});
}
mapData is a JSON response which brings 'Latitude','Longitude','Speed','State','Location' values.
I have drawn polylines for the Lats and Longs , but the markers are not displayed.And getting this error
TypeError: f is undefined
Your design is not clear to me exactly.
If you want to get marker visible in mouseout event listener than you have to provide map value. For example:
var marker = new google.maps.Marker({
position: event.latLng,
map: map
});
In that case you have to make map global. Currently it is locally defined in function initialize(). So:
var map;
function initialize(flightPlanCoordinates_arr) {
...
map = new google.maps.Map(document.getElementById('map'), mapOptions);
...
}
Additionally, it seems that this for loop
for (var i = 0; i < flightPlanCoordinates.length; i++) {
should be initialized as:
for (var i = 0; i < flightPlanCoordinates.length - 1; i++) {
Update: see example at jsbin. It's best I can get because I do not understand whole logic of some variables checking. If you set prober icon marker will be set. Note: I cannot perform that ajax call so I had to model data.