Google Maps Marker Cluster Sum Value - javascript

I currently have an app that creates an array of markers. But it is not useful, because I would like to see a group of markers and a custom property summed based on the distance between markers (depending on the zoom level).
I've said that maybe with MarkerClusterPlus I could accomplish something like this:
This even shows a custom icon, I don't need that, I only need the number over the cluster.
But I don't know where to start. Could someone place an example or a link?

You must define a custom property on the Marker object, so you can override the Calculator function in markercluster.js
MarkerClusterer.CALCULATOR = function (markers, numStyles) {
var index = 0;
var title = "";
var count = markers.length.toString();
var valueToSum=0;
for(var m=0;m<markers.length;m++){
//This is the custom property called MyValue
valueToSum+=Number(markers[m].MyValue);
}
var dv = val;
while (dv !== 0) {
dv = parseInt(dv / 10, 10); //you could define your own rules
index++;
}
index = Math.min(index, numStyles);
return {
text: valueToSum,
index: index,
title: title
};
};

Related

Javascript Object with a variable

I'm building a basic game with NSEW navigation.
Each NSEW button changes the current location's number, 1,2,3,etc.
Each location has an object that's intended to be associated with it, named loc1,loc2,loc3,etc.
Each object has a description that needs to be displayed, loc1.desc, loc2.desc, etc.
My display function is working, as is my navigation, BUT...
I'm TRYING to pass the loc#.desc value corresponding to the correct current location into the function. (This is Javascript, btw). Currently, it looks like this:
function nextLoc(dir) {
var newLoc = nav[currentLoc][dir];
currentLoc=newLoc;
displayMessage(loc[currentLoc].desc);}
I want it to input the current location's number and pass that to the displayMessage function. I've tried it a ton of different ways, but it still does NOT print the description. If I hard code the number (loc2.desc) or just pass currentLoc, it works, returning the correct object description or the currentLoc number. I've also tried:
loc+[currentLoc]+.desc
Is there a way to do this? I've searched and tried all the different ways to find this but I can't find this specific issue and, at this point, I'm just lost! Any help is greatly appreciated!!
In answer to comments, here's the whole js file:
//Location prototype
function Location(id, desc){
this.id = id;
this.desc = desc;}
//Location objects
var loc2 = new Location(2, "Circus");
var loc1 = new Location (1, "Zoo");
var loc0 = new Location (0,"You entered the park here");
var currentLoc = 0;
var EAST = 0;
var WEST = 1;
var NORTH = 2;
var nav = [ // E,W,N,S
/*Current Location*/
/* 0 */ [2,1,4,-1],
/* 1 */ [0,-1,3,-1],
/* 2 */ [-1,0,5-1],
/* 3 */ [4,-1,-1,1],
/* 4 */ [5,3,-1,0],
/* 5 */ [-1,4,-1,2],
];
// Directional Button Event Handlers
function btnEast_click() {nextLoc(EAST);}
function btnWest_click() {nextLoc(WEST);}
function btnNorth_click() {nextLoc(NORTH);}
function nextLoc(dir) {
var newLoc = nav[currentLoc][dir];
currentLoc=newLoc;
displayMessage(loc[currentLoc].desc);}
// Utility Function(s)
function displayMessage(msg) {
var target = document.getElementById("taMain");
target.value = msg + "\n\n" + target.value;
}
You were quite close to being able to do named-lookups in a map object. Rather than creating a bunch of independent locations (which in a browser, end up as properties of the window object, so there was an avenue that I've chosen not to pursue that would've let you use them.
What I'm doing below is creating an object for the static locations. Another approach would be to use notation like this, which would actually result in the same behavior but might be easier to understand what's going on:
var locations = [];
locations['loc2'] = new Location(2, "Circus");
locations['loc1'] = new Location(1, "Zoo");
locations['loc0'] = new Location(0, "You entered the park here.");
Also workable would be removing the 'loc' prefix on your keys, then you could write things like this:
var locations = [];
locations.add = function(id, desc){ locations[id] = new Location(id, desc)}
locations.add(0, "You entered the park here.")
// and your navigation method looks like this then
function nextLoc(dir){
var newLoc = nav[currentLoc][dir];
currentLoc=newLoc;
displayMessage(locations[currentLoc].desc);
}
Another form which resembles what you've done so far
var locations = {
loc2 : new Location(2, "Circus"),
loc1 : new Location (1, "Zoo"),
loc0 : new Location (0,"You entered the park here")
};
function nextLoc(dir) {
var newLoc = nav[currentLoc][dir];
currentLoc="loc"+newLoc;
displayMessage(locations[currentLoc].desc);}

Reach layer name property from a layer group in OpenLayers3

I have a layer group consisting of 3 layers and named for example: group1.
I want to produce an array of the names of the layers that are in this group. I'm actually doing that:
group1.getLayers().getArray()
I'm reaching the level of the ol.layer.vector, but I can't seem to find how to access the value of the name propertie.
My guess was to do add a .get("name") after the getArray() but it doesn't work (I guess you can't call more than 2 methods). I also tried stocking the results of the getArray() in a variable, but then I can't do a get("name") on the variable.
How can I access my layers name ?
Edit: Looks like I can use the getLayersArray() method also, but I'm stuck with the same problem.
Ok I found my answer.
function getNames(dom){
var stock = [];
var layer_names = [];
stock = dom.getLayersArray();
for(i=0;i<stock.length;i++){
layer_names[i] = stock[i].get("name");
};
return layer_names;
}
Thanks to #1saac .
Edit: Pushed it a little to add properties keys of each layer:
function getNames(domaine){
var r_stock = [];
var r_layers = [];
r_stock = domaine.getLayersArray();
for(i=0;i<r_stock.length;i++){
feat_source = r_stock[i].getSource();
feat_get = feat_source.getFeatures();
prop_feature[i] = feat_get[0].getKeys();
r_layers[i] = ["name", r_stock[i].get("name")];
for(j=0;j<prop_feature[i].length;j++){
r_layers[i].push("id" + j, prop_feature[i][j])
};
};
return r_layers;
};

