"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;
var _react = _interopRequireWildcard(require("react"));
var _reactNative = require("react-native");
var _MapContext = require("../modules/MapContext");
var _lodash = require("lodash");
var _MSlot = _interopRequireDefault(require("./slots/MSlot"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
/**
 * ScaleBar Props
 * @category Props
 */

// 支持的类型

/**
 * @defaultValue default options value
 * options 可选配置项 maxWidth 和距离单位 metric
 * `maxWidth: 100`
    `unit: 'metric'`
 *
 */
const defaultOptions = {
  maxWidth: 100,
  unit: 'metric'
};

// 单位
const unitAbbr = {
  kilometer: 'km',
  meter: 'm',
  mile: 'mi',
  foot: 'ft',
  'nautical-mile': 'nm'
};

/**
 * @example
 * ```
 * import Mapa, {Scalebar} from 'react-native-mapa';
import {SafeAreaView} from 'react-native';
import React from 'react';

function ScalebarView(): React.JSX.Element {
    return (
        <SafeAreaView style={{height: '100%'}}>
            <Mapa.MapView>
                <Scalebar />
            </Mapa.MapView>
        </SafeAreaView>
    );
}

export default ScalebarView;

 * ```
  @category Component
 */
const Scalebar = props => {
  const {
    map
  } = (0, _react.useContext)(_MapContext.MapContext);
  const [scaleInfo, setScaleInfo] = (0, _react.useState)({
    width: 0,
    scale: ''
  });
  const slotRef = _react.default.useRef(null);
  const [isShow, setIsShow] = (0, _react.useState)(true);
  // 获取地图的可见区域边界框

  const _update = (latitude, zoomLevel) => {
    const {
      maxWidth,
      unit
    } = props.options ?? defaultOptions;

    // TODO : 修改了计算方式
    const earthRadius = 6378137; // Earth's radius in meters
    const tileSize = 256; // Map tile size in pixels

    const metersPerPixel = Math.cos(latitude * Math.PI / 180) * 2 * Math.PI * earthRadius / (tileSize * Math.pow(2, zoomLevel));
    if (!(0, _lodash.isNumber)(maxWidth)) {
      throw new Error('maxWidth type need number');
    }
    const maxMeters = metersPerPixel * maxWidth;
    // The real distance corresponding to 100px scale length is rounded off to
    // near pretty number and the scale length for the same is found out.
    // Default unit of the scale is based on User's locale.
    if (unit === 'imperial') {
      const maxFeet = 3.2808 * maxMeters;
      if (maxFeet > 5280) {
        const maxMiles = maxFeet / 5280;
        _setScale(maxWidth, maxMiles, 'mile');
      } else {
        _setScale(maxWidth, maxFeet, 'foot');
      }
    } else if (unit === 'nautical') {
      const maxNauticals = maxMeters / 1852;
      _setScale(maxWidth, maxNauticals, 'nautical-mile');
    } else if (maxMeters >= 1000) {
      _setScale(maxWidth, maxMeters / 1000, 'kilometer');
    } else {
      _setScale(maxWidth, maxMeters, 'meter');
    }
  };
  const _setScale = (maxWidth, maxDistance, unit) => {
    const distance = getRoundNum(maxDistance);
    const ratio = distance / maxDistance;
    setScaleInfo({
      width: maxWidth * ratio * 2,
      scale: `${distance}${unitAbbr[unit] ?? 'km'}`
    });
  };

  // 渲染
  const onShow = async () => {
    const calculateScale = async (latitude, zoomLevel) => {
      try {
        _update(latitude[1], zoomLevel);
        slotRef.current?.refresh();
      } catch (error) {}
    };
    map.on('cameraChanged', event => {
      // @ts-ignore
      const {
        center,
        zoom
      } = event.properties;
      calculateScale(center, zoom);
    });
    map.on('loaded', async () => {
      calculateScale(await map.getCenter(), await map.getZoom());
    });
  };

  // remove scaleBar
  const onRemove = () => {
    // this._container.remove();
    // // $FlowFixMe[method-unbinding]
    // this._map.off('move', this._update);
    // this._map = (undefined: any);
  };
  (0, _react.useEffect)(() => {
    const needChange = (props.visible ?? isShow) === isShow;
    if (needChange) {
      setIsShow(!!props.visible);
      if (props.visible) {
        onShow();
      } else {
        onRemove();
      }
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [props.visible, map]);
  (0, _react.useEffect)(() => {
    onShow();
    return () => {
      //setScale(null); // 清除比例尺状态
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [map]);
  return /*#__PURE__*/_react.default.createElement(_MSlot.default, {
    ref: slotRef,
    style: props.style || 'bottom'
  }, /*#__PURE__*/_react.default.createElement(ScaleIndicator, {
    scaleInfo: scaleInfo
  }));
};
const ScaleIndicator = ({
  scaleInfo
}) => {
  let {
    width = 40,
    scale
  } = scaleInfo;
  const styles = _reactNative.StyleSheet.create({
    container: {
      width: width,
      borderRadius: 4,
      color: 'white'
    },
    scaleText: {
      fontSize: 16,
      textAlign: 'center',
      width: width
    },
    scaleLine: {
      flex: 1,
      flexDirection: 'row',
      alignItems: 'center'
    },
    scaleLeft: {
      width: 1,
      height: 6,
      borderStyle: 'solid',
      borderBlockStartColor: '#fff',
      borderLeftWidth: 1,
      borderRightWidth: 1
    },
    scaleRight: {
      width: 1,
      height: 6,
      borderStyle: 'solid',
      borderBlockStartColor: '#fff',
      borderLeftWidth: 1,
      borderRightWidth: 1
    },
    scaleMidle: {
      width: width - 4,
      height: 2,
      borderBlockColor: '#333',
      borderTopWidth: 1,
      borderBottomWidth: 1
    }
  });
  return /*#__PURE__*/_react.default.createElement(_reactNative.View, {
    style: {
      ...styles.container
    }
  }, /*#__PURE__*/_react.default.createElement(_reactNative.View, null, /*#__PURE__*/_react.default.createElement(_reactNative.Text, {
    style: styles.scaleText
  }, scale)), /*#__PURE__*/_react.default.createElement(_reactNative.View, {
    style: styles.scaleLine
  }, /*#__PURE__*/_react.default.createElement(_reactNative.View, {
    style: styles.scaleLeft
  }), /*#__PURE__*/_react.default.createElement(_reactNative.View, {
    style: styles.scaleMidle
  }), /*#__PURE__*/_react.default.createElement(_reactNative.View, {
    style: styles.scaleRight
  })));
};
var _default = exports.default = Scalebar;
function getDecimalRoundNum(d) {
  const multiplier = Math.pow(10, Math.ceil(-Math.log(d) / Math.LN10));
  return Math.round(d * multiplier) / multiplier;
}
function getRoundNum(num) {
  const pow10 = Math.pow(10, `${Math.floor(num)}`.length - 1);
  let d = num / pow10;
  d = d >= 10 ? 10 : d >= 5 ? 5 : d >= 3 ? 3 : d >= 2 ? 2 : d >= 1 ? 1 : getDecimalRoundNum(d);
  return pow10 * d;
}
//# sourceMappingURL=Scalebar.js.map