gpt4 book ai didi

javascript - React js从路径中删除点更新多边形

转载 作者:行者123 更新时间:2023-12-03 07:11:12 25 4
gpt4 key购买 nike

enter image description here

我有以下 map ,正如您在 map 上应该看到的那样,我有一个多边形和标记,它们是多边形的主要点,下面我打印了多边形的主要点,即标记。

我为用户提供了删除多边形点的可能性,如下图所示,通过单击 X,点被删除。

问题是,当我点击 X 时,该点作为标记被消除,但它似乎仍然是多边形的固定点,这确实不应该,多边形应该改变其形状, 基于淘汰点。

我不明白我哪里错了。你能帮我一些忙吗?

链接:codesandbox

索引:

import React from "react";
import ReactDOM from "react-dom";

import Map from "./Map";
import "./styles.css";

//import { makeStyles } from "@material-ui/core/styles";
import ExpansionPanel from "@material-ui/core/ExpansionPanel";
import ExpansionPanelSummary from "@material-ui/core/ExpansionPanelSummary";
import ExpansionPanelDetails from "@material-ui/core/ExpansionPanelDetails";
import Typography from "@material-ui/core/Typography";
import ExpandMoreIcon from "@material-ui/icons/ExpandMore";
import ClearIcon from "@material-ui/icons/Clear";
import TextField from "@material-ui/core/TextField";

const API_KEY = "MY_API_KEY";

/*const useStyles = makeStyles(theme => ({
root: {
width: "100%"
},
heading: {
fontSize: theme.typography.pxToRem(15),
fontWeight: theme.typography.fontWeightRegular
}
}));*/

const useStyles = theme => ({
root: {
width: "100%"
},
heading: {
fontSize: theme.typography.pxToRem(15),
fontWeight: theme.typography.fontWeightRegular
}
});

const center = {
lat: 38.9065495,
lng: -77.0518192
};

//const classes = useStyles();
//className={classes.heading}

export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
paths: [
{ lat: 38.97330905858943, lng: -77.10469090410157 },
{ lat: 38.9209748864926, lng: -76.9083102888672 },
{ lat: 38.82689001319151, lng: -76.92204319902345 },
{ lat: 38.82261046915962, lng: -77.0181735701172 },
{ lat: 38.90174038629909, lng: -77.14314305253907 }
]
};
}

render() {
const { paths } = this.state;

return (
<div className="App2">
<Map
apiKey={API_KEY}
center={center}
paths={paths}
point={paths => this.setState({ paths })}
/>
{paths.map((pos, key) => {
return (
<ExpansionPanel key={key}>
<ExpansionPanelSummary
expandIcon={<ExpandMoreIcon />}
aria-controls="panel1a-content"
id="panel1a-header"
>
<ClearIcon
style={{ color: "#dc004e" }}
onClick={() => {
paths.splice(key, 1);
console.log(paths);
this.setState({ paths: paths });
}}
/>
<Typography>Point #{key}</Typography>
</ExpansionPanelSummary>
<ExpansionPanelDetails>
<TextField
fullWidth
key={"lat" + key}
label="Latitude"
type="text"
value={pos.lat}
disabled={true}
/>
<TextField
fullWidth
key={"lng" + key}
label="Longitude"
type="text"
value={pos.lng}
disabled={true}
/>
</ExpansionPanelDetails>
</ExpansionPanel>
);
})}
</div>
);
}
}

//export default withStyles(useStyles)(App);
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

map :

import React, { useState, useRef, useCallback } from "react";
import {
LoadScript,
GoogleMap,
DrawingManager,
Polygon,
Marker
} from "@react-google-maps/api";

import "./styles.css";
const libraries = ["drawing"];

const options = {
drawingControl: true,
drawingControlOptions: {
drawingModes: ["polygon"]
},
polygonOptions: {
fillColor: `#2196F3`,
strokeColor: `#2196F3`,
fillOpacity: 0.5,
strokeWeight: 2,
clickable: true,
editable: true,
draggable: true,
zIndex: 1
}
};

