import {
  Feature_default as Feature_default2
} from "./chunk-W7BDJOQY.js";
import {
  GeometryCollection_default,
  LineString_default,
  MultiLineString_default,
  MultiPoint_default,
  MultiPolygon_default
} from "./chunk-7JXPN73Q.js";
import {
  Feature_default
} from "./chunk-E53S5GN6.js";
import {
  Point_default,
  Polygon_default,
  linearRingsAreOriented,
  linearRingssAreOriented,
  orientLinearRings,
  orientLinearRingsArray
} from "./chunk-AZGMK675.js";
import {
  equivalent,
  get,
  getTransform
} from "./chunk-A3RXLHYB.js";
import {
  abstract
} from "./chunk-Q5ZULJHM.js";

// node_modules/ol/format/Feature.js
var FeatureFormat = class {
  constructor() {
    this.dataProjection = void 0;
    this.defaultFeatureProjection = void 0;
    this.featureClass = /** @type {FeatureToFeatureClass<FeatureType>} */
    Feature_default;
    this.supportedMediaTypes = null;
  }
  /**
   * Adds the data projection to the read options.
   * @param {Document|Element|Object|string} source Source.
   * @param {ReadOptions} [options] Options.
   * @return {ReadOptions|undefined} Options.
   * @protected
   */
  getReadOptions(source, options) {
    if (options) {
      let dataProjection = options.dataProjection ? get(options.dataProjection) : this.readProjection(source);
      if (options.extent && dataProjection && dataProjection.getUnits() === "tile-pixels") {
        dataProjection = get(dataProjection);
        dataProjection.setWorldExtent(options.extent);
      }
      options = {
        dataProjection,
        featureProjection: options.featureProjection
      };
    }
    return this.adaptOptions(options);
  }
  /**
   * Sets the `dataProjection` on the options, if no `dataProjection`
   * is set.
   * @param {WriteOptions|ReadOptions|undefined} options
   *     Options.
   * @protected
   * @return {WriteOptions|ReadOptions|undefined}
   *     Updated options.
   */
  adaptOptions(options) {
    return Object.assign(
      {
        dataProjection: this.dataProjection,
        featureProjection: this.defaultFeatureProjection,
        featureClass: this.featureClass
      },
      options
    );
  }
  /**
   * @abstract
   * @return {Type} The format type.
   */
  getType() {
    return abstract();
  }
  /**
   * Read a single feature from a source.
   *
   * @abstract
   * @param {Document|Element|Object|string} source Source.
   * @param {ReadOptions} [options] Read options.
   * @return {FeatureType|Array<FeatureType>} Feature.
   */
  readFeature(source, options) {
    return abstract();
  }
  /**
   * Read all features from a source.
   *
   * @abstract
   * @param {Document|Element|ArrayBuffer|Object|string} source Source.
   * @param {ReadOptions} [options] Read options.
   * @return {Array<FeatureType>} Features.
   */
  readFeatures(source, options) {
    return abstract();
  }
  /**
   * Read a single geometry from a source.
   *
   * @abstract
   * @param {Document|Element|Object|string} source Source.
   * @param {ReadOptions} [options] Read options.
   * @return {import("../geom/Geometry.js").default} Geometry.
   */
  readGeometry(source, options) {
    return abstract();
  }
  /**
   * Read the projection from a source.
   *
   * @abstract
   * @param {Document|Element|Object|string} source Source.
   * @return {import("../proj/Projection.js").default|undefined} Projection.
   */
  readProjection(source) {
    return abstract();
  }
  /**
   * Encode a feature in this format.
   *
   * @abstract
   * @param {Feature} feature Feature.
   * @param {WriteOptions} [options] Write options.
   * @return {string|ArrayBuffer} Result.
   */
  writeFeature(feature, options) {
    return abstract();
  }
  /**
   * Encode an array of features in this format.
   *
   * @abstract
   * @param {Array<Feature>} features Features.
   * @param {WriteOptions} [options] Write options.
   * @return {string|ArrayBuffer} Result.
   */
  writeFeatures(features, options) {
    return abstract();
  }
  /**
   * Write a single geometry in this format.
   *
   * @abstract
   * @param {import("../geom/Geometry.js").default} geometry Geometry.
   * @param {WriteOptions} [options] Write options.
   * @return {string|ArrayBuffer} Result.
   */
  writeGeometry(geometry, options) {
    return abstract();
  }
};
var Feature_default3 = FeatureFormat;
function transformGeometryWithOptions(geometry, write, options) {
  const featureProjection = options ? get(options.featureProjection) : null;
  const dataProjection = options ? get(options.dataProjection) : null;
  let transformed = geometry;
  if (featureProjection && dataProjection && !equivalent(featureProjection, dataProjection)) {
    if (write) {
      transformed = /** @type {T} */
      geometry.clone();
    }
    const fromProjection = write ? featureProjection : dataProjection;
    const toProjection = write ? dataProjection : featureProjection;
    if (fromProjection.getUnits() === "tile-pixels") {
      transformed.transform(fromProjection, toProjection);
    } else {
      transformed.applyTransform(getTransform(fromProjection, toProjection));
    }
  }
  if (write && options && /** @type {WriteOptions} */
  options.decimals !== void 0) {
    const power = Math.pow(
      10,
      /** @type {WriteOptions} */
      options.decimals
    );
    const transform = function(coordinates) {
      for (let i = 0, ii = coordinates.length; i < ii; ++i) {
        coordinates[i] = Math.round(coordinates[i] * power) / power;
      }
      return coordinates;
    };
    if (transformed === geometry) {
      transformed = /** @type {T} */
      geometry.clone();
    }
    transformed.applyTransform(transform);
  }
  return transformed;
}
var GeometryConstructor = {
  Point: Point_default,
  LineString: LineString_default,
  Polygon: Polygon_default,
  MultiPoint: MultiPoint_default,
  MultiLineString: MultiLineString_default,
  MultiPolygon: MultiPolygon_default
};
function orientFlatCoordinates(flatCoordinates, ends, stride) {
  if (Array.isArray(ends[0])) {
    if (!linearRingssAreOriented(flatCoordinates, 0, ends, stride)) {
      flatCoordinates = flatCoordinates.slice();
      orientLinearRingsArray(flatCoordinates, 0, ends, stride);
    }
    return flatCoordinates;
  }
  if (!linearRingsAreOriented(flatCoordinates, 0, ends, stride)) {
    flatCoordinates = flatCoordinates.slice();
    orientLinearRings(flatCoordinates, 0, ends, stride);
  }
  return flatCoordinates;
}
function createRenderFeature(object, options) {
  var _a;
  const geometry = object.geometry;
  if (!geometry) {
    return [];
  }
  if (Array.isArray(geometry)) {
    return geometry.map((geometry2) => createRenderFeature({ ...object, geometry: geometry2 })).flat();
  }
  const geometryType = geometry.type === "MultiPolygon" ? "Polygon" : geometry.type;
  if (geometryType === "GeometryCollection" || geometryType === "Circle") {
    throw new Error("Unsupported geometry type: " + geometryType);
  }
  const stride = geometry.layout.length;
  return transformGeometryWithOptions(
    new Feature_default2(
      geometryType,
      geometryType === "Polygon" ? orientFlatCoordinates(geometry.flatCoordinates, geometry.ends, stride) : geometry.flatCoordinates,
      (_a = geometry.ends) == null ? void 0 : _a.flat(),
      stride,
      object.properties || {},
      object.id
    ).enableSimplifyTransformed(),
    false,
    options
  );
}
function createGeometry(object, options) {
  if (!object) {
    return null;
  }
  if (Array.isArray(object)) {
    const geometries = object.map(
      (geometry) => createGeometry(geometry, options)
    );
    return new GeometryCollection_default(geometries);
  }
  const Geometry = GeometryConstructor[object.type];
  return transformGeometryWithOptions(
    new Geometry(object.flatCoordinates, object.layout || "XY", object.ends),
    false,
    options
  );
}

export {
  Feature_default3 as Feature_default,
  transformGeometryWithOptions,
  createRenderFeature,
  createGeometry
};
//# sourceMappingURL=chunk-56VFHHUN.js.map
