I'm using JavaScript API 4.5 and my application is using webmap. I want to highlight the feature that the user clicks on (polygon) and clear the current one and highlight the new one every time the user clicks on a new feature.
I created a GraphicsLayer for it and use removeall() to remove all the graphics before draw the new one. This works fine until I zoom the map. When I zoom the map all the graphics come back and I can't figure out where they are stored. I checked the graphics layer and there is always one graphic in it which is the most recent selected feature.
highlightFeature(graphic) {
let theComponent = this;
let graphicsLayerMap;
theComponent.mapService.webMaps[theComponent.mapService.currentMap].layers.items.forEach(function(layer){
if (layer.type === 'graphics') {
graphicsLayerMap = layer;
}
});
// SimpleFillSymbolProperties only necessary because of tight coupling of object types. Normally outside of Angular/Webpack we wouldn't need a fake SimpleFillSymbolProperties class
let symbolProps = new SimpleFillSymbolProperties({
style: 'none',
outline: {
width: 2,
color: [0, 197, 255, 1]
}
});
let highlightSymbol = new SimpleFillSymbol(symbolProps);
graphic.symbol = highlightSymbol;
if (graphicsLayerMap !== undefined) {
// not the first time click on the map
graphicsLayerMap.removeAll();
graphicsLayerMap.add(graphic);
} else {
// if this is the first click on this map, add a graphicsLayer to the map
// add graphic to GraphicsLayer
let graphicsLayer = new GraphicsLayer({
graphics: [graphic],
listMode: 'hide'
});
this.mapService.webMaps[this.mapService.currentMap].layers.add(graphicsLayer);
}
}
Any help would be appreciated!
I figured this one out. The graphic parameter that's passing in is a Graphic. In 4.x, it has a property - layer which is "references the layer in which the graphic is stored." and this is the layer that I'm clicking on. So I guess it adds the graphic to the layer that I click on. I also add it to the GraphicsLayer and I'm clearing it every time I click on the map. So there are two graphics I think.
The solution is to just pass in the geometry of the graphic and create a Graphic in highlightFeature(). Then add the new graphic to the GraphicsLayer. !
highlightFeature(geometry) {
let theComponent = this;
let firstClick = true;
// SimpleFillSymbolProperties only necessary because of tight coupling of object types. Normally outside of Angular/Webpack we wouldn't need a fake SimpleFillSymbolProperties class
let symbolProps = new SimpleFillSymbolProperties({
style: 'none',
outline: {
width: 2,
color: [0, 197, 255, 1]
}
});
let highlightSymbol = new SimpleFillSymbol(symbolProps);
// Create a graphic and add the geometry and symbol to it
let graphic = new Graphic({
geometry: geometry,
symbol: highlightSymbol
});
// check to see if the graphics layer exists already
theComponent.mapService.webMaps[theComponent.mapService.currentMap].layers.items.forEach(function(layer){
if (layer.type === 'graphics') {
layer.removeAll();
layer.add(graphic);
firstClick = false;
}
});
if (firstClick) {
// first time click on this webmap
// add graphiclayer to the webmap
let graphicsLayerMap = new GraphicsLayer({
listMode: 'hide'
});
theComponent.mapService.webMaps[this.mapService.currentMap].layers.add(graphicsLayerMap);
// add graphic to the graphicslayer
graphicsLayerMap.add(graphic);
}
}