center on cluster from outside map - google-maps-api-3

I have multiple markers on a map, and I have added the following listener that centers a marker when clicked on.
google.maps.event.addListener(marker, 'click', (function (marker, count) {
return function () {
this.map.setCenter(marker.getPosition() as google.maps.LatLng);
}
})(marker, count));
I also have the following for centering on a specific marker from outside the map:
centerFromTimeline(i){
google.maps.event.trigger(this.markers[i], 'click');
}
which works all well and good, except for when the markers are clustered. If the marker is hidden in a cluster, centerFromTimeline() will not work cause this.map is null. Is there a way to center on the cluster in this situation?

So I found you can get the clusters and search them for your marker.
let inCluster
let clusters = await this.markerClusterer.getClusters()
for(let cluster of clusters){
let foundMarker = cluster.markers_.find(element => element === this.markers[i]);
if (foundMarker !== undefined)
inCluster = true;
break;
}

Related

Google map showing only some markers but all markers shown in debug mode

A few of my markers are not showing in the map I created and I have drilled down the reason being too many API calls. But the problem is that even after adding setTimout/ delay code all markers are not shown. When i debug the code in chrome though it works fine (even when i remove all the break points and allow the website to load - all markers are loaded without any issues)
www.khojiye.com is the link
function map_marker(ajax_result,address_length)
{
val = ajax_result[counter];
if($.trim(val)!=""){
//alert(i);
//alert(val);
var valA = val.split('###');
setTimeout(geocoder.geocode( { 'address': valA[0]}, function(results, status) {
if(status == google.maps.GeocoderStatus.OK)
{
var lat = results[0].geometry.location.lat();
var lng = results[0].geometry.location.lng();
// Set the coordonates of the new point
var latLng = new google.maps.LatLng(lat, lng);
//bounds.extend(latLng);
var marker = new google.maps.Marker(
{
position: latLng,
map: map,
title: valA[0],
animation: google.maps.Animation.DROP,
icon:valA[1]
});
// The HTML that is shown in the window of each item (when the icon it's clicked)
var html = "<div style='width:150px; margin-top: -12px;'><h3 style='font-size:16px; font-weight:500;'>"+valA[2]+"</h3><h4 style='font-size:15px; line-height:21px;'>"+valA[0]+"</h4><a href='"+valA[3]+"'>View Detail</h4></div>";
// Binds the infoWindow to the point
bindInfoWindow(marker, map, infoWindow, html);
// Add the marker to the array
markers.push(marker);
counter++;
a_c++;
if(counter<address_length)
map_marker(ajax_result,address_length);
}
else{
//alert("Geocode was not successful for the following reason: " + status);
//marker = '';
//markers.push(marker);
//console.log(status);
counter++;
b_c++;
if (status == google.maps.GeocoderStatus.OVER_QUERY_LIMIT){
counter--;
console.log(counter);
delay=delay*5;
}
if(counter<address_length)
map_marker(ajax_result,address_length);
}
}),delay);
}
}
I dont know what i did is a hack or not:
1. it seems my use of set timeout was incorrect
2. I removed the setTimeout from top function and added it as
setTimeout(function() {map_marker(ajax_result,address_length);},delay);}

Google maps circle overlay . how to call a function on after drag complete?

Guys after a long R&D I was able to draw a circle and put markers which are inside that area of circle based on position and radius.
I'm calling a function which triggers whenever the radius or the position of the circle changes..
It is working fine( function triggers and it fetches the markers from the database.) but the function is called when the circle is being dragged(some 100 times). i want that function to called OnDragComplete.. i didn't find any such events Google API..
below is my code.. Any help would be greatly appreciated.
google.maps.event.addListener(distanceWidget, 'distance_changed', function() {
displayInfo(distanceWidget);
searchLocations();
});
google.maps.event.addListener(distanceWidget, 'position_changed', function() {
displayInfo(distanceWidget);
searchLocations();
});
You could add a "dragging" property to the widget on the mouse events and check it in your other functions:
google.maps.event.addListener(distanceWidget, 'mousedown', function() {
distanceWidget.dragging = true;
});
google.maps.event.addListener(distanceWidget, 'mouseup', function() {
distanceWidget.dragging = false;
});
google.maps.event.addListener(distanceWidget, 'position_changed', function() {
if (distanceWidget.dragging === false) {
displayInfo(distanceWidget);
searchLocations();
}
});
I too faced this issue. we can use drag and dragend event listener inside
DistanceWidget function and use marker instance to listen
function DistanceWidget(map) {
this.set('map', map);
this.set('position', map.getCenter());
var marker = new google.maps.Marker({
lat: $('input[name=lat]').val(),
lng: $('input[name=lng]').val(),
draggable: true,
crossOnDrag: false,
cursor: 'crosshair',
title: 'Drag to change circle radius!',
icon: 'assets/front/images/pin.png',
});
google.maps.event.addListener(marker, 'drag', function(e) {
console.log('starting');
});
google.maps.event.addListener(marker, 'dragend', function(e) {
// Trigger once u drop the widget marker
console.log('end');
});
}

