跳至内容

useSceneDrillPick ​

响应式封装 Cesium.Scene.drillPick:根据屏幕坐标穿透拾取重叠的全部对象,返回结果数组的响应式引用。适用于重叠图形需要“先拾取、再从列表选择目标”的场景;与仅取最上层的 useScenePick 互补。

Usage ​

vue
<script setup lang="ts">
import * as Cesium from 'cesium';
import { useEntity, useSceneDrillPick, useScreenSpaceEventHandler, useViewer } from 'vesium';
import { computed, shallowRef, watchEffect } from 'vue';

const cursorPosition = shallowRef<Cesium.Cartesian2>();

// track mouse move
useScreenSpaceEventHandler(Cesium.ScreenSpaceEventType.MOUSE_MOVE, (movement: { endPosition: Cesium.Cartesian2 }) => {
  cursorPosition.value = movement.endPosition.clone();
});

// use scene drill pick to pick multiple objects at cursor
const drillPick = useSceneDrillPick(cursorPosition, {
  width: 5,
  height: 5,
  limit: 10,
});

// show all picked objects
const pickInfo = computed(() => {
  if (!drillPick.value || drillPick.value.length === 0) {
    return 'No object picked';
  }
  const names = drillPick.value.map((item: any, index: number) => {
    if (item.id instanceof Cesium.Entity) {
      return `${index + 1}. Entity: ${item.id.name || 'unnamed'}`;
    }
    if (item.primitive) {
      return `${index + 1}. Primitive: ${item.primitive.id?.name || 'unnamed'}`;
    }
    return `${index + 1}. Unknown`;
  });
  return names.join('\n');
});

// three boxes stacked at the same ground position — hover the center to drill all layers
const entities = useEntity([
  new Cesium.Entity({
    name: 'Layer 1 - Red',
    position: Cesium.Cartesian3.fromDegrees(120, 30, 500),
    box: {
      dimensions: new Cesium.Cartesian3(4000, 4000, 1000),
      material: new Cesium.ColorMaterialProperty(Cesium.Color.RED.withAlpha(0.6)),
    },
  }),
  new Cesium.Entity({
    name: 'Layer 2 - Green',
    position: Cesium.Cartesian3.fromDegrees(120, 30, 1200),
    box: {
      dimensions: new Cesium.Cartesian3(2600, 2600, 800),
      material: new Cesium.ColorMaterialProperty(Cesium.Color.GREEN.withAlpha(0.6)),
    },
  }),
  new Cesium.Entity({
    name: 'Layer 3 - Blue',
    position: Cesium.Cartesian3.fromDegrees(120, 30, 1800),
    box: {
      dimensions: new Cesium.Cartesian3(1400, 1400, 600),
      material: new Cesium.ColorMaterialProperty(Cesium.Color.BLUE.withAlpha(0.6)),
    },
  }),
]);

const viewer = useViewer();
watchEffect(() => {
  if (viewer.value && entities.value) {
    viewer.value.flyTo(entities.value, { duration: 1 });
  }
});
</script>

<template>
  <div class="text-12px p-10px whitespace-pre-wrap">
    {{ pickInfo }}
  </div>
</template>
ts
import * as Cesium from 'cesium';
import { useSceneDrillPick, useScreenSpaceEventHandler } from 'vesium';
import { shallowRef } from 'vue';

const cursorPosition = shallowRef<Cesium.Cartesian2>();
useScreenSpaceEventHandler(Cesium.ScreenSpaceEventType.MOUSE_MOVE, (m) => {
  cursorPosition.value = m.endPosition.clone();
});
const picks = useSceneDrillPick(cursorPosition, { limit: 10 }); // 最多 10 个,可降低开销
picks.value?.forEach((item, index) => {
  console.log(`${index + 1}.`, item.id.name);
});

配置项 ​

  • isActive - 是否激活拾取,默认 true;为 false 时结果重置为 undefined,支持 ref/getter。
  • throttled - 坐标变化的节流采样间隔(毫秒),默认 8。
  • limit - 最多收集的结果数量,透传给 scene.drillPick;不传返回全部命中对象,传较小值可降低开销。
  • width / height - 拾取矩形宽高,默认 3。

返回值 ​

  • 返回 ComputedRef<any[] | undefined>:拾取结果数组,元素含 id、primitive 等字段(对应 scene.drillPick 返回项);无命中或条件不满足时为 undefined。

注意事项 ​

  • drillPick 单次开销大于 pick,请配合 throttled 节流和 limit 限制数量。
  • viewer 不存在、位置为空或 isActive 为 false 时,结果重置为 undefined。

Type Definitions ​

typescript
import type { Cartesian2 } from 'cesium';
import type { ComputedRef, MaybeRefOrGetter } from 'vue';
export interface UseSceneDrillPickOptions {
    /**
     * Whether to activate the pick function.
     * @default true
     */
    isActive?: MaybeRefOrGetter<boolean | undefined>;
    /**
     * Throttled sampling (ms)
     * @default 8
     */
    throttled?: number;
    /**
     * If supplied, stop drilling after collecting this many picks.
     */
    limit?: MaybeRefOrGetter<number | undefined>;
    /**
     * The width of the pick rectangle.
     * @default 3
     */
    width?: MaybeRefOrGetter<number | undefined>;
    /**
     * The height of the pick rectangle.
     * @default 3
     */
    height?: MaybeRefOrGetter<number | undefined>;
}
/**
 * Uses the `scene.drillPick` function to perform screen point picking,
 * return a computed property containing the pick result, or undefined if no object is picked.
 *
 * @param windowPosition The screen coordinates of the pick point.
 */
export declare function useSceneDrillPick(windowPosition: MaybeRefOrGetter<Cartesian2 | undefined>, options?: UseSceneDrillPickOptions): ComputedRef<any[] | undefined>;