Cannot make Polyline dynamically attach and move between two point entities

1. A concise explanation of the problem you're experiencing.
I'm trying to attach a poly line to two point entities and make it so that if i move a point, it will automatically move the polyline as well.

I was thinking i could possibly use Cesium.ReferenceProperty because i was able to make a single point attach to another point and move along with it, but i couldn't get it to work with polyline... maybe there's a better way

2. A minimal code example. If you've found a bug, this helps us reproduce and repair it.
var vm = {};
vm.viewer = new Cesium.Viewer('cesiumContainer');
var scene = vm.viewer.scene;

function disableCameraMotion(state){
    vm.viewer.scene.screenSpaceCameraController.enableRotate = state;
    vm.viewer.scene.screenSpaceCameraController.enableZoom = state;
    vm.viewer.scene.screenSpaceCameraController.enableLook = state;
    vm.viewer.scene.screenSpaceCameraController.enableTilt = state;
    vm.viewer.scene.screenSpaceCameraController.enableTranslate = state;
}

var position = Cesium.Cartesian3.fromDegrees(-115.0, 37.0);
var positionCBP = function(){
  return position;
};

var position = Cesium.Cartesian3.fromDegrees(-115.0, 37.0);
var positionCBP = function(){
return position;
};

var myEllipse = vm.viewer.entities.add({
  id: 'ID1',
  name : 'Red Ellipse on surface',
  position: new Cesium.CallbackProperty(positionCBP, false),
  point: {
    pixelSize: 30,
    color: Cesium.Color.RED,
    outlineColor: Cesium.Color.BLACK,
    outlineWidth: 1.5
  }
});

var myEllipse2 = vm.viewer.entities.add({
  id: 'ID2',
  name : 'Red Ellipse on surface',
  position: Cesium.Cartesian3.fromDegrees(-114.0, 36.0),
  point: {
    pixelSize: 30,
    color: Cesium.Color.RED,
    outlineColor: Cesium.Color.BLACK,
    outlineWidth: 1.5
  }
});

// i get a rendering error if i try to do this, i think it doesn't like ReferenceProperty, and/or PositionPropertyArray
var myLeg = vm.viewer.entities.add({
  polyline: {
    positions: new Cesium.PositionPropertyArray([
      new Cesium.ReferenceProperty(vm.viewer.entities, 'ID1', [ 'position' ] ),
      new Cesium.ReferenceProperty(vm.viewer.entities, 'ID2', [ 'position' ] )
      ]),
      width: 5,
      material: new Cesium.PolylineOutlineMaterialProperty({
      color: Cesium.Color.RED,
      outlineColor: Cesium.Color.BLACK,
      outlineWidth: 2.5
    })
  }
});

// Using this for mouse click and drag movement
var handler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
      
handler.setInputAction(function(click) {
  var pickedObject = scene.pick(click.position);
  if (Cesium.defined(pickedObject) && pickedObject.id === myEllipse){
    vm.picked = true;
    disableCameraMotion(false);
    console.log('here');
  }
}, Cesium.ScreenSpaceEventType.LEFT_DOWN);