streetview visible_changed event does not giving panorama position and zoom

I am trying to capture when the pegman icon is dropped on the google maps and send the panorama position and zoom to server. The code below is for listening to visible_changed event. But the thePanorama.getZoom() and getPosition() return undefined.
thePanorama = map.getStreetView();
streetviewChangeListener = google.maps.event.addListener(thePanorama, 'visible_changed', function() {
console.log('visible_changed ');
console.log('streetview panorama position: ' + thePanorama.getPosition() + ' zoom: ' + thePanorama.getZoom());
emitStreetViewEvents({position: thePanorama.getPosition(), zoom: thePanorama.getZoom()});
});
Help?
unfortunately I had a simulare problem, calculating the distance between markers en panorama position to hide and show the markers.
I concluded that with the visible_changed you get the position from before the change.
To get this working I had to add an extra listener for the position_changes.
In my code I have to kinds of markers, one kind linking to panorama's and one linking to external websites, both visible in map mode. In panorama mode the panorama markers are hidden. The website markers are checked with distance from the panorama position and showing only the markers in a certain distance.
google.maps.event.addListener(panorama, 'visible_changed', function() {
if (panorama.getVisible()) {
hideMarkers();
checkZelfstudies();
} else {
showMarkers();
showZelfstudies();
}
});
google.maps.event.addListener(panorama, 'position_changed', function() {
checkZelfstudies();
});
https://developers.google.com/maps/documentation/javascript/streetview?hl=nl#StreetViewEvents
Hope this helps you solving your problem. It works in my code.
I just encode something for update the position and zoom when the pegman is dropped in google maps version 3, so, using your variables and adding some others lines, maybe it will help you:
var marker;
var latlng;
var map;
var panorama;
function initialize(position) {
map = new google.maps.Map(document.getElementById('map_canvas'), mapOptions);
panorama = new google.maps.StreetViewPanorama(document.getElementById('pano'), panoramaOptions);
thePanorama.setStreetView(panorama);
google.maps.event.addListener(panorama, 'position_changed', function() {
marker.setMap(null);
marker = new google.maps.Marker({
position: panorama.getPosition(),
map: map,
draggable: false
});
map.setCenter(marker.getPosition());
console.log(marker.position.lat());
console.log(marker.position.lng());
});
google.maps.event.addListener(map, 'zoom_changed', function() {
console.log('zoom_changed');
console.log(thePanorama.getZoom());
});
google.maps.event.addListener(panorama, 'pano_changed', function() {
console.log(panorama.getPano());
});
google.maps.event.addListener(panorama, 'pov_changed', function() {
console.log(panorama.getPov().heading % 360);
console.log(panorama.getPov().pitch);
});
}
I hope it works for you, greetings.

Google Maps APIV3 listener set_at not firing until second time

