在 React Leaflet 的地图中定位我
Location me in map from React Leaflet
我想问一下我是否使用 React Leaflet (https://react-leaflet.js.org/) 中的地图,但是如何向地图添加位置按钮?像这样我给出红色箭头的图像中位置按钮的示例
和link中的图片:
Example of an arrow Location Me
An example on my map where I want to add location Me
以及如何显示位置按钮,你从我的编码中将其保存在哪里?
import { React, useState } from 'react'
import {
LayersControl,
MapContainer,
Marker,
Popup,
TileLayer,
useMapEvents,
} from 'react-leaflet'
const { BaseLayer } = LayersControl
function LocationMarker() {
const [position, setPosition] = useState(null)
const map = useMapEvents({
click() {
map.locate()
},
locationfound(e) {
setPosition(e.latlng)
map.flyTo(e.latlng, map.getZoom())
},
})
return position === null ? null : (
<Marker position={position}>
<Popup>You are here</Popup>
</Marker>
)
}
function MapsMe() {
return (
<div className="flex ml-auto">
<div className="w-4/5">
<MapContainer center={51.505, -0.09} zoom=20>
<LayersControl>
<BaseLayer checked name="OpenStreetMap">
<TileLayer
attribution='© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png "
/>
</BaseLayer>
<LocationMarker />
</LayersControl>
</MapContainer>
</div>
</div>
)
}
export default MapsMe
如果您需要获得与图片中完全相同的结果,您需要使用
leaflet-easybutton
图书馆 font-awesome
。否则,您可以通过扩展传单控件轻松构建自己的图标。
安装它们:
npm i leaflet-easybutton
npm i font-awesome
导入它们:
import "leaflet-easybutton/src/easy-button.js";
import "leaflet-easybutton/src/easy-button.css";
import "font-awesome/css/font-awesome.min.css";
使用 fa-map-marker 图标实例化 L.easy-button
并在回调中保存位置并将地图移动到用户位置。
export default function Map() {
const [map, setMap] = useState(null);
const [position, setPosition] = useState(null);
useEffect(() => {
if (!map) return;
L.easyButton("fa-map-marker", () => {
map.locate().on("locationfound", function (e) {
setPosition(e.latlng);
map.flyTo(e.latlng, map.getZoom());
});
}).addTo(map);
}, [map]);
return (
<MapContainer
center={[51.505, -0.09]}
zoom={20}
style={{ height: "100vh" }}
whenCreated={setMap}
>
...
}
这里是demo。当你打开它时,图标不会显示,因为 svg 图标和 codesandbox 存在一个已知问题,但在本地你不应该有任何问题。
这就是我解决同样问题的方法。为传单控件创建了一个可重用的组件。轻松处理传单的好方法 类.
import L from "leaflet";
import React, { useEffect, useRef } from "react";
const ControlClasses = {
bottomleft: "leaflet-bottom leaflet-left",
bottomright: "leaflet-bottom leaflet-right",
topleft: "leaflet-top leaflet-left",
topright: "leaflet-top leaflet-right",
};
type ControlPosition = keyof typeof ControlClasses;
interface LeafLetControlProps {
position?: ControlPosition;
}
const LeafletControl: React.FC<LeafLetControlProps> = ({
position,
children,
}) => {
const divRef = useRef(null);
useEffect(() => {
if (divRef.current) {
L.DomEvent.disableClickPropagation(divRef.current);
L.DomEvent.disableScrollPropagation(divRef.current);
}
});
return (
<div ref={divRef} className={position && ControlClasses[position]}>
<div className={"leaflet-control"}>{children}</div>
</div>
);
};
export default LeafletControl;
使用具有所需功能的传单控件组件。
import { ActionIcon } from "@mantine/core";
import React, { useState } from "react";
import { useMapEvents } from "react-leaflet";
import { CurrentLocation } from "tabler-icons-react";
import LeafletControl from "./LeafletControl";
interface LeadletMyPositionProps {}
const LeadletMyPosition: React.FC<LeadletMyPositionProps> = ({}) => {
const [loading, setLoading] = useState<boolean>(false);
const map = useMapEvents({
locationfound(e) {
map.flyTo(e.latlng);
setLoading(false);
},
});
return (
<LeafletControl position={"topright"}>
<ActionIcon
onClick={() => {
setLoading(true);
map.locate();
}}
loading={loading}
variant={"transparent"}
>
<CurrentLocation />
</ActionIcon>
</LeafletControl>
);
};
export default LeadletMyPosition;
我想问一下我是否使用 React Leaflet (https://react-leaflet.js.org/) 中的地图,但是如何向地图添加位置按钮?像这样我给出红色箭头的图像中位置按钮的示例
和link中的图片:
Example of an arrow Location Me
An example on my map where I want to add location Me
以及如何显示位置按钮,你从我的编码中将其保存在哪里?
import { React, useState } from 'react'
import {
LayersControl,
MapContainer,
Marker,
Popup,
TileLayer,
useMapEvents,
} from 'react-leaflet'
const { BaseLayer } = LayersControl
function LocationMarker() {
const [position, setPosition] = useState(null)
const map = useMapEvents({
click() {
map.locate()
},
locationfound(e) {
setPosition(e.latlng)
map.flyTo(e.latlng, map.getZoom())
},
})
return position === null ? null : (
<Marker position={position}>
<Popup>You are here</Popup>
</Marker>
)
}
function MapsMe() {
return (
<div className="flex ml-auto">
<div className="w-4/5">
<MapContainer center={51.505, -0.09} zoom=20>
<LayersControl>
<BaseLayer checked name="OpenStreetMap">
<TileLayer
attribution='© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png "
/>
</BaseLayer>
<LocationMarker />
</LayersControl>
</MapContainer>
</div>
</div>
)
}
export default MapsMe
如果您需要获得与图片中完全相同的结果,您需要使用
leaflet-easybutton
图书馆 font-awesome
。否则,您可以通过扩展传单控件轻松构建自己的图标。
安装它们:
npm i leaflet-easybutton
npm i font-awesome
导入它们:
import "leaflet-easybutton/src/easy-button.js";
import "leaflet-easybutton/src/easy-button.css";
import "font-awesome/css/font-awesome.min.css";
使用 fa-map-marker 图标实例化 L.easy-button
并在回调中保存位置并将地图移动到用户位置。
export default function Map() {
const [map, setMap] = useState(null);
const [position, setPosition] = useState(null);
useEffect(() => {
if (!map) return;
L.easyButton("fa-map-marker", () => {
map.locate().on("locationfound", function (e) {
setPosition(e.latlng);
map.flyTo(e.latlng, map.getZoom());
});
}).addTo(map);
}, [map]);
return (
<MapContainer
center={[51.505, -0.09]}
zoom={20}
style={{ height: "100vh" }}
whenCreated={setMap}
>
...
}
这里是demo。当你打开它时,图标不会显示,因为 svg 图标和 codesandbox 存在一个已知问题,但在本地你不应该有任何问题。
这就是我解决同样问题的方法。为传单控件创建了一个可重用的组件。轻松处理传单的好方法 类.
import L from "leaflet";
import React, { useEffect, useRef } from "react";
const ControlClasses = {
bottomleft: "leaflet-bottom leaflet-left",
bottomright: "leaflet-bottom leaflet-right",
topleft: "leaflet-top leaflet-left",
topright: "leaflet-top leaflet-right",
};
type ControlPosition = keyof typeof ControlClasses;
interface LeafLetControlProps {
position?: ControlPosition;
}
const LeafletControl: React.FC<LeafLetControlProps> = ({
position,
children,
}) => {
const divRef = useRef(null);
useEffect(() => {
if (divRef.current) {
L.DomEvent.disableClickPropagation(divRef.current);
L.DomEvent.disableScrollPropagation(divRef.current);
}
});
return (
<div ref={divRef} className={position && ControlClasses[position]}>
<div className={"leaflet-control"}>{children}</div>
</div>
);
};
export default LeafletControl;
使用具有所需功能的传单控件组件。
import { ActionIcon } from "@mantine/core";
import React, { useState } from "react";
import { useMapEvents } from "react-leaflet";
import { CurrentLocation } from "tabler-icons-react";
import LeafletControl from "./LeafletControl";
interface LeadletMyPositionProps {}
const LeadletMyPosition: React.FC<LeadletMyPositionProps> = ({}) => {
const [loading, setLoading] = useState<boolean>(false);
const map = useMapEvents({
locationfound(e) {
map.flyTo(e.latlng);
setLoading(false);
},
});
return (
<LeafletControl position={"topright"}>
<ActionIcon
onClick={() => {
setLoading(true);
map.locate();
}}
loading={loading}
variant={"transparent"}
>
<CurrentLocation />
</ActionIcon>
</LeafletControl>
);
};
export default LeadletMyPosition;