0

I'm using Vue Cesium, and having a bit of trouble getting the desired behavior from the various Vue elements I'm adding to my map. Specifically, I want to get the element's id (created programmatically with v-for) and dispatch an action with it. I can add refs to the element. Is there a way I can programmatically add an onclick action to an element by ref? If there were a more organic way that I can use the Cesium library for this, it would be even better.

Here's the relevant element:

div class="viewer">
            <vc-viewer :terrainExaggeration="100" @ready="ready" :camera="camera">
                <div v-if="billboards.length > 0" v-for="billboard in billboards">
                    <vc-entity :ref="billboard.id" @click="selectCommunity(billboard.id)" :position="billboard.position" :billboard="billboard" :description="billboard.description" :id="billboard.id.toString()"> </vc-entity>
                </div>
                <vc-layer-imagery :alpha="alpha" :brightness="brightness" :contrast="contrast">
                    <vc-provider-imagery-bingmaps :url="url" :bmKey="bmKey" :mapStyle="mapStyle">
                    </vc-provider-imagery-bingmaps>
                </vc-layer-imagery>
            </vc-viewer>
        </div>
Boris K
  • 3,442
  • 9
  • 48
  • 87
  • Would you include a code snippit so we can evaluate the problem? Specifically I'm curious to see how you're creating id's; this isn't a Vue feature. – Chris Camaratta Dec 08 '19 at 22:07
  • @ChrisCamaratta done. The ID comes from the community entities which are coming from my back end. – Boris K Dec 08 '19 at 22:20
  • Is the problem that the `@click="selectCommunity(billboard.id)"` isn't firing? Attaching it to the wrapping `div` instead might work better. – Chris Camaratta Dec 08 '19 at 22:25
  • @ChrisCamaratta no, I tried that, didn't work either. – Boris K Dec 08 '19 at 22:31
  • You can't add a click handler to a custom component unless that component emits its own click events – Stephen Thomas Dec 08 '19 at 22:52
  • 1
    The map and its entities are rendered onto a canvas; they won't fire dom events so adding `@click` isn't the right way to do this. The Cesium equivalent appears to be the "pick" event, which frustratingly doesn't appear to be exposed by VC's `Entity` component. It looks like you might be able to use the [`LEFT_CLICK`](https://zouyaoji.top/vue-cesium/#/en/viewer/vc-viewer) event on the viewer and use it to find the clicked entity, if any, and take it from there. [This SO question](https://stackoverflow.com/q/34220203/1424869) shows an example of locating entities from events on the viewer. – Chris Camaratta Dec 08 '19 at 23:03

2 Answers2

2

The Cesium equivalent to click appears to be the "pick" event, which, frustratingly, doesn't appear to be exposed by the VC API. It looks like you might be able to use the LEFT_CLICK event on the viewer and use it to find the clicked entity. This SO question shows an example of locating entities from events on the viewer.

Taking a stab at a sample impl by combining the two ref's above with your sample, something like this might work:

<template>
    <vc-viewer :terrainExaggeration="100"
               @ready="ready"
               :camera="camera"
               ref="viewer"
               @LEFT_CLICK="onClick"
    >
        <vc-entity v-for="billboard in billboards"
                   :ref="billboard.id"
                   :position="billboard.position"
                   :billboard="billboard"
                   :description="billboard.description"
                   :id="billboard.id.toString()"
        />
        <vc-layer-imagery :alpha="alpha" :brightness="brightness" :contrast="contrast">
            <vc-provider-imagery-bingmaps :url="url" :bmKey="bmKey" :mapStyle="mapStyle">
            </vc-provider-imagery-bingmaps>
        </vc-layer-imagery>
    </vc-viewer>
</template>

<script>
export default {
  // ...ext'g
  methods: {
    // ...ext'g
    onClick (click) {
      const viewer = this.$refs.viewer;
      const pickedObject = viewer.scene.pick(click.position);
      if (Cesium.defined(pickedObject)) {
        const entityId = pickedObject.id._id;
        this.selectCommunity(entityId);
      }
    }
  }
}
</script>


(completely unrelated note: it's not necessary to wrap vc-entity in a div and it might cause unwanted side effects.)

Chris Camaratta
  • 2,729
  • 22
  • 35
0

The answer, thanks to Zouyaoji, appears here: https://github.com/zouyaoji/vue-cesium/issues/41#issuecomment-563029965.

In short, the vc-viewer element has two events that could be used for this: LEFT_CLICK and selectedEntityChanged.

Boris K
  • 3,442
  • 9
  • 48
  • 87