Strange behaviour when updating a Graphic

946
8
10-18-2018 03:04 AM
MatthieuThery1
Occasional Contributor

Hello,

I am trying to add a graphic on the map and update its angle/position based on a property received from an API (google streetview).

I am creating a GraphicsLayer that I add to the map, I then add a Graphic with the initial position/angle returned by the API. That's working fine.

I then wanted to update the graphic's position for when the user moves in the streetview window. As it's not possible yet to update a graphic (api 4.9) , I remove the graphic from the layer, change its geometry and add it back. Working fine too.

Now I want to modify the angle of the graphic, I am using the same process, it's successfully changing the angle of the newly added graphic, and removing the old one from the layer, but they all seem to stay "floating "on the map somehow.

Below is the code: (I also tried to create a brand new Graphic instead of cloning, same behaviour)

function setAngle(graphic, newHeading){
   graphicsLayerMap.remove(graphic); // tried removeAll()
   currentPointer = graphic.clone();
   currentPointer.symbol.angle = newHeading
   graphicsLayerMap.add(currentPointer);
}
panorama.addListener('pov_changed', function() {
   if(currentPointer != null){
      const newHeading = panorama.getPov().heading;
      setAngle(currentPointer, newHeading)
   }
});

And the result (in blue the rogue graphics, and in red the correct one within the layer):

 

If anyone can help me make sense of that.

0 Kudos
8 Replies
RobertScheitlin__GISP
MVP Emeritus

Matthieu,

   Using removeAll() clears all graphics from the GL. You are not adding the graphic to another layer like the view.graphics are you?

function setAngle(graphic, newHeading){
   graphicsLayerMap.removeAll();
   currentPointer = graphic.clone();
   currentPointer.symbol.angle = newHeading
   graphicsLayerMap.add(currentPointer);
}
panorama.addListener('pov_changed', function() {
   if(currentPointer != null){
      const newHeading = panorama.getPov().heading;
      setAngle(currentPointer, newHeading)
   }
});
0 Kudos
MatthieuThery1
Occasional Contributor

Hi,

RemoveAll() is "not working", as in it's removing the graphics from the layer as expected. When I view the graphicsLayer it only has 1 item, the correct one.

However intermediate graphics are still showing on the map, and I can't see on which layer they are.. I am not using view.graphics (although I tried that too, instead of the graphics layer, and had the same problem)

Strange thing is when I do the change position bit, it's working ok. It really looks like the issue is the "speed rate" at which the setAngle is called: 

function move(graphic, geometry){
   var point = new Point({x:geometry.lng, y:geometry.lat})
   graphicsLayerMap.removeAll();
   currentPointer = graphic.clone();
   currentPointer.geometry = point;
   graphicsLayerMap.add(currentPointer);
}
panorama.addListener('position_changed', function() {
   if(currentPointer != null){
      const newPosition = panorama.getPosition();
      var unit = {lat: newPosition.lat(), lng: newPosition.lng()};
      move(currentPointer, unit)
   }
});
0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Have you tried to go back to 4.8 and see if this is a 4.9 issue?

0 Kudos
MatthieuThery1
Occasional Contributor

I haven't tested on 4.8 yet.

I found a workaround though, if I set a time constraint on the setAngle function, this works fine. Apparently when things are going too fast, the graphicsLayer fails to clear the graphics, and they stay in memory somewhere. This is working:

panorama.addListener('pov_changed', function(e) {
   if(currentPointer != null){
      const newHeading = panorama.getPov().heading;
      var d = new Date().getTime();
      if(storedDate == null || d - storedDate > 200 ){
         storedDate = d;
         setAngle(currentPointer, newHeading)
      }
   }
});
ReneRubalcava
Frequent Contributor

It's not necessary clone the graphic anymore, you can update the symbol of the graphic directly now in GraphicsLayer. You may need to clone the symbol and update the color of the cloned symbol and assign it to the graphic, but no need to clone the whole graphic in this case.

I think another issue with the layer refresh means the change may not be seen until you zoom in and out, but not sure. That should be fixed in 4.10.

MatthieuThery1
Occasional Contributor

Yes I tried that, and yes you can't see the changes until you zoom in/out, which is not great for what I was trying to achieve. Anyway good to know that , this will be the case in 4.10.

0 Kudos
BlakeTerhune
MVP Regular Contributor

Rene Rubalcava Which version of the API allows you to update the symbol of the graphic directly?

0 Kudos
ReneRubalcava
Frequent Contributor

I want to say for 2D, this worked at 4.7, but not sure. In 3D this has worked for a while without clone.

0 Kudos