JavaScript fixed array or object length?

I need a way to store two values only within an array or object and limit its length to two values. The reason is that I am using a jQuery Vectormap to calculate the distance and a draw line between two coordinates x1/y1 & x2/y2.
Whenever a region/country is clicked, corresponding markers are loaded and added to the map
map.addMarker(id ,{latLng: [val.lat, val.long], name:val.name}) ; ect///
Now, whenever a marker is clicked I should be able to track count of two markers's selection and store their coordinates in an array then do the calculations..
onMarkerClick:function(e, code){
var coordinates = map.markers[code].config.latLng;
// latitude = coordinates[0]
// longitude = coordinates[1]
}
So if I were to use myArray.push([coordinates[0],coordinates[1]]) for each marker clicked then I end up with countless number of coordinates and thus making it impossible to draw my line.. Is there a way to set myArray length to 2 then when I push more values overwrite the existing one?
Thanks
If you want to be fancy about it, you can create your custom class that does this...
function CappedArray(Size)
{
this.push = function(Value) {
if(this.length==Size)
{
this.shift();
}
CappedArray.prototype.push.call(this, Value);
}
}
CappedArray.prototype = new Array();
//How you use it
var SomeArray = new CappedArray(2);
SomeArray.push([coordinates[0],coordinates[1]]);
...
Alternatively, if you want to force the fact that points should only be associated in successive pairs of insertions:
function PairArray()
{
this.push = function(Value) {
if(this.length==2)
{
this.splice(0, 2);
}
PairArray.prototype.push.call(this, Value);
}
}
PairArray.prototype = new Array();
//How you use it
var SomeArray = new PairArray();
SomeArray.push([coordinates[0],coordinates[1]]);
You could use an object like this:
var coords =
{
"c1": [x1,y1],
"c2": [x2,y2]
}
then when adding coordinates you could:
coords.c1 = coordinates[0];
coords.c2 = coordinates[1];

