On map using cluster layer to display the marker , on API call loading the data on reload i need to clear clustered marker in the map please help on this issue,normal marker to clear using current method (map.removeObjects(map.getObjects()) it working as excepted but i need remove default cluster marker
Please find the below code :
startClustering(map, data) {
// First we need to create an array of DataPoint objects,
// for the ClusterProvider
// tslint:disable-next-line:ter-prefer-arrow-callback
const dataPoints = data.map(function (item) {
console.log('item>>>>', item);
return new H.clustering.DataPoint(item.y, item.x);
});
const clusteredDataProvider = new H.clustering.Provider(dataPoints, {
clusteringOptions: {
// Maximum radius of the neighbourhood
eps: 1,
// minimum weight of points required to form a cluster
minWeight: 2,
},
});
// Create a layer tha will consume objects from our clustering provider
const clusteringLayer = new H.map.layer.ObjectLayer(clusteredDataProvider);
// To make objects from clustering provder visible,
// we need to add our layer to the map
map.addLayer(clusteringLayer);
}
i need to remove this cluster marker before call this funcation
The easiest approach will be to keep a reference to the cluster layer you wish to remove and then remove it by:
Given a reference called clusteringLayer:
map.removeLayer(clusteringLayer);
The other alternative of using map.getLayers() to retrieve all map layers and removing each layer via map.removerLayer(<layerRef>) might remove layers you do not wish to remove.
Related
I add DataPoints into Provider then into Layer which is bundled into the map.
Later I want to edit some of DataPoints, to do this I need to retrieve layer then provider from the map.
I try it by getting an array of layers but I won't know which one is a layer with my dataPoints.
let clusterDataProvider = new H.clustering.Provider(dataPoints, {
clusteringOptions: {
eps: 16,
minWeight: 2,
strategy: H.clustering.Provider.Strategy.GRID
},
theme: {
getClusterPresentation: this.getClusterPresentation,
getNoisePresentation: this.getNoisePresentation
}
})
}),
let layer = hereMap.getLayers().asArray().find(layer => layer instanceof H.map.layer.ObjectLayer)
if(!layer) {
layer = new H.map.layer.ObjectLayer(clusterDataProvider)
hereMap.addLayer(layer, 0);
}
layer.getProvider()
But ofc there can be a lot of ObjectLayers in my map, so how can I recognize which one is that with clusterDataProvider.
Or anyone has a better idea of how to edit a specific layer or cluster provider?
You can retrieve the layer by utilize this code:
function findClusterLayer(hereMap){
let layer = hereMap.getLayers().asArray().find(layer => {
let isObjLayer = layer instanceof H.map.layer.ObjectLayer;
return isObjLayer && (layer.getProvider() instanceof H.clustering.Provider);
});
return layer;
}
Unfortunately, you can't get dataPoints nor from layer nor from cluster provider, use please workaround like this:
var clusteringLayer = new H.map.layer.ObjectLayer(clusteredDataProvider);
clusteringLayer.$data = dataPoints;
later you can get datapoints like this:
var layer = findClusterLayer(map);
var dataPoints = layer.$data;
after changing some datapoints save it to cluster:
clusteredDataProvider.setDataPoints(dataPoints);
See please complete example
BTW: you can save some object into every datapoint see please documentation on https://developer.here.com/documentation/maps/3.1.20.0/api_reference/H.clustering.DataPoint.html#data
I'm using the aframe-particle-system-component, and was using .setAttribute() on the tick() function to update the particle system in real time, but it performed terribly, leading to almost instant memory-related crashes. Is there a way to directly access the maxAge, opacity, and enabled properties of the system? I'm assuming this is the best way to tackle this as the framework advises that .object3D is directly accessed for performance reasons. I would like to be able to access the particle system in a similar manner. Any help is appreciated.
tldr: here's an example with animated opacity, size, and some toggles. Switching max age seems to wait until all current particles are gone, though no word about it in the docs.
1. Gutting the particle system
The particle system is based on the ShaderParticleEngine, so modyfing it won't be that THREE.js'ish.
From what I can tell, the particle-system creates and stores SPE.Emitter's. You can access them here:
let particleSystem = this.el.component['particle-system']
let emitterGroup = particleSystem.particleGroup.emitters
Changing values - for example, if you have one emitter:
emitterGroup[0].disable() // disables the emitter
emitterGroup[0].opacity.value = 0.1 // sets the opacity
2. A job for a-frame custom components
I'd create a custom component - which will upon any change iterate through the emitter group and change the attributes:
AFRAME.registerComponent('particle-controller', {
schema: {
opacity: {default: 1}
},
init: function() {
let system = this.el.components['particle-system']
this.emitterGroup = system.particleGroup.emitters
},
update: function() {
this.setValueInEmitters(this.emitterGroup, 'opacity', this.data.opacity)
},
// may come in handy when changing more key-value pairs
setValueInEmitters(group, prop, value) {
for (let i = 0; i < group.length; i++) {
group[i].prop.value = value
}
}
})
The schema could be fed with key-value pairs or such to make the component more universal.
3. Why setAttribute is so heavy
Gathering from the source code, any change removes the old particle group and creates a new one from scratch.
In my openlayers 5 (based on a angular 6 app), I am implementing a functionality where you search for something, query the db, the db brings back some geoJSON and I render this geoJSON data in a ol vector layer.
There are two different ways to search, so there are two different forms that bring back geoJSOn to the same ol vector.
Of course, before rendering the data, I have to clear out the layer.
This is my code
ngOnInit() {//initialize some params and the ol map
//bring results-as you type - pure angular
this.results = this.myForm.valueChanges.pipe(
switchMap( formdata => this.mapcmsService.searchName(formdata.name, formdata.cepDrop))
);//pipe
this.tilesource = new OlXYZ({
url:'http://tile.stamen.com/terrain/{z}/{x}/{y}.jpg'
});
this.tilelayer = new OlTileLayer({
source: this.tilesource
});
this.vectorsource = new VectorSource({});
this.vectorlayer = new VectorLayer({
source: this.vectorsource
});
this.view = new OlView({
center: OlProj.fromLonLat([6.661594, 50.433237]),
zoom: 2,
});
this.olmap = new OlMap({
target: 'map',
layers: [this.tilelayer,this.vectorlayer],
view: this.view,
projection: 'EPSG:3857'
});
const selectClick = new Select({
condition: click,
layers:[this.vectorlayer]
});
this.olmap.addInteraction(selectClick);
selectClick.on(
'select', ()=>{
const values = selectClick.getFeatures().item(0).values_;
this.getDetails(values.id);
}
);
} //closes ngOnInit
Outside the ngOnInit, after the initialization,there are the two different functions that bring geoJSON to the same ol vector layer. They basically do the same thing.
searchById(id){
this.map_loading = true;
this.myService.getById(id).subscribe((data) =>{
this.vectorsource.refresh();
this.vectorsource.clear();
const fff = (new GeoJSON()).readFeatures(data.data);
this.vectorsource.addFeatures(fff);
this.map_loading = false;
})
}//searchById
and
searchCategories(){
this.map_loading = true;
this.myService.categoriesSearch(this.categoriesForm.value).subscribe((data) =>{
this.vectorsource.refresh();
this.vectorsource.clear();
const fff = (new GeoJSON()).readFeatures(data.data);
this.vectorsource.addFeatures(fff);
this.map_loading = false;
})
}//searchCategories
The problem is that the ol vector source is not always cleared before new features are added. I search for something, features are rendered. I search again , and sometimes, the old features remain on the map, along with the new ones.
I did a silly move to add refresh with clean and nothing is fixed. This is not standard, eg every other search. This randomly happen and I dont have a clue how to debug it. Please advice
Thanks
Is there an unique id for each feature?
I had the same problem that features were loaded constantly. I used the bbox-strategy and every time I moved the map, it loaded all the features in the extent, even if they were already there.
I had to set an unique id in the data for my features, so OpenLayers can refer to the existing ones if you load new ones. This randomness maybe comes through the generated ids for the features, that are sometimes equal to the new ones and sometimes not.
Dont know if that faces your problem, it just flew into my brain while I read that.
I show a map of a specific location, with points of interest pinned on the map. This is already accomplished...
What I am looking to do is to add the following functionality:
If the user is located WITHIN the existing bounds of this map, show the users current location zoomed in at 10 with these pins in place. If the user is NOT within the bounds of the map, just show the map with the points of interest pins.
I have included a portion of my code that will either show the users location, regardless of the existing bounds of the map OR show just the bounds without a users location. you will see that i have been playing around with the functionality and getting nowhere.
GeoMarker = new GeolocationMarker();
GeoMarker.setCircleOptions({fillColor: '#808080',fillOpacity:0.0,strokeOpacity:0.0});
google.maps.event.addListenerOnce(GeoMarker, 'position_changed', function() {
map.setCenter(this.getPosition());
//map.fitBounds(this.getBounds()); //uncomment to show based on user location regardless of the exsisting bounds of the map
//map.fitBounds(bounds); //uncomment to show ALL the listing Markers within the bounds of the map and not location of the user
//if (map.getZoom() > 1) map.setZoom(13); //this zoom is based on user location
// map.setCenter(this.getPosition());
var listener = google.maps.event.addListener(map, "idle", function() {
google.maps.event.removeListener(listener);
});
});
google.maps.event.addListener(GeoMarker, 'geolocation_error', function(e) {
alert('There was an error obtaining your position. Message: ' + e.message);
});
GeoMarker.setMap(map);
}
I'm not sure, if I understood your problem correctly, but you can obtain the bounds of your current viewport via google.maps.Map.getBounds() which returns a google.maps.LatLngBounds object. On this call the contains()-method passing the coordinates of your user to check if your user is within the bounds or not.
I want to remove an individual marker from Google map. I am using version 3 API. I know how I can remove all the markers by maintaining a markerArray and setting map null for all.
For removing one by one, I am thinking to make a key value pair combination. So that I give a key and remove the particular marker. I need help over this.
Following is the code, that I use to dram marker:
function geoCodeAddresses(data) {
var markerInfo = {addressKey: '', marker:''};
for (var i = 0; i < data.length; i++) {
myLocation = data[i];
geocoder.geocode({"address":myLocation}, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results[0].geometry.location);
var marker = new google.maps.Marker({map:map, position:results[0].geometry.location});
// checkpoint A
alert(myLocation);
/*
markerInfo.addressKey = myLocation;
markerInfo.marker = marker;*/
//mArray.push(markerInfo);
}
});
}
}
I will search for addresskey and remove the marker from mArray. But I get last value every time in geocode callback method. And one object got pushed every time. the var myLocation always give me the address of the last index of my array. If I alert it at check point A.
My approach is right?
Your problem is this line:
mArray.push(markerInfo);
That doesn't push the values of markerInfo into your array. It pushes a reference to markerInfo into your array. Now, on your next iteration of the loop, when you change the value of markerInfo, it changes the value pointed at by the references in the array too. So your array ends up having elements that all have the same value.
Try this instead:
mArray.push({addressKey:myLocation,marker:marker});
If that doesn't work, then this:
mArray.push({addressKey:data[i],marker:marker});