| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134 |
- import { __awaiter } from "tslib";
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
- import { forwardRef, useCallback, useEffect, useImperativeHandle, useRef, useState, } from "react";
- import { Amap, Marker } from "@amap/amap-react";
- import { AutoComplete, Button, Input, Space, message } from "antd";
- import { debounce, isNumber } from "lodash";
- import { DageMapGeocoder } from "./plugins";
- import { getAmapInputTips } from "./utils";
- export const DageMap = forwardRef(({ latitude, longitude, disabled, address, city, onlyCityArea, inputTipsApi, outCityAreaMessage, onAddressChange, onLngLatChange, onMapComplete, onError, }, ref) => {
- const mapRef = useRef();
- /** 是否禁用坐标解析地址 */
- const geocoderDisabled = useRef(false);
- const [loaded, setLoaded] = useState(false);
- /** 上一个坐标地址 */
- const prevPosition = useRef([longitude, latitude]);
- /** 输入框经度 */
- const [lng, setLng] = useState(longitude);
- /** 输入框纬度 */
- const [lat, setLat] = useState(latitude);
- const [options, setOptions] = useState([]);
- const [position, setPosition] = useState([longitude, latitude]);
- useImperativeHandle(ref, () => ({
- mapRef: mapRef.current,
- }));
- useEffect(() => {
- if (longitude === lng && latitude === lat)
- return;
- // 外部改动经纬度,不需要解析地址
- geocoderDisabled.current = true;
- setPosition([longitude, latitude]);
- setLat(latitude);
- setLng(longitude);
- prevPosition.current = [longitude, latitude];
- }, [longitude, latitude]);
- const handleSearch = useCallback(debounce((value) => __awaiter(void 0, void 0, void 0, function* () {
- if (!value) {
- setOptions([]);
- return;
- }
- const { tips } = yield getAmapInputTips(inputTipsApi, value, city);
- setOptions(tips || []);
- }), 500), [city]);
- const handleClick = useCallback((e, data) => {
- if (disabled)
- return;
- const { lng, lat } = data.lnglat;
- geocoderDisabled.current = false;
- setLat(lat);
- setLng(lng);
- setPosition([lng, lat]);
- onLngLatChange === null || onLngLatChange === void 0 ? void 0 : onLngLatChange({
- lat,
- lng,
- });
- }, [disabled, onLngLatChange]);
- /**
- * 地图初始化完成
- */
- const handleComplete = useCallback(() => {
- var _a;
- setLoaded(true);
- (_a = mapRef.current) === null || _a === void 0 ? void 0 : _a.setCenter([longitude, latitude], false, 1000);
- onMapComplete === null || onMapComplete === void 0 ? void 0 : onMapComplete();
- }, [longitude, latitude, onMapComplete]);
- const handleMarker = useCallback(debounce((e) => {
- const [lng, lat] = e._position;
- geocoderDisabled.current = false;
- setLat(lat);
- setLng(lng);
- onLngLatChange === null || onLngLatChange === void 0 ? void 0 : onLngLatChange({
- lat,
- lng,
- });
- setPosition(e._position);
- }, 200), [onLngLatChange]);
- const handlePosition = useCallback((long = lng, lati = lat) => {
- var _a;
- if (!long || !lati)
- return;
- onLngLatChange === null || onLngLatChange === void 0 ? void 0 : onLngLatChange({
- lat: lati,
- lng: long,
- });
- setPosition([long, lati]);
- (_a = mapRef.current) === null || _a === void 0 ? void 0 : _a.setCenter([long, lati], false, 1000);
- }, [lng, lat, onLngLatChange]);
- /**
- * 坐标搜索
- */
- const handleLngLatSearch = useCallback(() => {
- geocoderDisabled.current = false;
- handlePosition();
- }, [handlePosition]);
- const handleSelect = useCallback((val, opts) => {
- const [lng, lat] = opts.location.split(",").map((i) => Number(i));
- setLng(lng);
- setLat(lat);
- geocoderDisabled.current = true;
- handlePosition(lng, lat);
- onLngLatChange === null || onLngLatChange === void 0 ? void 0 : onLngLatChange({
- lat,
- lng,
- });
- prevPosition.current = [lng, lat];
- }, [handlePosition, onLngLatChange]);
- const handleAutoCompleteChange = useCallback((val) => {
- onAddressChange === null || onAddressChange === void 0 ? void 0 : onAddressChange(val);
- }, [onAddressChange]);
- const handleGeocoderAddress = (res) => {
- if (geocoderDisabled.current)
- return;
- if (onlyCityArea &&
- isNumber(city) &&
- !res.regeocode.addressComponent.adcode.startsWith(city.toString().substring(0, 2))) {
- // 超出市区范围
- handleOutCityAreaError();
- return;
- }
- onAddressChange === null || onAddressChange === void 0 ? void 0 : onAddressChange(res.regeocode.formattedAddress);
- prevPosition.current = [lng, lat];
- };
- const handleOutCityAreaError = () => {
- outCityAreaMessage && message.error(outCityAreaMessage, 2);
- onError === null || onError === void 0 ? void 0 : onError();
- setTimeout(() => {
- setLat(prevPosition.current[1]);
- setLng(prevPosition.current[0]);
- handlePosition(prevPosition.current[0], prevPosition.current[1]);
- }, 2000);
- };
- return (_jsxs(_Fragment, { children: [_jsx("div", { children: _jsx(AutoComplete, { allowClear: true, disabled: disabled, value: address, style: { width: 450 }, options: options.map((i) => (Object.assign(Object.assign({}, i), { value: i.name }))), onSearch: handleSearch, onSelect: handleSelect, onChange: handleAutoCompleteChange, children: _jsx(Input, { allowClear: true, placeholder: "\u8BF7\u8F93\u5165\u8BE6\u7EC6\u63CF\u8FF0" }) }) }), _jsxs(Space, { style: { margin: "15px 0" }, children: [_jsx(Input, { readOnly: disabled, value: lng, type: "number", placeholder: "\u8BF7\u8F93\u5165\u7ECF\u5EA6", onChange: (e) => setLng(Number(e.target.value)) }), _jsx(Input, { readOnly: disabled, value: lat, type: "number", placeholder: "\u8BF7\u8F93\u5165\u7EAC\u5EA6", onChange: (e) => setLat(Number(e.target.value)) }), !disabled && (_jsx(Button, { type: "primary", onClick: handleLngLatSearch, children: "\u67E5\u8BE2" }))] }), _jsx("div", { style: { width: 650, height: 400 }, children: _jsx(Amap, { ref: mapRef, zoom: 17, onComplete: handleComplete, onClick: handleClick, children: loaded && position ? (_jsxs(_Fragment, { children: [_jsx(Marker, { position: position, draggable: !disabled, onDragging: handleMarker }), !disabled && (_jsx(DageMapGeocoder, { city: city, position: position, onChange: handleGeocoderAddress, onError: handleOutCityAreaError }))] })) : (_jsx(_Fragment, {})) }) })] }));
- });
- export * from "./types";
- export * from "./utils";
|