javascript 如何在React Leaflet map上添加一个按钮来创建一个标记?

kb5ga3dv  于 2023-04-19  发布在  Java
关注(0)|答案(1)|浏览(181)

我有一个表单,用户必须在Map上指定他家的位置。在这个表单中,我使用了React Leafletmap。
<Marker>的默认位置是用户的当前位置。我想有一个按钮,每当用户点击它,标记成为可拖动的,并可以放置在用户设置它的任何地方。我还在<Popup>中添加了一个提交按钮,当用户点击它时,标记不得拖动,并且必须更新和保存标记位置以发送到后端。
下面是我的代码:

const SetViewToCurrentLocation = ({location, setLocation}) => {
    const map = useMap();

    function getGeo() {
        navigator.geolocation.getCurrentPosition( 
            (position) =>  {
                setLocation({
                    lat: position.coords.latitude,
                    lng: position.coords.longitude,
                });
            }, 
            (error) => {
                console.log("--------- ERROR WHILE FETCHING LOCATION ----------- ", error);
            },
            { enableHighAccuracy: true, timeout: 15000, maximumAge: 10000}
            ) ;
    }

    useEffect(() => {
        getGeo();
    }, []);

    useEffect(() => {
        if (location.lat && location.lng) {
            map.setView([location.lat, location.lng]);
        }
    }, [location]);

    return null;
};

const CustomizeMarker = ({location, setLocation}) => {
    const [draggable, setDraggable] = useState(false);
    console.log("*************** THE INPUT LOCATION IS ***************** ", location);
    let lat = location.lat;
    let lng = location.lng;
    const [position, setPosition] = useState({lat, lng});
    console.log("-----------------THE POS VALUE IS ------------------- ", position);
    const markerRef = useRef(null);

    const eventHandlers = useMemo(
        () => ({
            dragend() {
            const marker = markerRef.current
            if (marker != null) {
                console.log("+++++++++++ THE OUTPUT OF getLatLng IS ++++++++++++ ", marker.getLatLng());
                setPosition(marker.getLatLng());
                setDraggable(false);
            }
            },
        }),
        [],
    );

    const toggleDraggable = useCallback(() => {
        setDraggable((d) => !d)
    }, []);

    const saveLocation = () => {
        console.log("HELLO WORLD");
    };

    return (
        <>
            <Marker
                draggable={draggable}
                eventHandlers={eventHandlers}
                position={[position.lat, position.lng]}
                ref={markerRef}>
                <Popup minWidth={90}>
                    <Button onClick={saveLocation}>Submit</Button>
                </Popup>
            </Marker>
            <Button  onClick={toggleDraggable} variant='contained' className='edit-location-button'>Edit Your Location</Button>

        </>
    );
}
const EditHome = () => {
    const [location, setLocation] = useState({});

    return (
        <React.Fragment>
            <Box
                component="form"
                sx={{
                "& .MuiTextField-root": { m: 1, maxWidth: "100%"},
                }}
                noValidate
                autoComplete="off"
                dir="ltr"
            >
                    <form>
                        <div style={{ paddingLeft: "2.5rem" }}>
                            <Grid item xs={12}>
                                <h6 style={{ fontWeight: "bold", paddingRight: "4.9rem", marginTop: "0.8rem" }}>
                                    Specify The Location of Your Home on The Map
                                </h6>
                                <div className='map-container'>
                                    <MapContainer center={[0, 0]} zoom={16} scrollWheelZoom={true}>
                                        <TileLayer
                                            attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
                                            url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
                                        />
                                        <GeoSearchField />
                                        <SetViewToCurrentLocation location={location} setLocation={setLocation}/>
                                        {location.lat && location.lng && (<CustomizeMarker location={location} setLocation={setLocation} />)}
                                    </MapContainer>
                                </div>
                            </Grid>
                         </div>
                    </form>
                </Grid>
            </Box>
        </React.Fragment>
    )
}

export default EditHome;

但是我有几个问题。第一个是<Button>在Map中不可见,我想把它设置在Map的左上角,我已经为它定义了下面的CSSclass

.leaflet-container {
    width: 57rem;
    height: 40rem;
}

.map-container {
    position: relative;
}

.edit-location-button {
    position: absolute;
    top: 10px;
    right: 10px;
}

第二个问题是标记的功能及其位置的更改处理程序。
这是我的实现的当前输出:

我将感谢任何帮助。

k2arahey

k2arahey1#

你很接近了。
首先能够看到按钮添加一个zindex值在您的css大enought是在Map之上

.edit-location-button {
  position: absolute;
  top: 10px;
  right: 10px;
  z-index: 10000;
}

第二,你需要使按钮的类型按钮,否则他们似乎是类型提交,这将导致页面刷新每一次点击。它应该是类似的材料ui。我做了纯html。添加type="button"到您的按钮。

<>
      <Marker
        draggable={draggable}
        eventHandlers={eventHandlers}
        position={[position.lat, position.lng]}
        ref={markerRef}
      >
        <Popup minWidth={90}>
          <button type="button" onClick={saveLocation}>
            Submit
          </button>
        </Popup>
      </Marker>
      <button
        type="button"
        onClick={toggleDraggable}
        className="edit-location-button"
      >
        Edit Your Location
      </button>
   </>

这个功能看起来还不错,可以用。唯一的一点是,你不需要在Marker组件中添加编辑位置按钮,因为它们是不相关的。我把它放在了你已经拥有的Fragment的外面。此外,要在单击提交时获得坐标,你需要调用

const saveLocation = () => {
     if (markerRef.current)
      console.log(
        "+++++++++++ THE OUTPUT OF getLatLng IS ++++++++++++ ",
        markerRef.current.getLatLng()
      );
  };

而不是在dragend回调中记录标记。
您可以在demo中看到结果。

相关问题