export function processPickInfo()

in modules/core/src/lib/picking/pick-info.js [24:128]


export function processPickInfo({
  pickInfo,
  lastPickedInfo,
  mode,
  layers,
  viewports,
  x,
  y,
  z,
  pixelRatio
}) {
  const {pickedColor, pickedLayer, pickedObjectIndex} = pickInfo;

  const affectedLayers = pickedLayer ? [pickedLayer] : [];

  if (mode === 'hover') {
    // only invoke onHover events if picked object has changed
    const lastPickedObjectIndex = lastPickedInfo.index;
    const lastPickedLayerId = lastPickedInfo.layerId;
    const pickedLayerId = pickedLayer && pickedLayer.props.id;

    // proceed only if picked object changed
    if (pickedLayerId !== lastPickedLayerId || pickedObjectIndex !== lastPickedObjectIndex) {
      if (pickedLayerId !== lastPickedLayerId) {
        // We cannot store a ref to lastPickedLayer in the context because
        // the state of an outdated layer is no longer valid
        // and the props may have changed
        const lastPickedLayer = layers.find(layer => layer.props.id === lastPickedLayerId);
        if (lastPickedLayer) {
          // Let leave event fire before enter event
          affectedLayers.unshift(lastPickedLayer);
        }
      }

      // Update layer manager context
      lastPickedInfo.layerId = pickedLayerId;
      lastPickedInfo.index = pickedObjectIndex;
      lastPickedInfo.info = null;
    }
  }

  const viewport = getViewportFromCoordinates({viewports}); // TODO - add coords
  const coordinate = viewport && viewport.unproject([x - viewport.x, y - viewport.y], {targetZ: z});

  const baseInfo = {
    color: null,
    layer: null,
    index: -1,
    picked: false,
    x,
    y,
    pixel: [x, y],
    coordinate,
    // TODO remove the lngLat prop after compatibility check
    lngLat: coordinate,
    devicePixel: [pickInfo.pickedX, pickInfo.pickedY],
    pixelRatio
  };

  // Use a Map to store all picking infos.
  // The following two forEach loops are the result of
  // https://github.com/visgl/deck.gl/issues/443
  // Please be very careful when changing this pattern
  const infos = new Map();

  // Make sure infos always contain something even if no layer is affected
  infos.set(null, baseInfo);

  affectedLayers.forEach(layer => {
    let info = Object.assign({}, baseInfo);

    if (layer === pickedLayer) {
      info.color = pickedColor;
      info.index = pickedObjectIndex;
      info.picked = true;
    }

    info = getLayerPickingInfo({layer, info, mode});

    if (layer === pickedLayer && mode === 'hover') {
      lastPickedInfo.info = info;
    }

    // This guarantees that there will be only one copy of info for
    // one composite layer
    if (info) {
      infos.set(info.layer.id, info);
    }

    if (mode === 'hover' && layer.props.autoHighlight) {
      const pickingModuleParameters = {
        pickingSelectedColor: pickedLayer === layer ? pickedColor : null
      };
      const {highlightColor} = layer.props;
      if (pickedLayer === layer && typeof highlightColor === 'function') {
        pickingModuleParameters.pickingHighlightColor = highlightColor(info);
      }
      layer.setModuleParameters(pickingModuleParameters);
      // setModuleParameters does not trigger redraw
      layer.setNeedsRedraw();
    }
  });

  return infos;
}