(self["webpackChunk_vaadin_bundles"] = self["webpackChunk_vaadin_bundles"] || []).push([["vendors-node_modules_vaadin_map_node_modules_ol_interaction_Extent_js"],{

/***/ "./node_modules/@vaadin/map/node_modules/ol/interaction/Extent.js":
/*!************************************************************************!*\
  !*** ./node_modules/@vaadin/map/node_modules/ol/interaction/Extent.js ***!
  \************************************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "ExtentEvent": () => (/* binding */ ExtentEvent),
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _Feature_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../Feature.js */ "./node_modules/@vaadin/map/node_modules/ol/Feature.js");
/* harmony import */ var _MapBrowserEventType_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../MapBrowserEventType.js */ "./node_modules/@vaadin/map/node_modules/ol/MapBrowserEventType.js");
/* harmony import */ var _coordinate_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../coordinate.js */ "./node_modules/@vaadin/map/node_modules/ol/coordinate.js");
/* harmony import */ var _events_Event_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../events/Event.js */ "./node_modules/@vaadin/map/node_modules/ol/events/Event.js");
/* harmony import */ var _events_condition_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../events/condition.js */ "./node_modules/@vaadin/map/node_modules/ol/events/condition.js");
/* harmony import */ var _extent_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../extent.js */ "./node_modules/@vaadin/map/node_modules/ol/extent.js");
/* harmony import */ var _geom_Point_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../geom/Point.js */ "./node_modules/@vaadin/map/node_modules/ol/geom/Point.js");
/* harmony import */ var _geom_Polygon_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../geom/Polygon.js */ "./node_modules/@vaadin/map/node_modules/ol/geom/Polygon.js");
/* harmony import */ var _layer_Vector_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../layer/Vector.js */ "./node_modules/@vaadin/map/node_modules/ol/layer/Vector.js");
/* harmony import */ var _proj_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../proj.js */ "./node_modules/@vaadin/map/node_modules/ol/proj.js");
/* harmony import */ var _source_Vector_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../source/Vector.js */ "./node_modules/@vaadin/map/node_modules/ol/source/Vector.js");
/* harmony import */ var _style_Style_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../style/Style.js */ "./node_modules/@vaadin/map/node_modules/ol/style/Style.js");
/* harmony import */ var _Pointer_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Pointer.js */ "./node_modules/@vaadin/map/node_modules/ol/interaction/Pointer.js");
/**
 * @module ol/interaction/Extent
 */














/**
 * @typedef {Object} Options
 * @property {import("../events/condition.js").Condition} [condition] A function that
 * takes a {@link module:ol/MapBrowserEvent~MapBrowserEvent} and returns a
 * boolean to indicate whether that event should be handled.
 * Default is {@link module:ol/events/condition.always}.
 * @property {import("../extent.js").Extent} [extent] Initial extent. Defaults to no
 * initial extent.
 * @property {import("../style/Style.js").StyleLike} [boxStyle]
 * Style for the drawn extent box. Defaults to the `Polygon` editing style
 * documented in {@link module:ol/style/Style~Style}
 * @property {number} [pixelTolerance=10] Pixel tolerance for considering the
 * pointer close enough to a segment or vertex for editing.
 * @property {import("../style/Style.js").StyleLike} [pointerStyle]
 * Style for the cursor used to draw the extent. Defaults to the `Point` editing style
 * documented in {@link module:ol/style/Style~Style}
 * @property {boolean} [wrapX=false] Wrap the drawn extent across multiple maps
 * in the X direction? Only affects visuals, not functionality.
 */

/**
 * @enum {string}
 */
const ExtentEventType = {
  /**
   * Triggered after the extent is changed
   * @event ExtentEvent#extentchanged
   * @api
   */
  EXTENTCHANGED: 'extentchanged',
};

/**
 * @classdesc
 * Events emitted by {@link module:ol/interaction/Extent~Extent} instances are
 * instances of this type.
 */
