I create 100 markers on a map.
As each marker may not be visible depending on 5 boolean variables, I want each marker to be embedded in a layer: 1marker = 1 layer.
The 5 conditions are in an L.control with 5 checkboxes.
Initially, all are displayed and depending on the conditions the markers
singlemarker = [];
ListLayers = [];
// loop on the 100 markers from my database
// marker is set by the database
Object.entries(data.themes).forEach(theme => {
var marker = L.marker([Latm, Lngm],{icon: ChxIcon});
singlemarker.push(marker);
ListLayers.push(new L.layerGroup(singlemarker).addTo(map));
singlemarker = [];
})
console.log(ListeLayers.length) //I obtain 100
map.removelayer(ListLayers[0]); //-> not working
Does anyone have a clue to try to solve this problem?
With many thanks
Cordially
Jean Michel
Related
How to make infinite scrolling in both directions, up and down. I am using the InfiniteLoader and the List, both are react-virtualized components. I have a list of timestamps with initial date-time range. From there the list should be infinite in both directions. Currently, scroll-down to the bottom of the List will trigger the function _loadMoreRows(). However, I would like to trigger the _loadMoreRows() with the same functionality when scrolling in the direction up.
I have it working now :) Everything is fine. The threshold prop of the <InfiniteLoader> defines the threshold number of indices before the start/end of the List when to prefetch data, i.e. trigger _loadMoreRows().
The first and the last item in this.state.items should have their corresponding loadedRowsMap set to undefined after the initial data fetch.
const items = _getItems(); // fetch items
const rowCount = items.length;
const loadedRowsMap = [];
_.map(this.state.loadedRowsMap,(row,index)=>{
const status = (index===0 || index===rowCount-1) ? undefined : STATUS_LOADED;
loadedRowsMap.push(status)});
scrollToIndex = parseInt(rowCount/2,10);
this.setState({
items, rowCount, loadedRowsMap, scrollToIndex,
});
Before displaying the list, a scrollToIndex prop of the <List> component should be set to the middle of the list, i.e. rowCount/2. This number should satisfy the equation
0 + threshold < scrollToIndex < rowCount - 1 - threshold.
Function _isRowLoaded() will check loadedRowsMap[index]. If it is set to STATUS_LOADED or STATUS_LOADING (internal constants used inside the InfiniteLoader) it will not trigger _loadMoreRows(). If it is set to undefined, then it will trigger _loadMoreRows().
With this setup, trigering _loadMoreRows() works in both scroll directions, up and down.
There is an example of the heatmap https://www.mapbox.com/mapbox-gl-js/example/heatmap/ by the number of markers/points on the area. But is there a way to display a heatmap by average pins/markers values? For example if I have 5 pins and their average prop value speed=3 then it will be shown as green cluster/heatmap and if their av. prop val is 6 then it will be red cluster/heatmap.
I found that "clusterAggregates" property can help, but can't find any example of using it.
Thanks
I'll leave my way to do so. Old question, which is sometimes risen, but there are no nice sollution, so... Turf's hexgrid (http://turfjs.org/docs/#hexGrid) can help:
const hexagons = hexGrid(bbox, size);
const collection = // collection of your points;
const hexagonsWithin = collect(hexagons, collection, "propertyToAgretateFrom", "propertyToAggregateIn");
const notEmptyHexagonValues = hexagonsWithin.features.filter(({ properties }) => properties.propertyToAggregateIn.length !== 0);
const notEmptyHexagons = {
"type": "FeatureCollection",
"features": notEmptyHexagonValues,
};
// at this point you're having not empty hexagons as a geojson, which you can add to the map
collect is another method from turf, whatcollection should be you can look up in the docs, because it's changing a lot.
The general idea behind is to "divide" visible part of map (bbox) into hexagons by hexGrid method and and aggregate some properties that you need from every marker inside of every hexagon you'll have into the array, so you can get an average value, for example. And assign a color based on it.
Let's say we have feature.properties.propertyToAgretateFrom as 4 and 5 in two markers. After the aggregation, if these markers were inside one polygon, you'll have it feature.properties.propertyToAggregateIn: [4, 5] - this feature is polygon. From this on you can do pretty much everything you want.
How can i hide text of small slices in pie chart without to remove the text from the legend in the bottom?
I tried to remove the text like this:
if ((yVal < 5F) {
name = "";
} else {
//Add to y values
}
But then the legent text is empty also. so the users can't really know who is this slice.
My solution is to separate the legend texts and the pie chart slices text.
I set the legend (bottom map for each color) text and colors in this way
- In loop for all the contacts:
List<Integer> colors = new ArrayList<>();
List<String> labels = new ArrayList<>();
labels.add(fullName);
colors.add(METRIC_COLORS[index]);
Legend l = chart.getLegend();
l.setCustom(colors, labels);
In addition I added the text of pie-slices:
PieDataSet dataSet = new PieDataSet(yVals1, "");
dataSet.setColors(METRIC_COLORS);
I have a situation like this:
for (PieEntry pieEntry : leastPieEntries){
if(pieEntry.getValue() < 10)
{
pieEntry.setLabel("");
}
}
Tried to loop through all PieEntries but getValue returns the float value instead of percentage value...how did you do it?
I am trying to add some 2500 icons (2 Kb each) to a leaflet map. Filling the array is no problem. Adding the layer group to the map, however, takes between 2 and 5 seconds. Any suggestion how to improve the performance?
var icongroup = [];
for (id in reclist) {
var recname = reclist[id][0];
var posn = reclist[id][1];
var pose = reclist[id][2];
var mapicon = L.icon({iconUrl: icon, iconSize: [26, 29]});
icongroup.push(L.marker([posn, pose], {icon: mapicon}));
}
L.layerGroup(icongroup).addTo(map);
Adding thousands of markers to the page stresses the browser ressources for sure. There is a high chance this is the reason for your delay.
You should consider replacing your markers by a canvas, or clustering them.
See also: Plotting 140K points in leafletjs
I am not sure what the exact technical term for this question would be so please pardon the noobish question.
I have a leaflet map like this:
var map = L.map("dvMapContainer",
{
}).setView([39.782388193, -86.14135265], 14);
I am adding a marker to this map like this:
var vehicleMarker = new L.Marker([39.782388193, -86.14135265], { id: 'vehicle', icon: cssIcon });
map.addLayer(vehicleMarker);
Every few seconds, I update the position of the vehicleMarker and center the map
vehicleMarker.setLatLng(newLatLng);
map.setView(newLatLng, 18);
This works fine however the effect is not very visually pleasing as the map is constantly moving. I would like to move only the marker until it gets close to the edge of the map and then recenter the map. Is that possible ? Any hints/solutions will be much appreciated.
Each time you check (every few seconds), you can compare your marker location with the map bounds:
var bounds = map.getBounds();
if(vehicleMarker.getLatLng().lng > bounds.getEast()-.001 || vehicleMarker.getLatLng().lng < bounds.getWest()+.001 || vehicleMarker.getLatLng().lat > bounds.getNorth()-.001 || vehicleMarker.getLatLng().lat < bounds.getSouth()+.001)
//change bounds
If your next marker location is close to your current bounds, then change your map's current bounds.
You can change the .001 depending on how far zoomed out you are.
More info on bounds here: http://leafletjs.com/reference.html#latlngbounds