import {
  Control_default
} from "./chunk-VRTURNK3.js";
import "./chunk-BHVDQB66.js";
import {
  CLASS_UNSELECTABLE
} from "./chunk-6EWLK2BW.js";
import {
  METERS_PER_UNIT,
  getPointResolution
} from "./chunk-A3RXLHYB.js";
import "./chunk-ZLPTRF2L.js";
import "./chunk-54BTDBAD.js";
import "./chunk-Q5ZULJHM.js";
import "./chunk-NGFXCWUF.js";
import "./chunk-K25ZO44T.js";
import "./chunk-SRXHWJOY.js";
import "./chunk-5RHQVMYD.js";
import "./chunk-DC5AMYBS.js";

// node_modules/ol/control/ScaleLine.js
var UNITS_PROP = "units";
var LEADING_DIGITS = [1, 2, 5];
var DEFAULT_DPI = 25.4 / 0.28;
var ScaleLine = class extends Control_default {
  /**
   * @param {Options} [options] Scale line options.
   */
  constructor(options) {
    options = options ? options : {};
    const element = document.createElement("div");
    element.style.pointerEvents = "none";
    super({
      element,
      render: options.render,
      target: options.target
    });
    this.on;
    this.once;
    this.un;
    const className = options.className !== void 0 ? options.className : options.bar ? "ol-scale-bar" : "ol-scale-line";
    this.innerElement_ = document.createElement("div");
    this.innerElement_.className = className + "-inner";
    this.element.className = className + " " + CLASS_UNSELECTABLE;
    this.element.appendChild(this.innerElement_);
    this.viewState_ = null;
    this.minWidth_ = options.minWidth !== void 0 ? options.minWidth : 64;
    this.maxWidth_ = options.maxWidth;
    this.renderedVisible_ = false;
    this.renderedWidth_ = void 0;
    this.renderedHTML_ = "";
    this.addChangeListener(UNITS_PROP, this.handleUnitsChanged_);
    this.setUnits(options.units || "metric");
    this.scaleBar_ = options.bar || false;
    this.scaleBarSteps_ = options.steps || 4;
    this.scaleBarText_ = options.text || false;
    this.dpi_ = options.dpi || void 0;
  }
  /**
   * Return the units to use in the scale line.
   * @return {Units} The units
   * to use in the scale line.
   * @observable
   * @api
   */
  getUnits() {
    return this.get(UNITS_PROP);
  }
  /**
   * @private
   */
  handleUnitsChanged_() {
    this.updateElement_();
  }
  /**
   * Set the units to use in the scale line.
   * @param {Units} units The units to use in the scale line.
   * @observable
   * @api
   */
  setUnits(units) {
    this.set(UNITS_PROP, units);
  }
  /**
   * Specify the dpi of output device such as printer.
   * @param {number|undefined} dpi The dpi of output device.
   * @api
   */
  setDpi(dpi) {
    this.dpi_ = dpi;
  }
  /**
   * @private
   */
  updateElement_() {
    const viewState = this.viewState_;
    if (!viewState) {
      if (this.renderedVisible_) {
        this.element.style.display = "none";
        this.renderedVisible_ = false;
      }
      return;
    }
    const center = viewState.center;
    const projection = viewState.projection;
    const units = this.getUnits();
    const pointResolutionUnits = units == "degrees" ? "degrees" : "m";
    let pointResolution = getPointResolution(
      projection,
      viewState.resolution,
      center,
      pointResolutionUnits
    );
    const minWidth = this.minWidth_ * (this.dpi_ || DEFAULT_DPI) / DEFAULT_DPI;
    const maxWidth = this.maxWidth_ !== void 0 ? this.maxWidth_ * (this.dpi_ || DEFAULT_DPI) / DEFAULT_DPI : void 0;
    let nominalCount = minWidth * pointResolution;
    let suffix = "";
    if (units == "degrees") {
      const metersPerDegree = METERS_PER_UNIT.degrees;
      nominalCount *= metersPerDegree;
      if (nominalCount < metersPerDegree / 60) {
        suffix = "″";
        pointResolution *= 3600;
      } else if (nominalCount < metersPerDegree) {
        suffix = "′";
        pointResolution *= 60;
      } else {
        suffix = "°";
      }
    } else if (units == "imperial") {
      if (nominalCount < 0.9144) {
        suffix = "in";
        pointResolution /= 0.0254;
      } else if (nominalCount < 1609.344) {
        suffix = "ft";
        pointResolution /= 0.3048;
      } else {
        suffix = "mi";
        pointResolution /= 1609.344;
      }
    } else if (units == "nautical") {
      pointResolution /= 1852;
      suffix = "NM";
    } else if (units == "metric") {
      if (nominalCount < 1e-6) {
        suffix = "nm";
        pointResolution *= 1e9;
      } else if (nominalCount < 1e-3) {
        suffix = "μm";
        pointResolution *= 1e6;
      } else if (nominalCount < 1) {
        suffix = "mm";
        pointResolution *= 1e3;
      } else if (nominalCount < 1e3) {
        suffix = "m";
      } else {
        suffix = "km";
        pointResolution /= 1e3;
      }
    } else if (units == "us") {
      if (nominalCount < 0.9144) {
        suffix = "in";
        pointResolution *= 39.37;
      } else if (nominalCount < 1609.344) {
        suffix = "ft";
        pointResolution /= 0.30480061;
      } else {
        suffix = "mi";
        pointResolution /= 1609.3472;
      }
    } else {
      throw new Error("Invalid units");
    }
    let i = 3 * Math.floor(Math.log(minWidth * pointResolution) / Math.log(10));
    let count, width, decimalCount;
    let previousCount = 0;
    let previousWidth, previousDecimalCount;
    while (true) {
      decimalCount = Math.floor(i / 3);
      const decimal = Math.pow(10, decimalCount);
      count = LEADING_DIGITS[(i % 3 + 3) % 3] * decimal;
      width = Math.round(count / pointResolution);
      if (isNaN(width)) {
        this.element.style.display = "none";
        this.renderedVisible_ = false;
        return;
      }
      if (maxWidth !== void 0 && width >= maxWidth) {
        count = previousCount;
        width = previousWidth;
        decimalCount = previousDecimalCount;
        break;
      } else if (width >= minWidth) {
        break;
      }
      previousCount = count;
      previousWidth = width;
      previousDecimalCount = decimalCount;
      ++i;
    }
    const html = this.scaleBar_ ? this.createScaleBar(width, count, suffix) : count.toFixed(decimalCount < 0 ? -decimalCount : 0) + " " + suffix;
    if (this.renderedHTML_ != html) {
      this.innerElement_.innerHTML = html;
      this.renderedHTML_ = html;
    }
    if (this.renderedWidth_ != width) {
      this.innerElement_.style.width = width + "px";
      this.renderedWidth_ = width;
    }
    if (!this.renderedVisible_) {
      this.element.style.display = "";
      this.renderedVisible_ = true;
    }
  }
  /**
   * @private
   * @param {number} width The current width of the scalebar.
   * @param {number} scale The current scale.
   * @param {string} suffix The suffix to append to the scale text.
   * @return {string} The stringified HTML of the scalebar.
   */
  createScaleBar(width, scale, suffix) {
    const resolutionScale = this.getScaleForResolution();
    const mapScale = resolutionScale < 1 ? Math.round(1 / resolutionScale).toLocaleString() + " : 1" : "1 : " + Math.round(resolutionScale).toLocaleString();
    const steps = this.scaleBarSteps_;
    const stepWidth = width / steps;
    const scaleSteps = [this.createMarker("absolute")];
    for (let i = 0; i < steps; ++i) {
      const cls = i % 2 === 0 ? "ol-scale-singlebar-odd" : "ol-scale-singlebar-even";
      scaleSteps.push(
        `<div><div class="ol-scale-singlebar ${cls}" style="width: ${stepWidth}px;"></div>` + this.createMarker("relative") + // render text every second step, except when only 2 steps
        (i % 2 === 0 || steps === 2 ? this.createStepText(i, width, false, scale, suffix) : "") + "</div>"
      );
    }
    scaleSteps.push(this.createStepText(steps, width, true, scale, suffix));
    const scaleBarText = this.scaleBarText_ ? `<div class="ol-scale-text" style="width: ${width}px;">` + mapScale + "</div>" : "";
    return scaleBarText + scaleSteps.join("");
  }
  /**
   * Creates a marker at given position
   * @param {'absolute'|'relative'} position The position, absolute or relative
   * @return {string} The stringified div containing the marker
   */
  createMarker(position) {
    const top = position === "absolute" ? 3 : -10;
    return `<div class="ol-scale-step-marker" style="position: ${position}; top: ${top}px;"></div>`;
  }
  /**
   * Creates the label for a marker marker at given position
   * @param {number} i The iterator
   * @param {number} width The width the scalebar will currently use
   * @param {boolean} isLast Flag indicating if we add the last step text
   * @param {number} scale The current scale for the whole scalebar
   * @param {string} suffix The suffix for the scale
   * @return {string} The stringified div containing the step text
   */
  createStepText(i, width, isLast, scale, suffix) {
    const length = i === 0 ? 0 : Math.round(scale / this.scaleBarSteps_ * i * 100) / 100;
    const lengthString = length + (i === 0 ? "" : " " + suffix);
    const margin = i === 0 ? -3 : width / this.scaleBarSteps_ * -1;
    const minWidth = i === 0 ? 0 : width / this.scaleBarSteps_ * 2;
    return `<div class="ol-scale-step-text" style="margin-left: ${margin}px;text-align: ${i === 0 ? "left" : "center"};min-width: ${minWidth}px;left: ${isLast ? width + "px" : "unset"};">` + lengthString + "</div>";
  }
  /**
   * Returns the appropriate scale for the given resolution and units.
   * @return {number} The appropriate scale.
   */
  getScaleForResolution() {
    const resolution = getPointResolution(
      this.viewState_.projection,
      this.viewState_.resolution,
      this.viewState_.center,
      "m"
    );
    const dpi = this.dpi_ || DEFAULT_DPI;
    const inchesPerMeter = 1e3 / 25.4;
    return resolution * inchesPerMeter * dpi;
  }
  /**
   * Update the scale line element.
   * @param {import("../MapEvent.js").default} mapEvent Map event.
   * @override
   */
  render(mapEvent) {
    const frameState = mapEvent.frameState;
    if (!frameState) {
      this.viewState_ = null;
    } else {
      this.viewState_ = frameState.viewState;
    }
    this.updateElement_();
  }
};
var ScaleLine_default = ScaleLine;
export {
  ScaleLine_default as default
};
//# sourceMappingURL=ol_control_ScaleLine.js.map
