uiwjs / react-baidu-map

基于 React 封装的百度地图组件,支持 React Hook,帮助你轻松的接入地图到 React 项目中。
https://uiwjs.github.io/react-baidu-map
MIT License
222 stars 22 forks source link

你好,请问想要关联检索功能该怎么做呢? #39

Open huangpfly opened 4 years ago

huangpfly commented 4 years ago

就像baidu map原生api中那种检索功能 http://lbs.baidu.com/jsdemo.htm#a6_2

jaywcjlove commented 4 years ago

@huangpfly 当 map 对象初始化之后调用下面方法

function setPlace(){
  const local = new BMap.LocalSearch(map, { //智能搜索
    onSearchComplete: () => {
      const pp = local.getResults().getPoi(0).point;    //获取第一个智能搜索的结果
      map.centerAndZoom(pp, 18);
      map.addOverlay(new BMap.Marker(pp));    //添加标注
    }
  });
  local.search(myValue);

}
willyang90 commented 3 years ago

求demo,用了load,只有加载能用,之后无法更新结果

JoyNop commented 3 years ago

同求demo

jaywcjlove commented 3 years ago

@dream2023 @JoyNop @willyang90 @huangpfly

写了一个简单的示例,你们自己研究。

Example Preview: https://codesandbox.io/embed/react-baidu-map-demo-39-kq4c7?fontsize=14&hidenavigation=1&theme=dark

import { useRef } from "react";
import ReactDOM from "react-dom";
import { Map, APILoader } from "@uiw/react-baidu-map";

const Demo = () => {
  const input = useRef();
  const resultRef = useRef();
  function setPlace(map, BMap, myValue) {
    map.clearOverlays(); // 清除地图上所有覆盖物
    const local = new BMap.LocalSearch(map, {
      //智能搜索
      onSearchComplete: () => {
        const pp = local.getResults().getPoi(0).point; //获取第一个智能搜索的结果
        map.centerAndZoom(pp, 18);
        map.addOverlay(new BMap.Marker(pp)); //添加标注
      }
    });
    local.search(myValue);
  }
  return (
    <div style={{ width: "100%", height: "300px" }}>
      <input type="text" ref={input} />
      <div ref={resultRef}></div>
      <APILoader akay="GTrnXa5hwXGwgQnTBG28SHBubErMKm3f">
        <Map center="北京">
          {({ AMap, BMap, map, container }) => {
            if (input.current) {
              const ac = new BMap.Autocomplete({
                //建立一个自动完成的对象
                input: input.current,
                location: map
              });
              let myValue;
              ac.addEventListener("onconfirm", (e) => {
                const val = e.item.value;
                myValue =
                  val.province +
                  val.city +
                  val.district +
                  val.street +
                  val.business;
                // resultRef.current.innerHTML = `onconfirm<br />index = ${e.item.index}<br />myValue = ${myValue}`;
                // console.log("e", val);
                setPlace(map, BMap, myValue);
              });
            }
            return;
          }}
        </Map>
      </APILoader>
    </div>
  );
};
ReactDOM.render(<Demo />, document.getElementById("container"));
haungxinyan commented 2 years ago

@dream2023 @JoyNop @willyang90 @huangpfly

写了一个简单的示例,你们自己研究。

Example Preview: https://codesandbox.io/embed/react-baidu-map-demo-39-kq4c7?fontsize=14&hidenavigation=1&theme=dark

import { useRef } from "react";
import ReactDOM from "react-dom";
import { Map, APILoader } from "@uiw/react-baidu-map";

const Demo = () => {
  const input = useRef();
  const resultRef = useRef();
  function setPlace(map, BMap, myValue) {
    map.clearOverlays(); // 清除地图上所有覆盖物
    const local = new BMap.LocalSearch(map, {
      //智能搜索
      onSearchComplete: () => {
        const pp = local.getResults().getPoi(0).point; //获取第一个智能搜索的结果
        map.centerAndZoom(pp, 18);
        map.addOverlay(new BMap.Marker(pp)); //添加标注
      }
    });
    local.search(myValue);
  }
  return (
    <div style={{ width: "100%", height: "300px" }}>
      <input type="text" ref={input} />
      <div ref={resultRef}></div>
      <APILoader akay="GTrnXa5hwXGwgQnTBG28SHBubErMKm3f">
        <Map center="北京">
          {({ AMap, BMap, map, container }) => {
            if (input.current) {
              const ac = new BMap.Autocomplete({
                //建立一个自动完成的对象
                input: input.current,
                location: map
              });
              let myValue;
              ac.addEventListener("onconfirm", (e) => {
                const val = e.item.value;
                myValue =
                  val.province +
                  val.city +
                  val.district +
                  val.street +
                  val.business;
                // resultRef.current.innerHTML = `onconfirm<br />index = ${e.item.index}<br />myValue = ${myValue}`;
                // console.log("e", val);
                setPlace(map, BMap, myValue);
              });
            }
            return;
          }}
        </Map>
      </APILoader>
    </div>
  );
};
ReactDOM.render(<Demo />, document.getElementById("container"));