Remove Google Maps Markers by label

Im currently working on a cross platform app that has a google map that has a whole bunch of icons on it. I use an Ajax query to get a kendo ui mobile datasource that has a list of lat/lng values and a category of the object.
From there when the user selects turn on that category, those markers appear on the map. This currently works however removing them is the issue.
When I go to remove them, I do not know how to delete all markers with a specific label. Is there a global array of markers that I can iterate through to find the appropriate markers to remove?
If there is I can simply set these particular markers map to null to remove them.
My code for adding markers is below:
var dataItem;
var facData = new kendo.data.DataSource({
........
});
facData.fetch(function() {
if (e.checked == 1) {
for (var i = 0;i < facData.view().length;i++) {
dataItem = facData.view()[i];
dataItemLatLng = new google.maps.LatLng(dataItem.lat, dataItem.lon);
createMarker(dataItemLatLng, "Toilets", toiletIcon);
}
}
else {
Code for removing all markers with label "Toilets"
}
})
}
In some outer scope :
var markers = [];
And your function that creates/removes markers :
function foo() {
var facData = new kendo.data.DataSource({
........
});
facData.fetch(function() {
if (e.checked == 1) {
for (var i = 0; i < facData.view().length; i++) {
var dataItem = facData.view()[i];
var dataItemLatLng = new google.maps.LatLng(dataItem.lat, dataItem.lon);
var marker = createMarker(dataItemLatLng, "Toilets", toiletIcon);
markers.push(marker);
}
}
else {
while(markers.length) {
markers.pop().setMap(null);
}
}
});
}
You need to ensure that createMarker() returns the created marker.
As written, the markers array is emptied as the markers are removed from the map. This seems sensible, otherwise, next time round the array would still contain references to the old markers plus references to all the new ones - much of the time, this would mean duplicate markers created from the same data as last time ... and so on, and so on.
I created a global array that each marker, when added is pushed into. Then the remove code is simply:
for(var i=0; i< markerArray.length;i++){
if(markerArray[i].getTitle()=="Toilets"){
markerArray[i].setMap(null);
}
}

Remove specific markers from a map?

I have a Google Map with a bunch of markers.
I add markers to the map one-by-one and need to remove individual markers one-by-one too when required, using individual IDs.
Currently I have some horrible, verbose code, involving a global array of markers, an ID added as metadata to each marker, and a clunky method for looking up a marker's position within the array, as follows:
var markersArray = [];
function getPositionById(markerId, arr) {
for (var i = 0; i < arr.length; i++) {
if (arr[i].metadata.id === markerId) {
return i;
}
}
return null;
}
function removeMarker(markerId) {
var marker_position = getPositionById(markerId, markersArray);
if (marker_position !== null) {
markersArray[marker_position].setMap(null);
markersArray.splice(marker_position,1);
}
}
function setMarker(position, markerId) {
removeMarker(markerId);
var temp_marker = new google.maps.Marker({
position: position
});
temp_marker.setMap(map);
temp_marker.metadata = { id: markerId };
markersArray.push(temp_marker);
}
Could anyone suggest an even slightly more elegant way to do it?
Given that to remove a marker from the Map you need to use setMap(null), means that you need to have a reference to that marker.
The way you presented in your question doesn't look as horrible as you think, but another way to do it is to use a map instead of an array (not sure if map is the best term to use here since we are already working with the Google maps Map), nonetheless, using a map would rid you from the getPositionById() function, off course this assumes that all your markerIds are unique.
Your code would look something like this.
var markers = {};
function removeMarker(markerId) {
if(markers[markerId]){
markers[markerId].setMap(null);
delete markers[markerId];
}
}
function setMarker(position, markerId) {
removeMarker(markerId);
var temp_marker = new google.maps.Marker({
position: position
});
temp_marker.setMap(map);
temp_marker.metadata = { id: markerId };
markers[markerId] = temp_marker;
}

Categories