高德web服务api 查询接口案例
import React, { useEffect, useRef, useState, CSSProperties } from 'react' import { Select } from 'antd' const { Option } = Select; const AMAP_KEY = "cc9fb7d123185499909bf80c4c778535" const queryBykeyword = async (params: object) => { let url = 'https://restapi.amap.com/v3/place/text' const config = { output: 'JSON', key: AMAP_KEY, extensions: 'all' } let newParams = "?" for (const [key, value] of Object.entries({ ...config, ...params })) { newParams = newParams[newParams.length - 1] === "&" ? newParams : newParams + "&" newParams = newParams + key + "=" + value; } url = url + newParams return new Promise((resolve, reject) => { const xhr = new XMLHttpRequest() xhr.open("get", url) xhr.send() // xhr.responseType xhr.addEventListener('load', () => { const status = xhr.status; if ((status >= 200 && status < 300) || status === 304) { const result = JSON.parse(xhr.response) resolve(result) } else { reject(xhr) } }); }) } const styleSearch: CSSProperties = { width: "60%", background: 'transparent', position: 'absolute', right: 12, top: 20, zIndex: 2, } const styleHandle: CSSProperties = { cursor: ' pointer', pointerEvents: 'all', zIndex: 3, position: 'absolute', right: 8, top: 0, transform: 'translateY(50%)' } const styleTip: CSSProperties = { pointerEvents: 'none', zIndex: 3, position: 'absolute', right: 0, top: 20, // transform: 'translateX(50%) translateY(calc(-50% - 10px ))', fontSize: 12, transition: 'all 0.4s ease 0s' } interface PropsT { sendLnglat: (lnglat: any[]) => void initLnglat?: any[] } const Amap = (props: PropsT) => { const { sendLnglat,initLnglat } = props const refMap = useRef(null) // const [geoCenter, setGeoCenter] = useState<any[]>() const [keywords, setSeywords] = useState('') const [result, setResult] = useState<any[]>([]) const [myMap, setMyMap] = useState<any>() // const [currentItem, setCurrentItem] = useState<any>({}) const [hoverItemPos, setHoverItemPos] = useState<any>({}) const [hoverItem, setHoverItem] = useState<any>({}) useEffect(() => { if (!window.AMap) { // console.log('start loadMapScript'); loadMapScript() } else { initMap() } }, []) const loadMapScript = () => { window.initMap = () => { // console.log('AMap script is ready!!'); initMap(); }; const script = document.createElement('script'); script.type = 'text/javascript'; script.src = `https://webapi.amap.com/maps?v=1.4.15&key=${AMAP_KEY}&callback=initMap`; document.body.appendChild(script); }; const initMap = () => { if (!window.AMap) { // console.error('AMap script is not ready!!'); return; } // console.log('start initMap'); const map = new window.AMap.Map(refMap.current, { zoom: 12, // 级别 center: initLnglat,// 中心点坐标 resizeEnable: true, dragEnable: true, // showIndoorMap: false, // showLabel: false, // mapStyle: 'amap://styles/whitesmoke', // features: ['bg', 'road', 'building'], }); map.plugin('AMap.ToolBar', () => { // 添加地图控件 const toolbar = new window.AMap.ToolBar(); map.addControl(toolbar) }) map.on('click', (ev: any) => {// 绑定全局事点击件获取坐标 // 触发事件的对象 // var target = ev.target; // 触发事件的地理坐标,AMap.LngLat 类型 const lnglat = ev.lnglat; // 触发事件的像素坐标,AMap.Pixel 类型 // var pixel = ev.pixel; // 触发事件类型 // var type = ev.type; // console.log("ev==", ev); const { lng, lat } = lnglat sendLnglat([lng, lat]) }); map.on('dragstart', () => { // 绑定全局拖拽事件,重置活跃项及其坐标 setHoverItemPos({}) setHoverItem({}) }); setMyMap(map) // 保存当前地图实例 }; const handleChange = (_val: any, opt: any) => { const { item } = opt.props // console.log("val opt", val, opt); // setCurrentItem(item) if (!window.AMap || !myMap) { return } setHoverItemPos({}) setHoverItem({}) const lnglat = item.location?.split(',').map((i: any) => +i) || [] myMap.setCenter(lnglat) // 定位到选中项 myMap.setZoom(17) } const handleSearch = (val: any) => { const words = val.trim() // console.log("words==", words); setSeywords(words) search({ keywords: words }) } const search = (prms = {}) => { const params = { // keywords: keywords, // city: 'beijing', offset: 25, page: 1, ...prms } queryBykeyword(params).then((data: any) => { if (data?.status == 1 && data.pois.length) { setResult(data.pois) const item = data.pois?.[0] // 默认取搜索结果第一项为活跃项 if (!window.AMap || !myMap) { return } const lnglat = item.location?.split(',').map((i: any) => +i) || [] myMap.setCenter(lnglat) markResult(data.pois) // 将搜索结果 Mark 到地图上 } else { setResult([]) } }) } const markResult = (resultList: any[]) => { if (!window.AMap || !myMap) { return } setHoverItemPos({}) setHoverItem({}) const markers = resultList?.map(item => { const lnglatn = item.location?.split(',').map((i: any) => +i) || [] const marker = new window.AMap.Marker({ icon: "https://webapi.amap.com/theme/v1.3/markers/n/mark_b.png", position: lnglatn, offset: new window.AMap.Pixel(-10, -30), extData: { // marker 的额外数据 ...item }, }); marker.on('click', (e: any) => { // 单独给 marker 绑定事件 // console.log("ev click", e); const { target = {}, } = e const { w = {} } = target const { extData = {} } = w // const { lng, lat } = lnglat // myMap.setCenter([lng, lat]) // setCurrentItem(extData) const { location = '' } = extData sendLnglat(location.split(',')) // 获取点击项坐标 }); marker.on('mousemove', (e: any) => { // console.log("ev mousemove", e); const { target = {}, pixel } = e const { w = {} } = target const { extData = {} } = w setHoverItemPos(pixel) // 获取 hover 项坐标等信息以显示 setHoverItem(extData) }) // marker.on('mouseout', (e: any) => { // console.log("ev mouseout", e); // }) return marker }) myMap.clearMap(); // mark 前先 clear myMap.add(markers) } const Options = result.map((item: any) => <Option key={item.id} value={item.id} item={item} >{item.name}</Option>) return ( <div style={{ width: '100%', height: 300, position: 'relative' }}> <div ref={refMap} style={{ width: '100%', height: "100%" }} > </div> <div style={{ ...styleTip, right: hoverItemPos.x ? `calc(100% - ${hoverItemPos.x}px` : undefined, top: hoverItemPos.y, transform: `${hoverItemPos.x ? 'scale(1)' : 'scale(0.001)'} translateX(50%) translateY(calc(-50% - 10px ))` }} >{hoverItem.name}</div> <div style={{ ...styleSearch }} > <Select className="amap-search" showSearch // value={"Homepp"} size="large" placeholder={"请输入"} defaultActiveFirstOption={false} showArrow={false} filterOption onSearch={handleSearch} onChange={handleChange} notFoundContent={null} optionFilterProp="children" // style={{ pointerEvents: 'all' }} dropdownStyle={{ backgroundColor: 'rgba(225,225,225,0.8)' }} listHeight={220} > {Options} </Select> <span style={{ ...styleHandle }} onClick={() => { search({ keywords }) }}>搜索</span> </div> </div >) } export default Amap