class LoadScriptOnlyIfNeeded extends LoadScript {
componentDidMount() {
const cleaningUp = true;
const isBrowser = typeof document !== "undefined"; // require('@react-google-maps/api/src/utils/isbrowser')
const isAlreadyLoaded =
window.google &&
window.google.maps &&
document.querySelector("body.first-hit-completed"); // AJAX page loading system is adding this class the first time the app is loaded
if (!isAlreadyLoaded && isBrowser) {
// @ts-ignore
if (window.google && !cleaningUp) {
console.error("google api is already presented");
return;
}

this.isCleaningUp().then(this.injectScript);
}

if (isAlreadyLoaded) {
this.setState({ loaded: true });
}
}
}

export default function Map({ apiKey, center, paths = [], point }) {
const [path, setPath] = useState(paths);
const [state, setState] = useState({
drawingMode: "polygon"
});

const noDraw = () => {
setState(function set(prevState) {
return Object.assign({}, prevState, {
drawingMode: "maker"
});
});
};

const onPolygonComplete = React.useCallback(
function onPolygonComplete(poly) {
const polyArray = poly.getPath().getArray();
let paths = [];
polyArray.forEach(function(path) {
paths.push({ lat: path.lat(), lng: path.lng() });
});
setPath(paths);
console.log("onPolygonComplete", paths);
point(paths);
noDraw();
poly.setMap(null);
},
[point]
);

/*const onLoad = React.useCallback(function onLoad(map) {
//console.log(map);
}, []);

const onDrawingManagerLoad = React.useCallback(function onDrawingManagerLoad(
drawingManager
) {
// console.log(drawingManager);
},
[]);*/

// Define refs for Polygon instance and listeners
const polygonRef = useRef(null);
const listenersRef = useRef([]);

// Call setPath with new edited path
const onEdit = useCallback(() => {
if (polygonRef.current) {
const nextPath = polygonRef.current
.getPath()
.getArray()
.map(latLng => {
return { lat: latLng.lat(), lng: latLng.lng() };
});
setPath(nextPath);
point(nextPath);
}
}, [setPath, point]);

// Bind refs to current Polygon and listeners
const onLoad = useCallback(
polygon => {
polygonRef.current = polygon;
const path = polygon.getPath();
listenersRef.current.push(
path.addListener("set_at", onEdit),
path.addListener("insert_at", onEdit),
path.addListener("remove_at", onEdit)
);
},
[onEdit]
);

// Clean up refs
const onUnmount = useCallback(() => {
listenersRef.current.forEach(lis => lis.remove());
polygonRef.current = null;
}, []);

console.log(path);

return (
<div className="App">
<LoadScriptOnlyIfNeeded
id="script-loader"
googleMapsApiKey={apiKey}
libraries={libraries}
language="it"
region="us"
>
<GoogleMap
mapContainerClassName="App-map"
center={center}
zoom={10}
version="weekly"
//onLoad={onLoad}
>
{path.length === 0 ? (
<DrawingManager
drawingMode={state.drawingMode}
options={options}
onPolygonComplete={onPolygonComplete}
//onLoad={onDrawingManagerLoad}
editable
draggable
// Event used when manipulating and adding points
onMouseUp={onEdit}
// Event used when dragging the whole Polygon
onDragEnd={onEdit}
/>
) : (
<Polygon
options={{
fillColor: `#2196F3`,
strokeColor: `#2196F3`,
fillOpacity: 0.5,
strokeWeight: 2
}}
// Make the Polygon editable / draggable
editable
draggable
path={path}
// Event used when manipulating and adding points
onMouseUp={onEdit}
// Event used when dragging the whole Polygon
onDragEnd={onEdit}
onLoad={onLoad}
onUnmount={onUnmount}
/>
)}
{path.map((pos, key) => {
return <Marker key={key} label={"" + key} position={pos} />;
})}
</GoogleMap>
</LoadScriptOnlyIfNeeded>
</div>
);
}

最佳答案

将 useEffect 添加到 Map 组件以更新每个渲染的 paths

export default function Map({ apiKey, center, paths = [], point }) {
const [path, setPath] = useState();
const [state, setState] = useState({
drawingMode: "polygon"
});
useEffect(() => {
setPath(paths);
}, [paths]);
.
.
.

并使用过滤器代替拼接

在 React 中你不应该直接改变状态。

 onClick={() => {
this.setState({
paths: this.state.paths.filter((_, i) => i !== key)
});

或者像下面这样拼接

 onClick={() => {

const paths = this.state.paths;
this.setState({
paths: [...paths.slice(0,key), ...paths.slice(key+1)]})

}}

codesandbox

关于javascript - React js从路径中删除点更新多边形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59627596/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com