class ExtentEvent extends _events_Event_js__WEBPACK_IMPORTED_MODULE_1__["default"] {
  /**
   * @param {import("../extent.js").Extent} extent the new extent
   */
  constructor(extent) {
    super(ExtentEventType.EXTENTCHANGED);

    /**
     * The current extent.
     * @type {import("../extent.js").Extent}
     * @api
     */
    this.extent = extent;
  }
}

/**
 * @typedef {function (import("../coordinate.js").Coordinate): import("../extent.js").Extent} PointerHandler
 */

/***
 * @template Return
 * @typedef {import("../Observable").OnSignature<import("../Observable").EventTypes, import("../events/Event.js").default, Return> &
 *   import("../Observable").OnSignature<import("../ObjectEventType").Types|
 *     'change:active', import("../Object").ObjectEvent, Return> &
 *   import("../Observable").OnSignature<'extentchanged', ExtentEvent, Return> &
 *   import("../Observable").CombinedOnSignature<import("../Observable").EventTypes|import("../ObjectEventType").Types|
 *     'change:active'|'extentchanged', Return>} ExtentOnSignature
 */

/**
 * @classdesc
 * Allows the user to draw a vector box by clicking and dragging on the map.
 * Once drawn, the vector box can be modified by dragging its vertices or edges.
 * This interaction is only supported for mouse devices.
 *
 * @fires ExtentEvent
 * @api
 */
class Extent extends _Pointer_js__WEBPACK_IMPORTED_MODULE_2__["default"] {
  /**
   * @param {Options} [options] Options.
   */
  constructor(options) {
    options = options || {};

    super(/** @type {import("./Pointer.js").Options} */ (options));

    /***
     * @type {ExtentOnSignature<import("../events").EventsKey>}
     */
    this.on;

    /***
     * @type {ExtentOnSignature<import("../events").EventsKey>}
     */
    this.once;

    /***
     * @type {ExtentOnSignature<void>}
     */
    this.un;

    /**
     * Condition
     * @type {import("../events/condition.js").Condition}
     * @private
     */
    this.condition_ = options.condition ? options.condition : _events_condition_js__WEBPACK_IMPORTED_MODULE_3__.always;

    /**
     * Extent of the drawn box
     * @type {import("../extent.js").Extent}
     * @private
     */
    this.extent_ = null;

    /**
     * Handler for pointer move events
     * @type {PointerHandler|null}
     * @private
     */
    this.pointerHandler_ = null;

    /**
     * Pixel threshold to snap to extent
     * @type {number}
     * @private
     */
    this.pixelTolerance_ =
      options.pixelTolerance !== undefined ? options.pixelTolerance : 10;

    /**
     * Is the pointer snapped to an extent vertex
     * @type {boolean}
     * @private
     */
    this.snappedToVertex_ = false;

    /**
     * Feature for displaying the visible extent
     * @type {Feature}
     * @private
     */
    this.extentFeature_ = null;

    /**
     * Feature for displaying the visible pointer
     * @type {Feature<Point>}
     * @private
     */
    this.vertexFeature_ = null;

    if (!options) {
      options = {};
    }

    /**
     * Layer for the extentFeature
     * @type {VectorLayer}
     * @private
     */
    this.extentOverlay_ = new _layer_Vector_js__WEBPACK_IMPORTED_MODULE_4__["default"]({
      source: new _source_Vector_js__WEBPACK_IMPORTED_MODULE_5__["default"]({
        useSpatialIndex: false,
        wrapX: !!options.wrapX,
      }),
      style: options.boxStyle
        ? options.boxStyle
        : getDefaultExtentStyleFunction(),
      updateWhileAnimating: true,
      updateWhileInteracting: true,
    });

    /**
     * Layer for the vertexFeature
     * @type {VectorLayer}
     * @private
     */
    this.vertexOverlay_ = new _layer_Vector_js__WEBPACK_IMPORTED_MODULE_4__["default"]({
      source: new _source_Vector_js__WEBPACK_IMPORTED_MODULE_5__["default"]({
        useSpatialIndex: false,
        wrapX: !!options.wrapX,
      }),
      style: options.pointerStyle
        ? options.pointerStyle
        : getDefaultPointerStyleFunction(),
      updateWhileAnimating: true,
      updateWhileInteracting: true,
    });

    if (options.extent) {
      this.setExtent(options.extent);
    }
  }