const ac = new BMap.Autocomplete({ //建立一个自动完成的对象 input: addressRef.current, location: map, }) 类型“Autocomplete”上不存在属性“addEventListener”。ts(2339)

jaywcjlove commented 2 years ago

@huangpfly 是的 SDK 3.0 没有 addEventListener 方法。https://lbsyun.baidu.com/cms/jsapi/reference/jsapi_reference_3_0.html#a7b50

https://github.com/uiwjs/react-baidu-map/blob/fd2237641d3d9dd304638b266768dbc5ff91a873/packages/types/src/service.d.ts#L275-L331

Autocomplete 只有两个事件方法

https://github.com/uiwjs/react-baidu-map/blob/fd2237641d3d9dd304638b266768dbc5ff91a873/packages/types/src/service.d.ts#L309-L330

haungxinyan commented 2 years ago

写了一个季度的前端代码了 每次用地图还是很难,hook示例太少了 ,我遇到了一些问题,希望能帮我看看

<Form.Item
  rules={[{ required: true }]}
  name="address"
  label={intl.formatMessage({ id: 'attendance.outdoorwork.address', defaultMessage: 'Address' })}
>
  <input ref={addressRef} />
</Form.Item>

<Map center="北京">
          {({ BMap, map, container }) => {
            if (addressRef.current) {
              const ac = new BMap.Autocomplete({
                //建立一个自动完成的对象
                input: addressRef.current,
                location: map,
                onSearchComplete: (result) => {
                  setPlace(map, BMap, result.keyword)
                }
              })
              ac.setLocation(addressValue)

            }
          }}
        </Map>

const setPlace = (map, BMap, myValue) => {
    map.clearOverlays(); // 清除地图上所有覆盖物
    var point = undefined
    const local = new BMap.LocalSearch(map, {
      //智能搜索
      onSearchComplete: () => {
        const pp = local.getResults()?.getPoi(0)?.point || undefined; //获取第一个智能搜索的结果
        if (pp) {
          point=pp
          map.centerAndZoom(pp, 18);
          map.addOverlay(new BMap.Marker(pp)); //添加标注
        }
        form.setFieldsValue({longitude: pp?.lng||'', latitude: pp?.lat||''})
      }
    });
    local.search(myValue);

  }

问题1、浏览器提示错误

devScripts.js:6523 Warning: A component is changing an uncontrolled input to be controlled. This is likely caused by the value changing from undefined to a defined value, which should not happen. Decide between using a controlled or uncontrolled input element for the lifetime of the component. More info: https://reactjs.org/link/controlled-components at input

问题2、Input没有ref属性,所以用了input ,界面样式不统一了

jaywcjlove commented 2 years ago

@huangpfly 官方实例使用的 2.0 我们这个基于 百度地图SDK 3.0

问题 1. 是组件受控问题,与组件无关吧。 问题2. input 为什么没有 ref?是因为你嵌套了 Form.Item 组件导致的?

jaywcjlove commented 2 years ago

@huangpfly 实例预览: https://codesandbox.io/s/react-baidu-map-demo-39-v10j5?file=/src/index.js

const Demo = () => {
  const inputRef = useRef();
  return (
    <div style={{ width: "100%", height: "300px" }}>
      <input ref={inputRef} type="text" />
      <APILoader akay="GTrnXa5hwXGwgQnTBG28SHBubErMKm3f">
        <Map center="上海">
          {({ BMap, map, container }) => {
            var ac = new BMap.Autocomplete({
              //建立一个自动完成的对象
              input: inputRef.current,
              location: map
            });
            ac.addEventListener("onhighlight", function (e) {
              console.log(">onhighlight>>", e);
            });
            ac.addEventListener("onconfirm", function (e) {
              console.log(">onconfirm>>", e);
            });
            return;
          }}
        </Map>
      </APILoader>
    </div>
  );
};
haungxinyan commented 2 years ago

可以加个antd的Form套着的示例吗 我有预览过你的效果

jaywcjlove commented 2 years ago

百度地图 React 组件是一个壳, BMap, map 对象都扔给你了。我也不知道为什么 antd 的 Form 把 ref 给搞没有了。

如果你非要用 antd 的 form 那么你可以,把我的实例自定义成 antd 的表单控件,按照规则,就可以直接在 Form.Item 中使用了。

自定义方法实例如下:

https://ant.design/components/form-cn/#components-form-demo-customized-form-controls

image

@haungxinyan 你明白?