oak-frontend-base/es/components/map/locate/index.js

109 lines
4.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React, { useState, useRef, useEffect } from "react";
import { Row, Col, Input, List, Empty, Spin, } from 'antd';
import { SearchOutlined, CheckCircleFilled } from '@ant-design/icons';
import OpenLayer from '../openlayer';
import Styles from './web.module.less';
import { useFeatures } from '../../../platforms/web';
export default function Locate(props) {
const [mode, setMode] = useState('dragMap');
const [searchValue, setSearchValue] = useState('');
const [searchLoading, setSearchLoading] = useState(false);
const [pois, setPois] = useState();
const [currentPoi, setCurrentPoi] = useState();
const searchRef = useRef();
// 这里不能用useFeatures因为无法引用lib里面的provider引用src注入是不行的
const featureGeo = useFeatures().geo;
const searchFn = () => {
if (searchValue?.length > 1) {
setSearchLoading(true);
featureGeo.searchPoi(searchValue, props.areaId, undefined, 0, 10).then((result) => {
setSearchLoading(false);
setPois(result.map((ele, idx) => ({
...ele,
id: idx,
coordinate: [ele.longitude, ele.latitude],
})));
// setCurrentPoi(pois[0]);
}, (error) => {
console.warn(error);
setPois(undefined);
setSearchLoading(false);
});
}
else {
setPois(undefined);
}
};
let handle;
useEffect(() => {
handle = setTimeout(searchFn, 1000);
}, [searchValue]);
const center = currentPoi?.coordinate || props.coordinate;
const Locate = (<List className={Styles["location-list"]} header={<Input ref={searchRef} placeholder="请输入完整名称(如“浙江大学”)而非简称(如“浙大”)" value={searchValue} allowClear onChange={(e) => {
clearTimeout(handle);
setSearchValue(e.target.value);
}} prefix={<SearchOutlined />} onFocus={() => {
setMode('searchPoi');
}} onBlur={() => {
}}/>}>
{mode === 'searchPoi' && (<React.Fragment>
{searchLoading ? (<div className={Styles['location-list-meta']}>
<Spin delay={0} spinning size="default"/>
</div>) : (pois?.length
? pois.map((poi, index) => {
return (<div key={poi.id} onClick={() => {
setCurrentPoi(poi);
props.onLocated({
poiName: poi.poiName,
coordinate: poi.coordinate,
areaId: poi.areaId,
});
}}>
<List.Item actions={[
<div style={{
width: 24,
}}>
{currentPoi?.id ===
poi.id && (<CheckCircleFilled className={Styles['location-list-checked']}/>)}
</div>,
]}>
<List.Item.Meta title={poi.poiName}/>
</List.Item>
</div>);
})
: (<div className={Styles['location-list-meta']}>
<Empty description={`没有${searchValue}相关的地名搜索结果`} image={Empty.PRESENTED_IMAGE_SIMPLE}/>
</div>))}
</React.Fragment>)}
</List>);
const Map2 = props.Map || OpenLayer;
if (window.innerWidth > 480) {
return (<Row gutter={[16, 16]} style={{
width: '100%',
minHeight: 600,
maxHeight: '100%',
}}>
<Col xs={24} sm={14}>
<Map2 style={{ height: '100%' }} id="location-map" center={center} markers={center ? [center] : undefined}/>
</Col>
<Col xs={24} sm={10}>
{Locate}
</Col>
</Row>);
}
return (<Col style={{
width: '100%',
height: '100%',
display: 'flex',
flexDirection: 'column',
alignItems: 'stretch',
}}>
<Row>
<Map2 style={{ height: 400, width: '100%' }} id="location-map" center={center} markers={center ? [center] : undefined}/>
</Row>
<Row style={{ flex: 1, marginLeft: 5, marginRight: 5 }}>
{Locate}
</Row>
</Col>);
}