  /**
   * @param {import("../pixel.js").Pixel} pixel cursor location
   * @param {import("../Map.js").default} map map
   * @return {import("../coordinate.js").Coordinate|null} snapped vertex on extent
   * @private
   */
  snapToVertex_(pixel, map) {
    const pixelCoordinate = map.getCoordinateFromPixelInternal(pixel);
    const sortByDistance = function (a, b) {
      return (
        (0,_coordinate_js__WEBPACK_IMPORTED_MODULE_6__.squaredDistanceToSegment)(pixelCoordinate, a) -
        (0,_coordinate_js__WEBPACK_IMPORTED_MODULE_6__.squaredDistanceToSegment)(pixelCoordinate, b)
      );
    };
    const extent = this.getExtentInternal();
    if (extent) {
      //convert extents to line segments and find the segment closest to pixelCoordinate
      const segments = getSegments(extent);
      segments.sort(sortByDistance);
      const closestSegment = segments[0];

      let vertex = (0,_coordinate_js__WEBPACK_IMPORTED_MODULE_6__.closestOnSegment)(pixelCoordinate, closestSegment);
      const vertexPixel = map.getPixelFromCoordinateInternal(vertex);

      //if the distance is within tolerance, snap to the segment
      if ((0,_coordinate_js__WEBPACK_IMPORTED_MODULE_6__.distance)(pixel, vertexPixel) <= this.pixelTolerance_) {
        //test if we should further snap to a vertex
        const pixel1 = map.getPixelFromCoordinateInternal(closestSegment[0]);
        const pixel2 = map.getPixelFromCoordinateInternal(closestSegment[1]);
        const squaredDist1 = (0,_coordinate_js__WEBPACK_IMPORTED_MODULE_6__.squaredDistance)(vertexPixel, pixel1);
        const squaredDist2 = (0,_coordinate_js__WEBPACK_IMPORTED_MODULE_6__.squaredDistance)(vertexPixel, pixel2);
        const dist = Math.sqrt(Math.min(squaredDist1, squaredDist2));
        this.snappedToVertex_ = dist <= this.pixelTolerance_;
        if (this.snappedToVertex_) {
          vertex =
            squaredDist1 > squaredDist2 ? closestSegment[1] : closestSegment[0];
        }
        return vertex;
      }
    }
    return null;
  }

  /**
   * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent pointer move event
   * @private
   */
  handlePointerMove_(mapBrowserEvent) {
    const pixel = mapBrowserEvent.pixel;
    const map = mapBrowserEvent.map;

    let vertex = this.snapToVertex_(pixel, map);
    if (!vertex) {
      vertex = map.getCoordinateFromPixelInternal(pixel);
    }
    this.createOrUpdatePointerFeature_(vertex);
  }

  /**
   * @param {import("../extent.js").Extent} extent extent
   * @return {Feature} extent as featrue
   * @private
   */
  createOrUpdateExtentFeature_(extent) {
    let extentFeature = this.extentFeature_;

    if (!extentFeature) {
      if (!extent) {
        extentFeature = new _Feature_js__WEBPACK_IMPORTED_MODULE_7__["default"]({});
      } else {
        extentFeature = new _Feature_js__WEBPACK_IMPORTED_MODULE_7__["default"]((0,_geom_Polygon_js__WEBPACK_IMPORTED_MODULE_8__.fromExtent)(extent));
      }
      this.extentFeature_ = extentFeature;
      this.extentOverlay_.getSource().addFeature(extentFeature);
    } else {
      if (!extent) {
        extentFeature.setGeometry(undefined);
      } else {
        extentFeature.setGeometry((0,_geom_Polygon_js__WEBPACK_IMPORTED_MODULE_8__.fromExtent)(extent));
      }
    }
    return extentFeature;
  }