handler.setInputAction(function(movement) {
  if (!vm.picked){
    return;
  }
  position = vm.viewer.camera.pickEllipsoid(movement.endPosition,
  scene.globe.ellipsoid);
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

handler.setInputAction(function(movement) {
  // if picked
  vm.picked = false;
  disableCameraMotion(true);
}, Cesium.ScreenSpaceEventType.LEFT_UP);

// What's strange is ReferenceProperty works for position on a point entity.... when i move my first entity, it moves this new object as well
var object2 = new Cesium.Entity({id:'object2', point: {
  pixelSize: 10,
  color: Cesium.Color.GREEN,
  outlineColor: Cesium.Color.BLACK,
  outlineWidth: 1.5
}});
object2.model = new Cesium.ModelGraphics();
object2.position = new Cesium.ReferenceProperty(vm.viewer.entities, 'ID1', ['position']);
vm.viewer.entities.add(object2);

3. Context. Why do you need to do this? We might know a better way to accomplish your goal.

I need to be able to move, edit, or add points that connect polylines. e.g. A polyline is in between two point entities. If i click and drag a point on one end to move it, i want that poly line to update with it.

4. The Cesium version you're using, your operating system and browser.
Windows 10
Chrome
Cesium 1.50

Does anyone know if its possible to achieve what I need to do?

Polyline positions can be defined using an array of references, and this loads and renders with no issues.

See this sandcastle code that renders as expected:

https://cesiumjs.org/Cesium/Build/Apps/Sandcastle/#c=zVTRbpswFP2VK14gEjMhWTaJ0Whd0odpnVpl0vZQ+uDCTWvN2Mg2yVjVf5/BkKRZ1VV9mnjhHp9zfH2uYUMVbBhuUcEJCNzCAjWrS/K9wwI/78qFFIYygcoffchE+2ysDoVhpomt0DmQDmCoCS2K4D4TAKxIwP+8jP2wrQQtESywwgLOOGeVRpACdK3WNEfHqaS2HlIkMLSyoMrYNyqmZK1kucRbhaiDN3E8I+MQpu/JeNRLmTAJdBvbiv1C/o39xgSm49BhueRSJTvjtiKrs2W/KmvD7SEXT5A+nZ8uvjym/WCFuUsgJrMWfsjEg8tmn8zkBclMXpPMP4N52wXz7v8Lpl1/LpVK8qbl7JvtD62Tw9t52aOXSlaoTHOqFG2CKyeBQ+YK16hQ5DhQg6O9w/5+whX4w2Y+XMMofLXb5Am3wex677t1Oc12QEkNKkb50VFdIhcu3K89Z9fA/aB+foQvHuLxGCdujHaQo8NxeqGXatNwnLvVj6yspDJQKx4QEhksK25b1dFNnf9EQ3KtW1kaDaK0YBv7EZxk3tEvJvMg51Rru7KueXdRM2+eRpb/SMYlLZi4vdig4rRpKXfx/NyBhJA0suXfKiMlv6HqwPEP

This also works with a time-varying position, and the line updates as expected:

https://cesiumjs.org/Cesium/Build/Apps/Sandcastle/#c=zVRdT9swFP0rVl+SSiFtUmCsK2is7QOjVau22zRRhExyCxauHdlOWYf47/NH+hUqQDztLbn33ON7z7n2AgukyBwidIraIEk+D7/nlGDWwQrCmeDzC8lPjuuR78X16PNBvXEQxV71y5Qtisp4byVO0zEknKXSt/QBOq4HiMHjS6xfNXSOMKE8edCEW8C2CflPU4YQkgoLNdF8qOm6Dmw4yYUAtichFc+2onEBN4wjzO5MfPsUGwt7g8HwZjwZDLfQYwVZCWxC4fj3eNLt37R7g/blTf9Hb3Ix7F10R65ynlNFMkpA6NLDoqN7ntP0nJG5nty0JXKYsmengNNgQeBRl+yI8NPGfC+xv23OFCYMhBcgJ4zr0qD6PAWqicsKrnO+hVZLh0o8zyikQy6JIpztnj7eTQ4Fz0CopW8ISoXWeBta+b5qQjunvzBr2K3qwJ0AkP5BFB2FejMan8J69W2++B18x5bvpOBz4+ntIGppltypG9oAAWn43XKRtIm8i07kWaMYtlvjjSBFXUpJJgFpWWQuZjgBh8mKHptl9YosYaq58icjf4COyV9ookY9KDzjlIvNUpm/cNTtFFmeK6o9bu8Bfeudty93Yb9Iqu6bKAqPTPh57e5m+Pgdw8cfGf5NQw6tIdqW6n8mjMm/pkrG6dJgNs0WQ8ud+1W+F+dC4KV/5UrQNnIEM9AvVQLrK1Q6OyhWEF0hb3WYh65RNfgwW7yHbUV2veF9dDodrQPmgRIE09KoTpGBE7dfYNYNPK2qX7fw3SaWbYydjdrI6radlaDSkmpJ4cxlv5J5xoVCuaB+GNYU6OupW5W12zx5ABUmUpqyVm1V1ErJQl+C02ml9MJOK/ppxVLqzCyndlGnlbNWTeN3yijHKWF3gwUIipcGch+d9VwwDMNWTf++rFKc01ssthj/AQ

Hey Scott, thanks for looking into this! The sandcastle made me realize that may be there's an issue with the way I'm trying to make the mouse click and drag to move work instead. I can't seem to implement the click and drag correctly without the rendering issue (instead of time-varying)

I have it partially working by updating the entity position in my MOUSE_MOVE method, but now I can't seem to get the line to continuously draw, it disappears when I move the point and reappears when I let go.

I don’t know if this is for sure the issue without seeing a Sandcastle of your code, but I’m guessing what you’re seeing when it disappears and re-appears is because entities in Cesium are asynchronously created. I have a longer explanation of this and how to override it here:

https://groups.google.com/d/msg/cesium-dev/5N1P_qPmbPo/rbnHNKFoAQAJ

A dynamic property like the CallbackProperty will also mark an entity as dynamic. This is why the drawing on terrain example updates correctly (except when you finish drawing, it’ll disappear for a few seconds, that’s when it recreates the object as static)

Hi there Omar!
I almost forgot that I could share the Sandcastle project!

Here is what I have so far, you'll notice that if I move a point, the line disappears like you mentioned. What I'm trying to do is a little different from creating a new polyline. I wonder if theres any way I could make it dynamic as well?

You can indeed! Instead of changing its position directly, save its position in a property on the object, maybe like:

focused.savedPosition =

``

And then create a CallbackProperty for the entity’s position:

This marks it as dynamic. The callback property can then simply return the object’s saved position.

2 Likes

That solution worked perfectly. Thanks for all the help!