I have the following code, which should trigger an alert when a Polygon shape is changed. This alert only appears after the shape has been changed twice. Meaning, I have to resize the shape two times before the event is triggered.
Any idea as to what may be causing this behavior?
function drawListener(drawingManager) {
var coord_listener = google.maps.event.addListener(drawingManager, 'polygoncomplete', function (polygon) {
var coordinates = (polygon.getPath().getArray()); //get
var bounds = new google.maps.LatLngBounds();
var people = [];
google.maps.event.addListener(polygon.getPath(), 'set_at', function () { //check to see if the item has been changed //THIS ONLY GETS CALLED AFTER POLYGON HAS BEEN CHANGED TWICE
alert('changed');
});
});
I found my answer: I must use 'insert_at' in addition to 'set_at'
google.maps.event.addListener(polygon.getPath(), 'set_at', function () {
alert('changed');
});
google.maps.event.addListener(polygon.getPath(), 'insert_at', function () {
alert('also changed');
});
Thanks.

Any change in zoom level causes all my markers to re-appear on my Google map

Any change in zoom level causes all markers to appear on the map that have been on the map at any time since the last page load. This is true whether the zoom level change is due to a setZoom() call in my code or because I operate the zoom slider.
I have a map control widget with buttons to add markers that correspond to different categories. So you click the button for Groups and the map populates with markers that represent Groups. Then you click on the Individuals button and the Groups markers are cleared and deleted and the Individual markers appear on the map. And so on with other categories. But any change in zoom level brings back any markers that have been on the map since the page was last refreshed.
I'm using MarkerClustererPlus. I don't know whether this would be a bug in MarkerClustererPlus, in Google's code or in my code. Hopefully the latter. I'll include my addMarkers function below. Since I both clear and delete the markers before adding new markers, I don't know how it's possible for the previous markers to come back, nevermind why a zoom change trigger their return:
function addMarkers(map,flag) {
clearOverlays();
deleteOverlays();
if ('event' == flag) {
data = himaps_event_data;
} else if ('story' == flag) {
data = himaps_story_data;
} else if ('group' == flag) {
data = himaps_group_data;
} else {
data = himaps_user_data;
}
for (var k in data) {
var item = data[k];
var latLng = new google.maps.LatLng(item.lat, item.lng);
var marker = new google.maps.Marker({'position': latLng});
markersArray.push(marker);
}
var markerCluster = new MarkerClusterer(map, markersArray);
}
Also, if I change zoom, then the markers don't clear anymore. They just continue to accumulate on the map if I click the buttons to change category. That definitely doesn't happen if I don't change the zoom level.
By request, here's more of the code:
function clearOverlays() {
if (markersArray) {
for (var i = 0; i < markersArray.length; i++ ) {
markersArray[i].setMap(null);
}
}
}
function deleteOverlays() {
if (markersArray) {
for (i in markersArray) {
markersArray[i].setMap(null);
}
markersArray.length = 0;
}
}
/* map controls */
(function($) {
Drupal.behaviors.himaps = {
attach: function(context, settings) {
$('.map-controls button').click(function() {
flag = this.id.replace('map-','');
addMarkers(map,flag);
});
}
}
})(jQuery);
/* homepage map */
function newMap(clat,clng) {
if (!clat) {
clat = 37.65;
}
if (!clng) {
clng = -97.43;
}
var myOptions = {
scrollwheel: false,
mapTypeControl: false,
mapTypeControlOptions: {
style: google.maps.MapTypeControlStyle.HORIZONTAL_BAR,
position: google.maps.ControlPosition.LEFT_CENTER
},
panControl: false,
panControlOptions: {
position: google.maps.ControlPosition.LEFT_CENTER
},
zoomControlOptions: {
style: google.maps.ZoomControlStyle.LARGE,
position: google.maps.ControlPosition.LEFT_CENTER
},
draggable: true,
center: new google.maps.LatLng(clat, clng),
zoom: 4,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
return new google.maps.Map(document.getElementById("map-canvas"), myOptions);
}
var map;
var markersArray = [];
var geocoder;
var marker;
var listener;
google.maps.event.addDomListener(window, 'load', initmapping);
function initmapping() { //aka initialize()
map = newMap();
addMarkers(map,'group');
geocoder = new google.maps.Geocoder();
}
Last but not least, here is the MarkerClustererPlus library: http://google-maps-utility-library-v3.googlecode.com/svn/tags/markerclustererplus/2.0.9/src/
I don't know much about MarkerClusterer but what appears to be happening is every time you call your addMarkers function you are creating a new MarkerClusterer but the old one is never destroyed/removed, hence on zoom change all instances you have created redraw the markers they have. Try the clearMarkers or removerMarkers method of MarkerClusterer and also only create one instance of MarkerClusterer and reuse it instead of creating a new one each time you cal addMarkers.

Resources