  /**
   * @param {import("../coordinate.js").Coordinate} vertex location of feature
   * @return {Feature} vertex as feature
   * @private
   */
  createOrUpdatePointerFeature_(vertex) {
    let vertexFeature = this.vertexFeature_;
    if (!vertexFeature) {
      vertexFeature = new _Feature_js__WEBPACK_IMPORTED_MODULE_7__["default"](new _geom_Point_js__WEBPACK_IMPORTED_MODULE_9__["default"](vertex));
      this.vertexFeature_ = vertexFeature;
      this.vertexOverlay_.getSource().addFeature(vertexFeature);
    } else {
      const geometry = vertexFeature.getGeometry();
      geometry.setCoordinates(vertex);
    }
    return vertexFeature;
  }

  /**
   * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.
   * @return {boolean} `false` to stop event propagation.
   * @override
   */
  handleEvent(mapBrowserEvent) {
    if (!mapBrowserEvent.originalEvent || !this.condition_(mapBrowserEvent)) {
      return true;
    }
    //display pointer (if not dragging)
    if (
      mapBrowserEvent.type == _MapBrowserEventType_js__WEBPACK_IMPORTED_MODULE_10__["default"].POINTERMOVE &&
      !this.handlingDownUpSequence
    ) {
      this.handlePointerMove_(mapBrowserEvent);
    }
    //call pointer to determine up/down/drag
    super.handleEvent(mapBrowserEvent);
    //return false to stop propagation
    return false;
  }

  /**
   * Handle pointer down events.
   * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.
   * @return {boolean} If the event was consumed.
   * @override
   */
  handleDownEvent(mapBrowserEvent) {
    const pixel = mapBrowserEvent.pixel;
    const map = mapBrowserEvent.map;

    const extent = this.getExtentInternal();
    let vertex = this.snapToVertex_(pixel, map);

    //find the extent corner opposite the passed corner
    const getOpposingPoint = function (point) {
      let x_ = null;
      let y_ = null;
      if (point[0] == extent[0]) {
        x_ = extent[2];
      } else if (point[0] == extent[2]) {
        x_ = extent[0];
      }
      if (point[1] == extent[1]) {
        y_ = extent[3];
      } else if (point[1] == extent[3]) {
        y_ = extent[1];
      }
      if (x_ !== null && y_ !== null) {
        return [x_, y_];
      }
      return null;
    };
    if (vertex && extent) {
      const x =
        vertex[0] == extent[0] || vertex[0] == extent[2] ? vertex[0] : null;
      const y =
        vertex[1] == extent[1] || vertex[1] == extent[3] ? vertex[1] : null;

      //snap to point
      if (x !== null && y !== null) {
        this.pointerHandler_ = getPointHandler(getOpposingPoint(vertex));
        //snap to edge
      } else if (x !== null) {
        this.pointerHandler_ = getEdgeHandler(
          getOpposingPoint([x, extent[1]]),
          getOpposingPoint([x, extent[3]]),
        );
      } else if (y !== null) {
        this.pointerHandler_ = getEdgeHandler(
          getOpposingPoint([extent[0], y]),
          getOpposingPoint([extent[2], y]),
        );
      }
      //no snap - new bbox
    } else {
      vertex = map.getCoordinateFromPixelInternal(pixel);
      this.setExtent([vertex[0], vertex[1], vertex[0], vertex[1]]);
      this.pointerHandler_ = getPointHandler(vertex);
    }
    return true; //event handled; start downup sequence
  }

  /**
   * Handle pointer drag events.
   * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.
   * @override
   */
  handleDragEvent(mapBrowserEvent) {
    if (this.pointerHandler_) {
      const pixelCoordinate = mapBrowserEvent.coordinate;
      this.setExtent(this.pointerHandler_(pixelCoordinate));
      this.createOrUpdatePointerFeature_(pixelCoordinate);
    }
  }

  /**
   * Handle pointer up events.
   * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.
   * @return {boolean} If the event was consumed.
   * @override
   */
  handleUpEvent(mapBrowserEvent) {
    this.pointerHandler_ = null;
    //If bbox is zero area, set to null;
    const extent = this.getExtentInternal();
    if (!extent || (0,_extent_js__WEBPACK_IMPORTED_MODULE_11__.getArea)(extent) === 0) {
      this.setExtent(null);
    }
    return false; //Stop handling downup sequence
  }

