react中基于腾讯地图的地图选点,地址搜索逆向定位获取经纬度
- 效果示例图
- 地图组件tencentMap/index.jsx
- 样式map.scss
- 使用案例
效果示例图
地图组件tencentMap/index.jsx
import { useEffect, useRef, useState } from "react";
import "./map.scss";function loadTMap(key) {return new Promise((resolve, reject) => {if (typeof window.TMap !== "undefined") {resolve(window.TMap);return true;}window.onTMapCallback = function () {resolve(window.TMap);return true;};const script = document.createElement("script");script.type = "text/javascript";script.src = `https://map.qq.com/api/gljs?v=1.exp&key=${key}&callback=onTMapCallback&s=1&libraries=service`;script.onerror = reject;document.head.appendChild(script);return true;});
}function TencentMap(props) {let mapInit = useRef(null);let Map = useRef(null);let markerLayer = useRef(null);let [keyword, setKeyword] = useState("");let [suggestionList, setSuggestionList] = useState([]);//初始化腾讯地图function initMap() {document.querySelector("#tencentContainer").innerHTML = "";mapInit.current = loadTMap("PZHBZ-G6A34-QV7UJ-X4QXK-YIMRK-RAFZS");mapInit.current.then((TMap) => {//定义map变量,调用TMap.Map构造函数创建地图容器Map.current = new TMap.Map(document.querySelector("#tencentContainer"), {zoom: 17, //设置地图缩放级别});//修改地图中心点Map.current.setCenter(new TMap.LatLng(31.230355, 121.47371));//创建并初始化MultiMarker(用于实现在地图中的点标注功能)markerLayer.current = new TMap.MultiMarker({id: "marker-layer",map: Map.current, //指定地图容器geometries: [],});//给地图设置点击事件Map.current.on("click", (evt) => {if (markerLayer.current) {markerLayer.current.setGeometries([]);}const lat = evt.latLng.getLat().toFixed(6);const lng = evt.latLng.getLng().toFixed(6);let location = new TMap.LatLng(lat, lng);// 创建一个正逆地址解析类const geocoder = new TMap.service.Geocoder();// 将给定的坐标位置转换为地址geocoder.getAddress({ location: location }).then((response) => {setKeyword(response.result.address);props.click({keyword: response.result.address,position: {lat: lat,lng: lng,},});markerLayer.current.add([{id: "1", //点标记唯一标识,后续如果有删除、修改位置等操作,都需要此idposition: evt.latLng, //点标记坐标位置},]);});});});}//根据输入值进行逆向定位function searchHandle(e) {let value = trim(e);if (value.length > 0) {setKeyword(value);searchSuggestionAPI(value);} else {setKeyword("");}}function searchSuggestionAPI(value) {mapInit.current.then((TMap) => {// 新建一个关键字输入提示类let suggest = new TMap.service.Suggestion({pageSize: 10, // 返回结果每页条目数});suggest.getSuggestions({keyword: value,}).then((result) => {// 以当前所输入关键字获取输入提示if (result.data.length > 0) {setSuggestionList(result.data);}}).catch((error) => {console.log("[error]", error);});});}// 点击选中下拉数据function selectSuggestionHandle(row) {mapInit.current.then((TMap) => {//修改地图中心点Map.current.setCenter(new TMap.LatLng(row.location.lat, row.location.lng));if (markerLayer.current) {markerLayer.current.setGeometries([]);}setKeyword(row.address);props.click({keyword: row.address,position: {lat: row.location.lat,lng: row.location.lng,},});markerLayer.current.add([{id: "1", //点标记唯一标识,后续如果有删除、修改位置等操作,都需要此idposition: new TMap.LatLng(row.location.lat, row.location.lng), //点标记坐标位置},]);setSuggestionList([]);});}//防抖function debounce(fn, delay = 1000) {let timer = null;return function () {if (timer) {clearTimeout(timer);}timer = setTimeout(() => {fn.apply(this, arguments);}, delay);};}/*** 去除空格,type: 1-所有空格 2-前后空格 3-前空格 4-后空格*/function trim(str, type) {str = str || "";type = type || 1;switch (type) {case 1:return str.replace(/\s+/g, "");case 2:return str.replace(/(^\s*)|(\s*$)/g, "");case 3:return str.replace(/(^\s*)/g, "");case 4:return str.replace(/(\s*$)/g, "");default:return str;}}useEffect(() => {initMap();}, []);return (<><div className="tencentMap-wrap"><div className="tencent" id="tencentContainer"></div><div className="tencent-search"><div className="search-header"><inputtype="text"placeholder="请输入地址"value={keyword}onChange={(e) => searchHandle(e.target.value)}/></div>{suggestionList.length > 0 ? (<ul className="suggestion-wrap">{suggestionList.map((item, index) => (<likey={index}className="suggestion-item"onClick={() => {selectSuggestionHandle(item);}}>{item.title}</li>))}</ul>) : ("")}</div></div></>);
}
export default TencentMap;
样式map.scss
.tencentMap-wrap {width: 90%;margin: 12px auto;.tencent {width: 100%;height: 400px;}.tencent-search {width: 100%;margin-top: 12px;display: flex;flex-direction: column;position: relative;.search-header {width: 100%;position: relative;input,input:focus {border-radius: 4px;outline: none;padding: 0px 12px;border: 1px solid #dcdcdc;border-radius: 4px;width: 100%;height: 40px;}input::placeholder,input::-moz-placeholder,input::-webkit-input-placeholder {color: #999;}}.suggestion-wrap {border: 1px solid #dcdcdc;border-radius: 4px;width: 100%;position: absolute;left: 0px;top: 44px;background-color: #fff;box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.3);z-index: 9;padding: 12px 0px;display: flex;flex-direction: column;.suggestion-item {border-bottom: 1px solid #dcdcdc;width: 100%;cursor: pointer;padding: 12px 12px;font-size: 16px;color: #333;}.suggestion-item:last-child {border-bottom: 0px;}.suggestion-item:hover {background-color: rgba(220, 220, 220, 0.5);}}}
}
使用案例
import { useEffect } from "react";
import TencentMap from "../../components/tencentMap";function Tencent() {function mapHandle(row) {console.log("[row]", row);}useEffect(() => {}, []);return (<><TencentMap click={mapHandle} /></>);
}
export default Tencent;
腾讯地图Javascript API,功能扩展请参考官网