I cannot set a marker in a marker cluster invisible by looping my array of markers. I always get the message Uncaught TypeError: Property 't' of object [object Object] is not a function Which translates to setVisible is not a function in my case. (Found out after debugging in chrom)
The following code is used (simplified):
var markers = [];
function placeMarker() {
marker = new google.maps.Marker({
position: position,
map: map,
icon: pinImage,
});
markers.push(marker);
}
function deleteMarkers() {
if (markers) {
for (var i = 0; i < markers.length; i++) {
markers[i].setVisible(false);
}
markers = [];
}
}
The error is thrown in deleteMarkers on the line with markers[i].setVisible(false); What causes this error to be thrown? It seems like the marker is placed inside the array as Object instead of google.maps.Marker
Solved the problem myself in a way that works, but which is not the best way imho.
I had this script embedded in my source
<script src="http://google-maps-utility-library-v3.googlecode.com/svn/trunk/markerclusterer/src/markerclusterer_compiled.js" type="text/javascript"></script>
The error wasnt thrown by google maps but instead by the call to removeMarker on the clusterer:
google.maps.event.addListener(marker, 'visible_changed', function () {
if (marker.getVisible()) {
markerCluster.addMarker(marker, true);
} else {
markerCluster.removeMarker(marker, true);
}
});
All I did was removing _compiled from the script (As I wanted to know what goes wrong in this code). But instead of finding the source of this error, the code began to work.
I think there's something interfering with our scripts in the compiled version, as we have many js scripts on our site.
So the problem is fixed for me, as we embed the script as uncompiled version.
Related
I have a page that works well it loads a Bing Map and creates a layer which is then filled with Polygons. I then need to reload the JSON data that makes the polygons and this again works, however the data is then added to another layer so appears over the top. I have tried to delete the layer, clear the layer etc etc but nothing seems to work.
Any idea please.
This is the function that does it all...
function AddData() {
dataLayer = new Microsoft.Maps.Layer();
Microsoft.Maps.loadModule('Microsoft.Maps.GeoJson', function () {
var featureCollection = Microsoft.Maps.GeoJson.read(json, {
polygonOptions: {
strokeColor: 'LightSkyBlue',
strokeThickness: 2
}
});
for (var i = 0; i < featureCollection.length; i++) {
var fillColour = featureCollection[i].metadata.FillColor;
featureCollection[i].setOptions({ fillColor: fillColour });
Microsoft.Maps.Events.addHandler(featureCollection[i], 'click', displayClickBox);
Microsoft.Maps.Events.addHandler(featureCollection[i], 'mouseover', displayMouseOverBox);
Microsoft.Maps.Events.addHandler(featureCollection[i],'mouseout', displayMouseOut);
dataLayer.add(featureCollection[i], 0);
}
map.layers.insert(dataLayer);
});
}
var getJson = function () {
var onContentComplete = function (response) {
//Load the JSON data into the local variable for use latter in the project...
json = response.data;
//load the map now that we have the polygon data...
AddData();
};
var onError = function (reason) {
//An error has occured so display a message to the user...
$scope.error = "Server communication error please try again...";
//Log the error to the console for admin debug...
console.log(reason.data);
};
//Load the JSON for the map polygons into memory ready for display...
$http.get("../JSON/MapData.json")
.then(onContentComplete, onError);
}
As I have said I have tried to clear the layer first using
dataLayer.clear();
But that seems to do nothing.
Help please as I have been working at this for hours now.
Thanks
Cliff.
By the sounds of things you want all data to render in a single layer, but instead it is rendering two or more layers. This happens because you are creating a new instance of dataLayer every time the AddData function is called. Additionally, this overwrites the local variable for dataLayer and thus you lose the reference to the original layer that you are trying to clear/delete. If you want to clear or delete the layer, do that before initializing the new layer. Try adding the following to the top of your AddData function:
if(dataLayer){
map.layers.remove(dataLayer);
}
Alternatively, reuse the layer by clearing it if it exists of or creating it if it doesn't:
if(dataLayer){
dataLayer.clear();
}else{
dataLayer = new Microsoft.Maps.Layer();
}
Apologies in advance if this is an obvious issue. I have done as much searching as I could putting this issue into search terms.
I have the below block of code which is supposed to create a Google maps marker for each 'transponder' if there has not been one added previously. However every time this block of code runs it doesn't detect the previously created marker stored in the transponder object and recreates it.
This is despite seeing the marker within the transponder object in the DOM view of Firebug.
function addOrUpdateTransponderPostionRpt(transponderPositionRpt) {
var t = getTransponderById(transponderPositionRpt.TransponderId);
if (t) {
console.log("Found Transponder: " + t.Id);
if (t.gMapMarker) {
console.log("Transponder has existing marker, updating: " + t.Id);
moveMarker(t.gMapMarker, new google.maps.LatLng(transponderPositionRpt.Latitude, transponderPositionRpt.Longitude));
} else {
console.log("Transponder has no existing marker, creating: " + t.Id);
var marker = new google.maps.Marker({
position: new google.maps.LatLng(transponderPositionRpt.Latitude, transponderPositionRpt.Longitude),
map: map,
title: t.DefaultNickname
});
t.gMapMarker = marker;
}
}
}
debug output from the javascript (the same every time)
Found Transponder: 4
Transponder has no existing marker, creating: 4
Found Transponder: 6
Transponder has no existing marker, creating: 6
Can anyone help ? :)
EDIT: Additional methods referenced in this code block:
function getTransponderById(id) {
var ret;
$.each(transponders, function (i, item) {
if (transponders[i].Id == id) {
ret = transponders[i];
return;
}
});
return ret;
}
function moveMarker(marker, newPosition) {
marker.setPosition(newPosition);
}
a) the real joke first:
Finally buying Microsoft stuff over the years paid off..
Trying to debug using Chrome, my map was showing just one marker. It was on the correct latlng for the period of the setTimeout, blinks for a small fraction of second, back to same position.
At a certain time, shot code to Explorer by mistake....... voila... code iterates through the database, but does not use the setTimeout for each marker. At Explorer, setTime out (Ex, 5 seconds), means all the markers will show up, with the right infowindow, but it's 5 seconds for all markers. The longer the time, the longer it will stay in one of them (alwyas the same one), going really fast on the other markers. At chrome, the iteration was so fast I could not see the iteration thru the other latlng's. It was just a blink.
b) I guess the problem is that the getJson (or Ajax), using either for loop or $.each (I used all sorts of combinations.....) is combined with the other loop inside the function changeMarker. So there are two loops going on at the same time. However, I don't know how to fix it. If I close the Ajax (or getJson) right after the $.each or for loop, the rest of the code doesn't get the values. Nothing happens (just my alert, which is for debugging purposes).
No, I don't fully understand closures. Yes, I read a bunch of stuff, the main one here, but also here and here and there. but still didn't figure it out to :/
c) Not easy being a newbie, trying to solve a problem for days... and not getting it solved.
Any help will be greatly appreciated!
Here is the code - omitted a long section where map gets personal options.
var BERLIN = new google.maps.LatLng(-32.517683, -46.394393);
var map = null;
var marker = null;
var index = 0;
var infoWindow = null;
var latlng ;
var MY_MAPTYPE_ID = 'custom_style';
function initialize() {
//personal options not included here.
var customMapType = new google.maps.StyledMapType(featureOpts, styledMapOptions);
map.mapTypes.set(MY_MAPTYPE_ID, customMapType);
$.getJSON('php/locationsJson.php',function(json){
$.each( json, function(i, item) {
var lat = this.lat;
var lng = this.lng;
var location = new google.maps.LatLng(json[i].lat,json[i].lng);
alert( json[i].lat +','+json[i].lng );
function dropMarker (map, pos){
return new google.maps.Marker({
map: map,
position: location,
draggable: false,
}); // return
}
function changeMarker() {
if (marker) {
infoWindow.close();
marker.setMap(null);
}
var pos = location[index];
marker = dropMarker(map,pos);
var contentString = ('lat: ' + location.lat() + '<br />' + 'lng: ' + location.lng())
infoWindow.setContent(contentString);
setTimeout(function () {
infoWindow.open(map, marker);
}, 100);
index = (index + 1) % json.length;
setTimeout(function () {
changeMarker();
}, 4000);
}
var customMapType = new google.maps.StyledMapType(featureOpts, styledMapOptions);
infoWindow = new google.maps.InfoWindow()
changeMarker();
}); //$.each
}); //end of getjson
} //end of initialized
Here is fiddle (thanks for the help to get to that point) for the code BEFORE the AJAX. I tried to add the json file in the fiddle, but it's too complex to add json inside the fiddle.
Thank you again for your time.
As your approach in the fiddle works fine, you don't need much modifications to
achieve it via ajax.
Instead of starting the timeouts inside the loop use the loop only to populate the NEIGBORHOODS-array, and after the loop call changeMarker()
The success-callback for $.getJSON:
function(json){
NEIGBORHOODS=[];
$.each(json,
function(){
NEIGBORHOODS.push(new google.maps.LatLng(this.lat,this.lng));
});
changeMarker();
}
The rest of the code may stay as it is in the fiddle.
Working fiddle with ajax-request: http://jsfiddle.net/doktormolle/CVECG/
(Note: In the fiddle I've used $.post() because jsfiddle requires post-requests for JSON, you can use $.getJSON in your application)
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
change global variable inside javascript closure
I am having a problem storing data in a javascript global array . I can't figure out why the array is empty even though I have assigned it some elements.
Basically I have two functions: loadMarkers is called whenever a user clicks a button and gets some information from a url in JSON, parses that data and stores it in the global array. The other function is showMarkers that just iterates over the array and show all the markers, but that array is empty!
Thansks in advance.
var markers = [];
function loadMarkers(url) {
markers = [];
$.get(url, function(data) {
var json = jQuery.parseJSON(data);
for (var i = 0; i < json.length; i++) {
// parsing json
var lat = json[i].Latitude;
var lng = json[i].Longitude;
var id = json[i].ID;
console.log(id); // this prints with no problems!
// create new marker
var marker = new google.maps.Marker({
position: new google.maps.LatLng(lat, lng),
title: id,
html: "<p>" + "Info for container " + id + "</p>"
});
// add marker to markers array
markers.push(markers[i]);
// add info window to marker
google.maps.event.addListener(marker, "click", function() {
infoWindow.setContent(this.html);
infoWindow.open(map, this);
});
}
});
}
function showMarkers() {
for (i = 0; i < markers.length; i++)
console.log(markers); // here I get an empty array!
markers[i].setMap(map);
}
It seems like this line:
markers.push(markers[i]);
should instead be:
markers.push(marker);
Maybe its the following code
// add marker to markers array
markers.push(marker); // was markers[i]
Regarding your second question in the comments the $.get() method returns a jQuery deferred object which allows you to execute functions after method has finished.
$.get().done( function( ) {
// your code
});
There's a typo in the code:
markers.push(markers[i]);
should be:
markers.push(marker);
It can be surprisingly hard to spot this kind of typos by just looking at the code (it's like our brains are trained to let us read what we expect to read)... In this case the best approach to find quickly these kind of errors is to add a debugger; instruction in the code, and follow along the execution of the program through the devtools of your choice.
I wonder whether someone may be able to help me please.
This page allows users to filter (via checkboxes), markers which are placed on the map. Clicking on any marker performs a 'reverse geocode' action and in conjunction with selecting the 'Search Locations' button, the user can then see POI's within a given radius of the clicked marker.
For demo purposes, if you select the 'Coin' checkbox, click the green marker, then select the 'Search Locations' button, the marker will bounce and the right hand sidebar will be populated with POI's.
The problem I'm having is that in Internet Explorer everything works fine, but when I try to run this in Chrome, the marker looses the 'bounce' functionality, the 'reverse geocode' doesn't run and in the error console I receive the following error:
Uncaught ReferenceError: reversegeocode is not defined at line 55 of my code which is:
reversegeocode(); I've done some reading on this and other sites and from reading the guidance I've tried changing this part of my code to this:
function geocodePosition(pos) {
var clickListener =
document.getElementById('findosgb36lat').value = this.mylat;
document.getElementById('findosgb36lon').value = this.mylon;
document.getElementById('address').value = this.myaddress;
if(bouncingMarker)
bouncingMarker.setAnimation(null);
if(bouncingMarker != this) {
this.setAnimation(google.maps.Animation.BOUNCE);
bouncingMarker = this;
}
else bouncingMarker = null;
}
geocoder.geocode({latLng: pos }, function(responses) {
if (responses && responses.length > 0) {
updateMarkerAddress(responses[0].formatted_address);
} else {
updateMarkerAddress('Cannot determine address at this location.');
}
});
}
function updateMarkerAddress(str) {
document.getElementById('address').value = str;
}
function getAddress(latlng) {
if (!geocoder) {
geocoder = new google.maps.Geocoder();
}
geocoder.geocode({ 'latLng': latlng }, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
// Looping through the result
for (var i = 0; i < results.length; i++) {
if (results[0].formatted_address) {
document.getElementById('address').value =
results[0].formatted_address;
}
}
}
}
)
}
But unfortunately, this doesn't work and actually creates more problems with syntax errors.
I'm relatively new to Javascript, so perhaps I've totally misunderstood,. But I just wondered whether someone could possibly take a look at this please and let me know where I'm going wrong?
Many thanks and kind regards
Code feedback:
What is the second line in your code: var clickListener = meant to do (something is missing)?
Both of your calls to geocoder.geocode pass an object with a property named: latLng; the object passed should match the structure of google.maps.GeocoderRequestapi-doc, which has properties named: address, bounds, location, and region. I suggest you change the name of these properties from: latLng to location.
I'm not sure of the context of the code shown, but the usage of this in this code section looks suspicious:
if(bouncingMarker != this) {
this.setAnimation(google.maps.Animation.BOUNCE);
bouncingMarker = this;
}
It looks like you are within a global function, so it looks like the use of this may not make sense here?
That's all I see after a first pass; hope this helps you -