  /**
   * Remove the interaction from its current map and attach it to the new map.
   * Subclasses may set up event handlers to get notified about changes to
   * the map here.
   * @param {import("../Map.js").default} map Map.
   * @override
   */
  setMap(map) {
    this.extentOverlay_.setMap(map);
    this.vertexOverlay_.setMap(map);
    super.setMap(map);
  }

  /**
   * Returns the current drawn extent in the view projection (or user projection if set)
   *
   * @return {import("../extent.js").Extent} Drawn extent in the view projection.
   * @api
   */
  getExtent() {
    return (0,_proj_js__WEBPACK_IMPORTED_MODULE_0__.toUserExtent)(
      this.getExtentInternal(),
      this.getMap().getView().getProjection(),
    );
  }

  /**
   * Returns the current drawn extent in the view projection
   *
   * @return {import("../extent.js").Extent} Drawn extent in the view projection.
   * @api
   */
  getExtentInternal() {
    return this.extent_;
  }

  /**
   * Manually sets the drawn extent, using the view projection.
   *
   * @param {import("../extent.js").Extent} extent Extent
   * @api
   */
  setExtent(extent) {
    //Null extent means no bbox
    this.extent_ = extent ? extent : null;
    this.createOrUpdateExtentFeature_(extent);
    this.dispatchEvent(new ExtentEvent(this.extent_));
  }
}

/**
 * Returns the default style for the drawn bbox
 *
 * @return {import("../style/Style.js").StyleFunction} Default Extent style
 */
function getDefaultExtentStyleFunction() {
  const style = (0,_style_Style_js__WEBPACK_IMPORTED_MODULE_12__.createEditingStyle)();
  return function (feature, resolution) {
    return style['Polygon'];
  };
}

/**
 * Returns the default style for the pointer
 *
 * @return {import("../style/Style.js").StyleFunction} Default pointer style
 */
function getDefaultPointerStyleFunction() {
  const style = (0,_style_Style_js__WEBPACK_IMPORTED_MODULE_12__.createEditingStyle)();
  return function (feature, resolution) {
    return style['Point'];
  };
}

/**
 * @param {import("../coordinate.js").Coordinate} fixedPoint corner that will be unchanged in the new extent
 * @return {function (import("../coordinate.js").Coordinate): import("../extent.js").Extent} event handler
 */
function getPointHandler(fixedPoint) {
  return function (point) {
    return (0,_extent_js__WEBPACK_IMPORTED_MODULE_11__.boundingExtent)([fixedPoint, point]);
  };
}

/**
 * @param {import("../coordinate.js").Coordinate} fixedP1 first corner that will be unchanged in the new extent
 * @param {import("../coordinate.js").Coordinate} fixedP2 second corner that will be unchanged in the new extent
 * @return {PointerHandler|null} event handler
 */
function getEdgeHandler(fixedP1, fixedP2) {
  if (fixedP1[0] == fixedP2[0]) {
    return function (point) {
      return (0,_extent_js__WEBPACK_IMPORTED_MODULE_11__.boundingExtent)([fixedP1, [point[0], fixedP2[1]]]);
    };
  }
  if (fixedP1[1] == fixedP2[1]) {
    return function (point) {
      return (0,_extent_js__WEBPACK_IMPORTED_MODULE_11__.boundingExtent)([fixedP1, [fixedP2[0], point[1]]]);
    };
  }
  return null;
}

/**
 * @param {import("../extent.js").Extent} extent extent
 * @return {Array<Array<import("../coordinate.js").Coordinate>>} extent line segments
 */
function getSegments(extent) {
  return [
    [
      [extent[0], extent[1]],
      [extent[0], extent[3]],
    ],
    [
      [extent[0], extent[3]],
      [extent[2], extent[3]],
    ],
    [
      [extent[2], extent[3]],
      [extent[2], extent[1]],
    ],
    [
      [extent[2], extent[1]],
      [extent[0], extent[1]],
    ],
  ];
}

/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Extent);


/***/ })

}])
//# sourceMappingURL=vendors-node_modules_vaadin_map_node_modules_ol_interaction_Extent_js.js.map