我正在尝试实现一个简单的地图编辑器,在类型记录上使用React传单,并结合react-传单绘制的EditControl。
控件应该在其属性中接收一组块(块基本上是带有serverId的多边形)和一组处理程序,在添加/更新/删除块时调用。
显示初始块很好,但是当一个块被编辑或删除时,我无法获得修改/删除块的serverId。
如何检索这些信息?
以下是我的实现:
import React, { FC } from 'react';
import { MapContainer, TileLayer, FeatureGroup, Polygon } from 'react-leaflet';
import { EditControl } from 'react-leaflet-draw';
import { LatLng } from 'leaflet';
import 'leaflet-draw/dist/leaflet.draw.css';
import 'leaflet-fullscreen/dist/Leaflet.fullscreen';
import 'leaflet-fullscreen/dist/leaflet.fullscreen.css';
import { If, Then } from 'react-if';
export interface Coordinate {
latitude: number;
longitude: number;
}
export interface Block {
serverId: number;
coordinates: Coordinate[];
}
interface MapEditorProps {
blocks: Block[];
onBlockCreated?: (coordinates: Coordinate[]) => void;
onBlockDeleted?: (blockId: number) => void;
onBlockUpdated?: (block: Block) => void;
}
const MapEditor: FC<MapEditorProps> = ({ blocks, onBlockCreated, onBlockDeleted, onBlockUpdated }: MapEditorProps) => {
const onCreated = (e) => {
const { layerType, layer } = e;
if (layerType === 'polygon') {
if (onBlockCreated !== undefined) {
const latlngs = layer.getLatLngs()[0];
onBlockCreated(latlngs.map((l: LatLng) => ({ latitude: l.lat, longitude: l.lng } as Coordinate)));
}
}
};
const onDeleted = (e) => {
if (onBlockDeleted !== undefined) {
// How to fetch the id of the deleted block?
// const blockId = ???
// onBlockDeleted (polygonId);
}
};
const onUpdated = (e) => {
if (onBlockUpdated !== undefined) {
// How to fetch the modified block?
// const updatedBlock = ???;
// onBlockUpdated (updatedBlock);
}
};
return (
<div>
<MapContainer
style={{ height: '100vh', width: '100wh' }}
center={{ lat: 44.72, lng: 8.4 }}
zoom={15}
fullscreenControl
>
<TileLayer
attribution=""
url="https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}"
/>
<FeatureGroup>
<EditControl
position="topright"
onCreated={onCreated}
onEdited={onUpdated}
onDeleted={onDeleted}
draw={{
rectangle: false,
polyline: false,
circle: false,
circlemarker: false,
marker: true
}}
/>
<If condition={blocks !== null}>
<Then>
{blocks.map((block) => (
<Polygon key={block.serverId} positions={block.coordinates.map((c) => [c.latitude, c.longitude])} />
))}
</Then>
</If>
</FeatureGroup>
</MapContainer>
</div>
);
};
export default MapEditor;发布于 2021-12-14 07:33:02
最后,我创建了一个自定义多边形,PolygonBlock及其相关的PolygonBlock新的PolygonBlockProps接口使用serverId扩展了原始PolygonProps:
export interface PolygonBlockProps extends PolygonProps {
serverId?: number;
}
const PolygonBlock: FC<PolygonBlockProps> = (props: PolygonBlockProps) => <Polygon {...props} />;然后用新的PolygonBlocks填充地图。
{blocks.map((block) => (
<PolygonBlock
key={block.serverId}
positions={block.coordinates.map((c) => [c.latitude, c.longitude])}
serverId={block.serverId}
/>
))}在处理事件时,获取所涉及的多边形,以检查事件的.layers.getLayers(),,该事件的serverId现在可在.options成员中使用:
const onUpdated = (e) => {
if (onBlockUpdated !== undefined) {
const rawModifiedLayers = e.layers.getLayers();
// Fetch the modified blocks
const updatedBlocks = rawModifiedLayers.map((polygon) => ({
serverId: polygon.options.serverId,
coordinates: polygon.getLatLngs()[0].map((l: LatLng) => ({ latitude: l.lat, longitude: l.lng } as Coordinate))
}));
onBlockUpdated(updatedBlocks);
}
};下面是完整的代码:
import React, { FC } from 'react';
import { MapContainer, TileLayer, FeatureGroup, Polygon, PolygonProps } from 'react-leaflet';
import { EditControl } from 'react-leaflet-draw';
import { LatLng } from 'leaflet';
import 'leaflet-draw/dist/leaflet.draw.css';
import 'leaflet-fullscreen/dist/Leaflet.fullscreen';
import 'leaflet-fullscreen/dist/leaflet.fullscreen.css';
import { If, Then } from 'react-if';
export interface PolygonBlockProps extends PolygonProps {
serverId?: number;
}
const PolygonBlock: FC<PolygonBlockProps> = (props: PolygonBlockProps) => <Polygon {...props} />;
export interface Coordinate {
latitude: number;
longitude: number;
}
export interface Block {
serverId: number;
coordinates: Coordinate[];
}
interface MapEditorProps {
blocks: Block[];
onBlockCreated?: (coordinates: Coordinate[]) => void;
onBlocksDeleted?: (blockIds: number[]) => void;
onBlockUpdated?: (blocks: Block[]) => void;
}
const MapEditor: FC<MapEditorProps> = ({ blocks, onBlockCreated, onBlocksDeleted, onBlockUpdated }: MapEditorProps) => {
const onCreated = (e) => {
const { layerType, layer } = e;
if (layerType === 'polygon') {
if (onBlockCreated !== undefined) {
const latlngs = layer.getLatLngs()[0];
onBlockCreated(latlngs.map((l: LatLng) => ({ latitude: l.lat, longitude: l.lng } as Coordinate)));
}
}
};
const onDeleted = (e) => {
if (onBlocksDeleted !== undefined) {
const rawModifiedLayers = e.layers.getLayers();
// Fetch the modified block ids
const deletedBlockIds = rawModifiedLayers.map((polygon) => polygon.options.serverId);
onBlocksDeleted(deletedBlockIds);
}
};
const onUpdated = (e) => {
if (onBlockUpdated !== undefined) {
const rawModifiedLayers = e.layers.getLayers();
// Fetch the modified blocks
const updatedBlocks = rawModifiedLayers.map((polygon) => ({
serverId: polygon.options.serverId,
coordinates: polygon.getLatLngs()[0].map((l: LatLng) => ({ latitude: l.lat, longitude: l.lng } as Coordinate))
}));
onBlockUpdated(updatedBlocks);
}
};
return (
<div>
<MapContainer
style={{ height: '100vh', width: '100wh' }}
// center={{ lat: 44.710293, lng: 8.081944 }}
center={{ lat: 44.72, lng: 8.4 }}
zoom={15}
// scrollWheelZoom={false}
fullscreenControl
>
<TileLayer
attribution=""
url="https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}"
/>
<FeatureGroup>
<EditControl
position="topright"
onCreated={onCreated}
onEdited={onUpdated}
onDeleted={onDeleted}
draw={{
rectangle: false,
polyline: false,
circle: false,
circlemarker: false,
marker: true
}}
/>
<If condition={blocks !== null}>
<Then>
{blocks.map((block) => (
<PolygonBlock
key={block.serverId}
positions={block.coordinates.map((c) => [c.latitude, c.longitude])}
serverId={block.serverId}
/>
))}
</Then>
</If>
</FeatureGroup>
</MapContainer>
</div>
);
};
export default MapEditor;https://stackoverflow.com/questions/70339141
复制相似问题