I'm using superclsuter for clustering markers in react native map, what I want is to get all children from a cluster no matter what level of nesting a cluster may have.
to explain the situation a little better, a cluster can have markers and other clusters as children, I need to flatten the child clusters to get markers inside them.
cluster
marker
cluster(3 markers)
// this should return the 4 markers, the top-level marker, and markers within the child cluster
I know it is late for an answer, but this solution is for google map using google-map-react package.
First on initializing the map options, add maxZoom and minZoom. maxZoom must be equal to supercluster max-zoom
On cluster rendering use this code:
if(isCluster){
if(zoom>=15){
return (
//Create MultiMarker similar to the marker below but different infowindow style to display list of places and display text
<MultiMarker
key={`cluster-${cluster.id}`}
lat={latitude}
lng={longitude}
text={`${pointCount} Listing`}
places={supercluster.getChildren(cluster.id)}
>
</MultiMarker>
)
}else{
return ClusterMarker;
}
}
return Normal or Custom marker;
For cluster reference: https://www.leighhalliday.com/google-maps-clustering
Related
I'm working on a leaflet map where many markers are shown with prunecluster, and I need to get the list of clusters that are currently shown in the map.
I have initialized the clusters with
var pruneCluster = new PruneClusterForLeaflet(150, 70);
The only array of the cluster I'm seeing in the developers tools and in the code is pruneCluster.Cluster._clusters. Actually it is a mostly exact representation of the clusters shown in the map, but, sometimes, the length of that array is different from the number of clusters that are shown in the map. I.e., that array doesn't represent the situation I have in the map.
What array should I use?
That pruneCluster.Cluster._clusters contains all the clusters it calculated, but since you can pan and zoom the map, the visible clusters can be a subset of it.
You can iterate over the clusters and test if they are visible. Like this:
// Get the bounds of the map visible in the browser
// 'map' is your Leaflet map
var boundsOfView = map.getBounds();
// Iterate all prune clusters
var allClusters = pruneCluster.Cluster._clusters;
var clustersInView = [], clusterBounds;
for (var i = 0; i < allClusters.length; i += 1) {
clusterBounds = allClusters[i].bounds;
// Is this cluster visible? (within the visible bounds?)
if (boundsOfView.intersects([[clusterBounds.minLat, clusterBounds.minLng], [clusterBounds.maxLat, clusterBounds.maxLng]])) {
// Yes, visible, so store it
clustersInView.push(allClusters[i]);
}
}
// Now you have all your visible clusters in 'clustersInView'
It is using these Leaflet methods:
getBounds() to get the bounds of the visible part of the map
intersects() to test if the boundaries of a cluster intersect the bounds of the map, i.e. visible or not
And of PruneCluster:
bounds (line 83 in the source code), which contains the min/max coordinates of a cluster
Hope it helps!
I have a Google Map object available on my window object like so:
var map = window.site.map.el;
That Map also also has a bunch of markers placed on it, I'd like to hide a Marker on that Map where the marker's place_id property is equal to "123" for example.
However I don't see a function I can call on the Map class that will return me an array of all markers placed on the map that I can then loop through and hide depending on the marker's place_id.
Google maps does not provide a way to get all Markers, you need to do it yourself
while adding marker to the map keep it in array
var myMarkers = [];
....
for(...) {
var marker = new google.maps.Marker({...});
myMarkers.push(marker);
}
Than you can hide any marker, just by setting map to null
myMarker[i].setMap(null);
Or bring it back
myMarker[i].setMap(map);
Google Maps has a nice feature called Marker Clusterer which lets you to apply grid-based clustering to a collection of markers.
Marker Clusterer counts every marker as one, it sums up the number of markers in the grid. Differently, I want to assign a weight to every marker and sum up these weights in the cluster. Is it possible with Google Maps API? Do you know any other javascript library which provides a similar feature?
It's not as complicated as it seems.
The markerclusterer-library provides the option to override the calculator-function(this is the function that will build the cluster-icons).
Store the weight as a property of the markers, e.g.:
new google.maps.Marker({position:new google.maps.LatLng(1,2),weight:8});
The calculator-function may look like this:
var calc=function(markers, numStyles) {
var weight=0;
for(var i=0;i<markers.length;++i){
weight+=markers[i].weight;
}
return {
text: weight,
index: Math.min(String(weight).length, numStyles)
};
}
To apply this custom function:
initialize the clusterer without markers:
var markerCluster = new MarkerClusterer(map);
set the function
markerCluster.setCalculator(calc);
add the markers:
markerCluster.addMarkers(markers);
Demo: http://jsfiddle.net/doktormolle/H4EJu/
The pitfall: the calculator-function will have to iterate over all markers(by default it doesn't, it only calculates based on the length of the markers-array). This will affect the performance of the MarkerClusterer, especially when you have a lot of markers.
I have a leaflet.js map that has points and linestrings on it that come from an external JSON file.
If I add:
map.setView(new L.LatLng(0,0), 10);
It will centre the map on the latitude and longitude 0,0. How can I set it so the map centre and zoom fit all of the points from the JSON on it?
You could add all of your layers to a FeatureGroup which has a getBounds method. So you should be able to just say myMap.fitBounds(myFeatureGroup.getBounds());
The getBounds method for L.FeatureGroup is only available in the master branch (not the latest version, 0.3.1), for now at least.
Similar case with me. I drawn all the markers from GeoJson data. So I written the function, which gets called repeatedly on button click. Just try if it suits your requirements.
function bestFitZoom()
{
// declaring the group variable
var group = new L.featureGroup;
// map._layers gives all the layers of the map including main container
// so looping in all those layers filtering those having feature
$.each(map._layers, function(ml){
// here we can be more specific to feature for point, line etc.
if(map._layers[].feature)
{
group.addLayer(this)
}
})
map.fitBounds(group.getBounds());
}
The best use of writing this function is that even state of map/markers changed, it will get latest/current state of markers/layers. Whenever this method gets called all the layers will be visible to modest zoom level.
I needed to do this when showing a user directions from his origin to a destination. I store my list of directions in an array of L.LatLng called directionLatLngs then you can simply call
map.fitBounds(directionLatLngs);
This works because map.fitBounds takes a L.LatLngBounds object which is just an array of L.LatLng
http://leafletjs.com/reference.html#latlngbounds
Is there any way to remove the markers that the directions put on the map? I have 4 locations that show on the map. A green arrow where the user is and 3 locations marked A, B, C. If I click on one it routes between the user's location and the marker. The problem is that google adds a new A & B marker to the map as the start and end of the directions. Now I have a couple A and B markers on the map and it's pretty confusing.
Thanks
In the DirectionsRendererOptions set suppressMarkers to true
This is an old post, but I ran on the same issue. I have map with my own markers, I would select few of them and starting point, then I would show directions with markers A, B, C... The problem was how to remove directions and show my markers again.
Here is what worked for me to remove direction paths with markers (A, B, C, etc..).
directionsDisplay.setMap(null);
directionsDisplay = new google.maps.DirectionsRenderer();
directionsDisplay.setMap(map);
RefreshMarkers(); //your function to draw your markers
directionDisplay is declared globally. It's API v3.
Not sure if this is helpful or not. When you create a new GDirection and supply it with a map object, it will automatically draw the polyline to the map as soon as the direction is loaded. This also automatically adds the markers at the start and end of the journey.
I've noticed, however, that if you don't supply the map object initially and instead use the the 'load' event listener to manually add the polyline to the map, you get the line but not the markers.
//Don't supply a map to GDirections()
var direction = new GDirections();
//Make sure {getPolyline:true} is given to the load function
direction.load("here to there", {getPolyline:true});
GEvent.addListener(direction,
"load",
function(){ map.addOverlay(direction.getPolyline()); }
);
This might be easier than finding and removing the markers, especially if you're using the 'load' event listener anyway.
For each marker you want to remove, do
marker.setMap(null);
http://code.google.com/apis/maps/documentation/v3/overlays.html#Markers
Hit menu then layers and on the lower left press clear map. That should clear out everything on the map.
Normally you'd be able to simply do marker.setMap(null), but because the Directions call automatically places the A & B markers on the map, you do not have direct access to them and therefore cannot remove them in this way.