react中使用腾讯地图

腾讯文档

申请好对应key

配置限额

https://lbs.qq.com/service/webService/webServiceGuide/webServiceQuota

代码

用到的服务端接口
1.逆地址解析
2.关键词输入提示

import React, {
    
     Component } from 'react';
import styles from './map.less'
import {
    
     Form, Row, Col, Input, Select, Spin, message } from 'antd';
import PropTypes from 'prop-types';
import {
    
     connect } from 'dva';
import axios from 'axios'
import debounce from 'lodash/debounce';
import createItem from '@/components/form/ItemList/createItem';
let key = 'your tengxun key';

@createItem()
@connect((merchantsFile) => ({
    
    
  ...merchantsFile,
}))

export default class mapControl extends Component {
    
    
  componentDidMount() {
    
    
    // this.props.onRef && this.props.onRef(this);
    this.initMap();
    this.fetchUser = debounce(this.fetchUser, 800);
  }
  static propTypes = {
    
    
    editable: PropTypes.bool,
    optionKey: PropTypes.string,
    options: PropTypes.array,
    addBlankOption: PropTypes.bool,
    type: PropTypes.oneOf(['dropdown', 'radio', 'group', 'searchQuery', 'menu']),
    value: PropTypes.any,
    valueType: PropTypes.oneOf(['object', 'array']),
    onChange: PropTypes.func,
    menuData: PropTypes.array,
    term: PropTypes.string,
  }

  static defaultProps = {
    
    
    dispatch: PropTypes.dispatch,
  }

  constructor(props) {
    
    
    super(props);
    // this.qqMap = {};
    this.state = {
    
    
      inputValue: undefined,
      // 展示中心经纬度和默认Marker经纬度(没啥用)
      center: '',
      fetching: false,
      loading: false,
      lnglatObj: {
    
    
        lat: '',
        lng: ''
      },
      data: []
    };
  }
  // 创建TMap方法  核心代码
  TMap = key => {
    
    
    return new Promise(function (resolve, reject) {
    
    
      window.init = function () {
    
    
        resolve(qq);
      };
      var script = document.createElement('script');
      script.type = 'text/javascript';
      script.src = 'http://map.qq.com/api/js?v=2.exp&callback=init&key=' + key;
      script.onerror = reject;
      document.head.appendChild(script);
    });
  }

  initMap = () => {
    
    
    //设置中心坐标
    this.TMap(key).then(qq => {
    
    
      //设置地图属性
      let myOptions = {
    
    
        zoom: 16,
        mapTypeId: qq.maps.MapTypeId.ROADMAP,
        viewMode: '2D',
        disableDefaultUI: true
      };
      //创建地图,绑定dom
      this.map = new qq.maps.Map(document.getElementById('myMap'), myOptions);
      // 获取当前位置
      if (navigator.geolocation) {
    
    
        navigator.geolocation.getCurrentPosition(position => {
    
    
          const {
    
     latitude, longitude } = position.coords;
          const currentLocation = new qq.maps.LatLng(latitude, longitude);
          this.setMapMarker(currentLocation)
        });
      }
    });
  }
  // 设置地图点位以及将该点位移入中心位置
  setMapMarker = (myLatlng) => {
    
    
    // let latObj = { lat: 30, lng: 80 }
    this.map.setCenter(myLatlng);
    //现实已经存在的点 qq已挂载在window下面
    let markerlast = new qq.maps.Marker({
    
    
      position: myLatlng,
      map: this.map,
      draggable: true
    });
    qq.maps.event.addListener(markerlast, 'dragend', this.changeAddress);
  }
  // 拖曳点位并且获取地址 逆地址编码
  changeAddress = (location) => {
    
    
    this.setState({
    
     loading: true })
    // 根据拖曳的坐标调取接口获取位置
    const {
    
     dispatch } = this.props
    dispatch({
    
    
      type: "后端接口",
      payload: {
    
    
        path: 'ws/geocoder/v1/',
        method: 'GET',
        param: {
    
    
          location: location.latLng.lat + ',' + location.latLng.lng,
        }
      }
    }).then(res => {
    
    
      this.setState({
    
     loading: false })
      if (res.code !== 20000) {
    
    
        message.error(res.data.message);
        return
      } else {
    
    
        this.setState({
    
     lnglatObj: res.data.result.location })
        this.setInputValue(res.data.result.address)
      }
    });
  }

  handleChange = (chageValue, twoValue) => {
    
    
    const {
    
     form } = this.props
    const {
    
     children, data } = twoValue.props
    this.setState({
    
    
      inputValue: children,
      lnglatObj: data.location
    }, () => {
    
    
      // console.log(this.state.lnglatObj, 'lnglatObj')
      const {
    
     lat, lng } = data.location
      const locationObj = new qq.maps.LatLng(lat, lng)
      this.setValueFather()
      // 地图点位联动
      this.setMapMarker(locationObj)
    })
  }

  // 触发父组件赋值
  setValueFather = () => {
    
    
    const {
    
     inputValue, lnglatObj } = this.state
    this.props.onChange(
      (!inputValue && !lnglatObj)
        ? undefined
        : [inputValue && inputValue.valueOf(), lnglatObj && lnglatObj.valueOf()]
    );
  }

  setInputValue = (e) => {
    
    
    // 当输入框值为空清空经纬度和默认地址
    if (!e) {
    
    
      this.setState({
    
    
        lnglatObj: {
    
     lng: null, lat: null },
      })
    }
    this.setState({
    
    
      inputValue: e,
    }, () => {
    
    
      this.setValueFather()
    })
  }
  // 获取模糊查询
  fetchUser = value => {
    
    
    const {
    
     dispatch } = this.props
    this.setState({
    
     loading: true })
    dispatch({
    
    
      type: "后端接口",
      payload: {
    
    
        enableCache: true,
        path: 'ws/place/v1/suggestion',
        method: 'GET',
        param: {
    
    
          keyword: value
        }
      }
    }).then(res => {
    
    
      this.setState({
    
     loading: false })
      if (res.code === 20000) {
    
    
        message.success(res.message);
        this.setState({
    
     data: res.data.data });
      } else {
    
    
        message.error(res.message);
      }
    });
  };
  render() {
    
    
    const {
    
     inputValue, fetching, data, loading } = this.state
    const {
    
     valueMap } = this.props
    const options = this.state.data.map(d => <Option key={
    
    d.id} data={
    
    d}>{
    
    d.address}</Option>);
    return (<>
      <Select
        showSearch
        {
    
    ...this.props}
        value={
    
    inputValue ? inputValue : valueMap}
        placeholder='请输入详细地址'
        filterOption={
    
    false}
        onSearch={
    
    this.fetchUser}
        onChange={
    
    this.handleChange}
        notFoundContent={
    
    fetching ? <Spin size="small" /> : null}
        style={
    
    {
    
     marginBottom: 16, width: '100%' }}
        loading={
    
    loading}
      >
        {
    
    options}
      </Select>
      <div id="myMap" className={
    
    styles.myMap}></div>
    </>);
  }
}

map.less

.myMap {
    
    
  /*地图(容器)显示大小*/
  width: 100%;
  height: 215px;
}

.rowmap {
    
    
  margin-bottom: 24px;
}

.mapcon {
    
    
  height: 215px;
}

猜你喜欢

转载自blog.csdn.net/LRQQHM/article/details/136745628