forked from Abdulbari/sgeUpdated
745 lines
23 KiB
JavaScript
745 lines
23 KiB
JavaScript
import React, { useEffect } from "react";
|
||
import {
|
||
MapContainer,
|
||
Marker,
|
||
Polygon,
|
||
Popup,
|
||
TileLayer,
|
||
Tooltip,
|
||
useMap,
|
||
LayerGroup,
|
||
} from "react-leaflet";
|
||
import "../components/leaflet.css";
|
||
import { useState, useRef } from "react";
|
||
import {
|
||
Button,
|
||
Label,
|
||
Modal,
|
||
ModalHeader,
|
||
ModalBody,
|
||
Row,
|
||
Col,
|
||
Input,
|
||
Card,
|
||
CardHeader,
|
||
CardTitle,
|
||
} from "reactstrap";
|
||
import Select from "react-select";
|
||
import { useTranslation } from "react-i18next";
|
||
import DataInputGroup from "../components/data-input/index.js";
|
||
import { useSelector, useDispatch } from "react-redux";
|
||
import { getCities } from "../redux/actions/cities";
|
||
import { v4 as uuidv4 } from "uuid";
|
||
import { getCity } from "../redux/actions/city";
|
||
import { getDistrict } from "../redux/actions/district";
|
||
// import {
|
||
// getOrganisations,
|
||
// getOrganisationById,
|
||
// } from "../redux/actions/organisations";
|
||
import { getAreasWithCriteria } from "../redux/actions/areas";
|
||
import { ChromePicker } from "react-color";
|
||
import { customFilterForSelect } from "../utility/Utils";
|
||
import { permissionCheck } from "../components/permission-check";
|
||
import { getDataCenters } from "../redux/actions/dataCenter";
|
||
|
||
const ColorPicker = ({ selectedColors, setSelectedColors, index }) => {
|
||
const [showColorPicker, setShowColorPicker] = useState(false);
|
||
|
||
useEffect(() => {
|
||
const storedColors = localStorage.getItem("selectedMapColors");
|
||
if (storedColors) {
|
||
setSelectedColors(JSON.parse(storedColors));
|
||
}
|
||
}, []);
|
||
|
||
useEffect(() => {
|
||
localStorage.setItem("selectedMapColors", JSON.stringify(selectedColors));
|
||
}, [selectedColors]);
|
||
|
||
const handleColorChange = (color) => {
|
||
const rgbaColor = `rgba(${color.rgb.r}, ${color.rgb.g}, ${color.rgb.b}, 0.3)`;
|
||
const updatedColors = [...selectedColors];
|
||
updatedColors[index] = rgbaColor;
|
||
setSelectedColors(updatedColors);
|
||
};
|
||
|
||
const handlePickerOutsideClick = (event) => {
|
||
// Renk seçici dışına tıklama kontrolü
|
||
if (
|
||
event.target.closest(".color-picker-container") === null &&
|
||
event.target.closest(".color-box") === null
|
||
) {
|
||
setShowColorPicker(false);
|
||
}
|
||
};
|
||
|
||
useEffect(() => {
|
||
// Tüm belgeye tıklama olayını dinle
|
||
document.addEventListener("click", handlePickerOutsideClick);
|
||
|
||
return () => {
|
||
// Bileşen kaldırıldığında tıklama olayının dinlemesini kaldır
|
||
document.removeEventListener("click", handlePickerOutsideClick);
|
||
};
|
||
}, []);
|
||
|
||
return (
|
||
<div className="color-picker-container">
|
||
<div
|
||
key={index}
|
||
className="color-box"
|
||
style={{
|
||
backgroundColor: selectedColors[index],
|
||
width: "30px",
|
||
height: "15px",
|
||
display: "inline-block",
|
||
marginRight: "10px",
|
||
cursor: "pointer",
|
||
}}
|
||
onClick={() => setShowColorPicker(true)}
|
||
></div>
|
||
{showColorPicker && (
|
||
<div style={{ position: "absolute", zIndex: 1000 }}>
|
||
<ChromePicker
|
||
color={selectedColors[index]}
|
||
onChange={handleColorChange}
|
||
/>
|
||
</div>
|
||
)}
|
||
</div>
|
||
);
|
||
};
|
||
|
||
const Map = () => {
|
||
const { t } = useTranslation();
|
||
const dispatch = useDispatch();
|
||
|
||
const citiesStore = useSelector((state) => state.cities);
|
||
const cityStore = useSelector((state) => state.city);
|
||
const districtStore = useSelector((state) => state.district);
|
||
// const OrganisationsStore = useSelector((state) => state.organizations);
|
||
const areasStore = useSelector((state) => state.areas);
|
||
const dataCenterStore = useSelector((state) => state.dataCenter);
|
||
|
||
const [cities, setCities] = useState([]);
|
||
const [districts, setDistricts] = useState([]);
|
||
const [neighborhoods, setNeighborhoods] = useState([]);
|
||
// const [organizationOptions, setOrganizationOptions] = useState([]);
|
||
// const organizationId = localStorage.getItem("organizationId");
|
||
// const roleTag = localStorage.getItem("roleTag");
|
||
// const [selectedOrganization, setSelectedOrganization] = useState({
|
||
// label: localStorage.getItem("organizationName"),
|
||
// value: organizationId,
|
||
// });
|
||
const [areasOptions, setAreasOptions] = useState([]);
|
||
|
||
const [done, setDone] = useState(false);
|
||
const [selectedCity, setSelectedCity] = useState(null);
|
||
const [selectedDistrict, setSelectedDistrict] = useState(null);
|
||
const [districtView, setDistrictView] = useState(false);
|
||
const [neighbourhoodView, setNeighbourhoodView] = useState(false);
|
||
const cityRefs = useRef({});
|
||
const districtRefs = useRef({});
|
||
const neighbourhoodRefs = useRef({});
|
||
const [zoom, setZoom] = useState(6.7);
|
||
const [center, setCenter] = useState({ lat: 38.5, lng: 35.27 });
|
||
|
||
const [showDataInputModal, setShowDataInputModal] = useState(false);
|
||
const [inputData, setInputData] = useState({
|
||
// organization: selectedOrganization,
|
||
});
|
||
const [referance, setReferance] = useState(
|
||
Number(localStorage.getItem("referance")) || 1000
|
||
);
|
||
const [referance2, setReferance2] = useState(
|
||
Number(localStorage.getItem("referance2")) || 2000
|
||
);
|
||
const initialColors = [
|
||
"rgba(44,232,44,0.3)",
|
||
"rgba(234,234,17,0.3)",
|
||
"rgba(228,19,19,0.3)",
|
||
];
|
||
const [selectedColors, setSelectedColors] = useState(initialColors);
|
||
|
||
const currentYear = new Date().getFullYear();
|
||
const [year, setYear] = useState({ value: currentYear, label: currentYear });
|
||
const renderYearOptions = () => {
|
||
const years = [];
|
||
for (let year = currentYear; year >= 1990; year--) {
|
||
years.push({ label: year, value: year });
|
||
}
|
||
return years;
|
||
};
|
||
|
||
useEffect(() => {
|
||
dispatch(getCities());
|
||
dispatch(getDataCenters());
|
||
}, []);
|
||
|
||
// useEffect(() => {
|
||
// if (selectedOrganization?.value != "undefined") {
|
||
// dispatch(getAreasWithCriteria(selectedOrganization.value));
|
||
// }
|
||
// }, [selectedOrganization]);
|
||
|
||
useEffect(() => {
|
||
setAreasOptions([]);
|
||
|
||
// Load all areas without organization filter for now
|
||
// You may want to add organization filtering back later if needed
|
||
const citiesOptions =
|
||
areasStore?.areasWithCriteria
|
||
?.map((area) =>
|
||
Array.isArray(area?.cities) // cities'in bir dizi olup olmadığını kontrol edin
|
||
? area.cities.map((city) => ({
|
||
value: city?.id,
|
||
label: city?.name,
|
||
type: "city",
|
||
}))
|
||
: []
|
||
)
|
||
.flat() || []; // Eğer map boş dönerse, `flat` sonrası boş bir dizi kullan
|
||
|
||
const districtsOptions = areasStore?.areasWithCriteria
|
||
?.map((area) => {
|
||
return area?.districts?.map((district) => {
|
||
return {
|
||
value: district?.id,
|
||
label: district?.name + " (" + district?.city?.name + ")",
|
||
type: "district",
|
||
};
|
||
});
|
||
})
|
||
.flat();
|
||
|
||
const neighborhoodsOptions = areasStore?.areasWithCriteria
|
||
?.map((area) => {
|
||
return area?.neighborhoods?.map((neighborhood) => {
|
||
return {
|
||
value: neighborhood?.id,
|
||
label:
|
||
neighborhood?.name +
|
||
" (" +
|
||
neighborhood?.district?.name +
|
||
" / " +
|
||
neighborhood?.district?.city?.name +
|
||
")",
|
||
type: "neighborhood",
|
||
};
|
||
});
|
||
})
|
||
.flat();
|
||
|
||
setAreasOptions([
|
||
...(citiesOptions || []),
|
||
...(districtsOptions || []),
|
||
...(neighborhoodsOptions || []),
|
||
]);
|
||
}, [areasStore]);
|
||
|
||
// useEffect(() => {
|
||
// if (roleTag === "SUPER_ADMIN") {
|
||
// dispatch(getOrganisations());
|
||
// } else {
|
||
// dispatch(getOrganisationById(organizationId));
|
||
// }
|
||
// }, []);
|
||
|
||
const handleDataInputButtonPressed = ({ area, type }) => {
|
||
const areaName =
|
||
type === "neighborhood"
|
||
? `${area?.name} / ${area?.district?.name} / ${area?.district?.city?.name}`
|
||
: type === "district"
|
||
? `${area?.name} / ${area?.city?.name}`
|
||
: area?.name;
|
||
|
||
const areaType =
|
||
type === "district"
|
||
? "district"
|
||
: type === "city"
|
||
? "city"
|
||
: type === "neighborhood"
|
||
? "neighborhood"
|
||
: "";
|
||
setShowDataInputModal(true);
|
||
setInputData({
|
||
...inputData,
|
||
area: { value: area?.id, label: areaName, type: areaType },
|
||
});
|
||
};
|
||
|
||
useEffect(() => {
|
||
if (!citiesStore?.cities || !year?.value) {
|
||
console.error("Cities or year is not defined.");
|
||
return;
|
||
}
|
||
|
||
setCities(() => {
|
||
const updatedCities = citiesStore.cities.map((city) => {
|
||
const mainDataTables = city.mainDataTables
|
||
? city.mainDataTables.filter(
|
||
(data) => data.year === year.value.toString()
|
||
)
|
||
: [];
|
||
|
||
const total = mainDataTables.reduce(
|
||
(acc, data) => acc + (data?.totalEmission || 0),
|
||
0
|
||
);
|
||
|
||
return { ...city, mainDataTables, total };
|
||
});
|
||
|
||
return updatedCities;
|
||
});
|
||
}, [citiesStore?.cities, year?.value]);
|
||
|
||
useEffect(() => {
|
||
if (selectedCity != undefined) {
|
||
dispatch(getCity(selectedCity?.id));
|
||
}
|
||
}, [selectedCity]);
|
||
|
||
useEffect(() => {
|
||
if (selectedDistrict != undefined && selectedDistrict.length != 0) {
|
||
dispatch(getDistrict(selectedDistrict?.id));
|
||
}
|
||
}, [selectedDistrict]);
|
||
|
||
useEffect(() => {
|
||
if (!cityStore?.city?.districts || !year.value) {
|
||
return;
|
||
}
|
||
|
||
setDistricts(() => {
|
||
const updatedDistricts = cityStore.city.districts?.map((district) => {
|
||
const mainDataTables = district.mainDataTables.filter(
|
||
(data) => data.year === year.value.toString()
|
||
);
|
||
const total = mainDataTables.reduce(
|
||
(acc, data) => acc + data.totalEmission,
|
||
0
|
||
);
|
||
return { ...district, mainDataTables, total };
|
||
});
|
||
|
||
return updatedDistricts;
|
||
});
|
||
}, [selectedCity, cityStore?.city, year.value]);
|
||
|
||
useEffect(() => {
|
||
if (!districtStore?.district?.neighborhoods || !year.value) {
|
||
return;
|
||
}
|
||
|
||
setNeighborhoods(() => {
|
||
const updatedNeighborhoods = districtStore.district?.neighborhoods?.map(
|
||
(neighborhood) => {
|
||
const mainDataTables = neighborhood.mainDataTables.filter(
|
||
(data) => data.year === year.value.toString()
|
||
);
|
||
const total = mainDataTables.reduce(
|
||
(acc, data) => acc + data.totalEmission,
|
||
0
|
||
);
|
||
return { ...neighborhood, mainDataTables, total };
|
||
}
|
||
);
|
||
|
||
return updatedNeighborhoods;
|
||
});
|
||
}, [selectedDistrict, districtStore?.district, year.value]);
|
||
|
||
// useEffect(() => {
|
||
// let organizationOptions = [];
|
||
|
||
// if (
|
||
// OrganisationsStore.organization &&
|
||
// OrganisationsStore.organization.length !== 0
|
||
// ) {
|
||
// organizationOptions.push({
|
||
// value: OrganisationsStore.organization.id,
|
||
// label: OrganisationsStore.organization.tag,
|
||
// });
|
||
|
||
// if (OrganisationsStore.organization.children) {
|
||
// organizationOptions = [
|
||
// ...organizationOptions,
|
||
// ...OrganisationsStore.organization.children.map((organization) => ({
|
||
// value: organization.child.id,
|
||
// label: organization.child.tag,
|
||
// })),
|
||
// ];
|
||
// }
|
||
// } else {
|
||
// organizationOptions = OrganisationsStore.dataOrganization.map(
|
||
// (organization) => ({
|
||
// value: organization.id,
|
||
// label: organization.tag,
|
||
// })
|
||
// );
|
||
// }
|
||
|
||
// setOrganizationOptions(organizationOptions);
|
||
// }, [OrganisationsStore]);
|
||
|
||
const renderDataInputModal = () => {
|
||
return (
|
||
<Modal
|
||
isOpen={showDataInputModal}
|
||
toggle={() => setShowDataInputModal(!showDataInputModal)}
|
||
className="modal-dialog-centered"
|
||
size="lg"
|
||
>
|
||
<ModalHeader toggle={() => setShowDataInputModal(!showDataInputModal)}>
|
||
{t("DataInput.dataInput")} - {inputData?.area?.label}
|
||
</ModalHeader>
|
||
<ModalBody>
|
||
<DataInputGroup inputData={inputData} setInputData={setInputData} />
|
||
</ModalBody>
|
||
</Modal>
|
||
);
|
||
};
|
||
|
||
const grayOptions = {
|
||
color: "gray",
|
||
fillColor: "transparent",
|
||
opacity: 1,
|
||
};
|
||
|
||
const greenOptions = {
|
||
color: "gray",
|
||
fillColor: selectedColors[0],
|
||
opacity: 1,
|
||
};
|
||
|
||
const yellowOptions = {
|
||
color: "gray",
|
||
fillColor: selectedColors[1],
|
||
opacity: 1,
|
||
};
|
||
|
||
const redOptions = {
|
||
color: "gray",
|
||
fillColor: selectedColors[2],
|
||
opacity: 1,
|
||
};
|
||
|
||
const pathOptions = (total) => {
|
||
return total > referance2
|
||
? redOptions
|
||
: referance < total && total < referance2
|
||
? yellowOptions
|
||
: total != 0 && total < referance
|
||
? greenOptions
|
||
: grayOptions;
|
||
};
|
||
|
||
const turkeyBounds = [
|
||
[34.42, 44.83],
|
||
[43.45, 25.62],
|
||
];
|
||
|
||
const RenderDistrictView = () => {
|
||
return districts?.map((district, index) => {
|
||
return (
|
||
<Polygon
|
||
key={uuidv4()}
|
||
ref={(c) => {
|
||
districtRefs.current[index] = c;
|
||
if (index === district.length - 1 && !done) {
|
||
setDone(true);
|
||
}
|
||
}}
|
||
fillOpacity={1}
|
||
pathOptions={pathOptions(district.total)}
|
||
positions={convertCoordinates(district.coordinates)}
|
||
eventHandlers={{
|
||
mouseover: () => {
|
||
const district = districtRefs.current[index];
|
||
district.openPopup();
|
||
},
|
||
}}
|
||
>
|
||
<Tooltip permanent direction="center" className="tooltip">
|
||
{district.name}
|
||
</Tooltip>
|
||
{
|
||
<Popup closeButton={true} autoPan={false}>
|
||
<h5 className="w-100 text-center">{district.name}</h5>
|
||
<Button
|
||
className="w-100 mb-1"
|
||
color="primary"
|
||
onClick={() => {
|
||
setSelectedDistrict(district);
|
||
setNeighbourhoodView(true);
|
||
setDistrictView(false);
|
||
setSelectedCity(null);
|
||
setZoom(11.0);
|
||
let convertCordinates = convertCoordinates(
|
||
district.coordinates
|
||
);
|
||
|
||
let length = convertCordinates[0][0][0].length;
|
||
let mlength = ((length + 1) / 2).toFixed(0);
|
||
let lat1 = convertCordinates[0][0][0][0];
|
||
let lng1 = convertCordinates[0][0][0][1];
|
||
let lat2 = convertCordinates[0][0][mlength][0];
|
||
let lng2 = convertCordinates[0][0][mlength][1];
|
||
|
||
setCenter({
|
||
lat: ((lat1 + lat2) / 2).toFixed(2),
|
||
lng: ((lng1 + lng2) / 2).toFixed(2),
|
||
});
|
||
}}
|
||
>
|
||
{t("Areas.neighborhoods")}
|
||
</Button>
|
||
<br></br>
|
||
{areaCheck({ areaId: district.id }) &&
|
||
permissionCheck("dataset_create") && (
|
||
<Button
|
||
className="w-100 mb-1"
|
||
color="primary"
|
||
onClick={() =>
|
||
handleDataInputButtonPressed({
|
||
area: district,
|
||
type: "district",
|
||
})
|
||
}
|
||
>
|
||
{t("DataInput.dataInput")}
|
||
</Button>
|
||
)}
|
||
<br></br>
|
||
<Button
|
||
className="w-100"
|
||
color="primary"
|
||
onClick={() => {
|
||
setDistrictView(false);
|
||
setCenter({ lat: 38, lng: 37 });
|
||
setZoom(6.7);
|
||
}}
|
||
>
|
||
{t("Map.goBack")}
|
||
</Button>
|
||
</Popup>
|
||
}
|
||
</Polygon>
|
||
);
|
||
});
|
||
};
|
||
|
||
const neighborhoodTooltipBackground = (total) => {
|
||
return total > referance2
|
||
? selectedColors[2]
|
||
: referance < total && total < referance2
|
||
? selectedColors[1]
|
||
: total != 0 && total < referance
|
||
? selectedColors[0]
|
||
: "white";
|
||
};
|
||
|
||
const renderNeighbourhoodView = () => {
|
||
return neighborhoods?.map((neighbourhood, index) => {
|
||
return (
|
||
<Marker
|
||
opacity={0}
|
||
zoom={10.75}
|
||
key={uuidv4()}
|
||
ref={(c) => {
|
||
// <--- add city refs to ref object here
|
||
neighbourhoodRefs.current[index] = c;
|
||
if (index === neighbourhood.length - 1 && !done) {
|
||
setDone(true);
|
||
}
|
||
}}
|
||
fillOpacity={1}
|
||
pathOptions={pathOptions(neighbourhood.total)}
|
||
position={[
|
||
Number(neighbourhood?.minLat + neighbourhood?.maxLat) / 2,
|
||
Number(neighbourhood?.minLong + neighbourhood?.maxLong) / 2,
|
||
]}
|
||
eventHandlers={{
|
||
mouseover: () => {
|
||
const neighbourhood = neighbourhoodRefs.current[index];
|
||
neighbourhood.openPopup();
|
||
},
|
||
}}
|
||
>
|
||
<Tooltip permanent direction="center" className="tooltip">
|
||
{neighbourhood.name}
|
||
</Tooltip>
|
||
<Popup closeButton={true} autoPan={false}>
|
||
{areaCheck({ areaId: neighbourhood.id }) &&
|
||
permissionCheck("dataset_create") && (
|
||
<Button
|
||
className="w-100 mb-1"
|
||
color="primary"
|
||
onClick={() =>
|
||
handleDataInputButtonPressed({
|
||
area: neighbourhood,
|
||
type: "neighborhood",
|
||
})
|
||
}
|
||
>
|
||
{t("DataInput.dataInput")}
|
||
</Button>
|
||
)}
|
||
<br></br>
|
||
<Button
|
||
className="w-100"
|
||
color="primary"
|
||
onClick={() => {
|
||
setNeighbourhoodView(false);
|
||
setCenter({ lat: 38, lng: 37 });
|
||
setZoom(6.7);
|
||
}}
|
||
>
|
||
{t("Map.goBack")}
|
||
</Button>
|
||
</Popup>
|
||
</Marker>
|
||
);
|
||
});
|
||
};
|
||
|
||
function ChangeZoom({ center, zoom }) {
|
||
const map = useMap();
|
||
map.setView(center, zoom);
|
||
return null;
|
||
}
|
||
function convertCoordinates(coords) {
|
||
const editedCoordinates = JSON.parse(coords);
|
||
return editedCoordinates;
|
||
}
|
||
|
||
function areaCheck({ areaId }) {
|
||
return areasOptions?.some((area) => areaId === area.value);
|
||
}
|
||
|
||
const renderDataCenterMarkers = () => {
|
||
if (!dataCenterStore?.dataCenters) return null;
|
||
|
||
return (
|
||
<LayerGroup>
|
||
{dataCenterStore.dataCenters.map((dc) => {
|
||
if (!dc.latitude || !dc.longitude) return null;
|
||
|
||
return (
|
||
<Marker key={dc.id} position={[dc.latitude, dc.longitude]}>
|
||
<Popup>
|
||
<div className="data-center-popup">
|
||
<h5 className="mb-2">{dc.dataCenter}</h5>
|
||
<p className="mb-1">
|
||
<strong>{t("DataCenter.number")}:</strong> {dc.number}
|
||
</p>
|
||
<p className="mb-1">
|
||
<strong>{t("DataCenter.externalId")}:</strong>{" "}
|
||
{dc.externalId}
|
||
</p>
|
||
<p className="mb-1">
|
||
<strong>{t("DataCenter.city")}:</strong>{" "}
|
||
{dc.area?.cities?.map((city) => city.name).join(", ") ||
|
||
"-"}
|
||
</p>
|
||
{dc.area && (
|
||
<p className="mb-1">
|
||
<strong>{t("Area")}:</strong> {dc.area.tag}
|
||
</p>
|
||
)}
|
||
{dc.dataCenterEmissionSources?.length > 0 && (
|
||
<p className="mb-1">
|
||
<strong>{t("EmissionSources.emissionSources")}:</strong>{" "}
|
||
{dc.dataCenterEmissionSources.length}
|
||
</p>
|
||
)}
|
||
{dc.ayposURL && (
|
||
<Button
|
||
className="w-100 mb-1"
|
||
color="primary"
|
||
onClick={() => window.open(dc.ayposURL, "_blank")}
|
||
>
|
||
Dashboard
|
||
</Button>
|
||
)}
|
||
</div>
|
||
</Popup>
|
||
<Tooltip>{dc.dataCenter}</Tooltip>
|
||
</Marker>
|
||
);
|
||
})}
|
||
</LayerGroup>
|
||
);
|
||
};
|
||
|
||
return (
|
||
<Card>
|
||
<CardHeader className="border-bottom">
|
||
<CardTitle tag="h4">{t("Map.title")}</CardTitle>
|
||
</CardHeader>
|
||
<div style={{ height: "700px", width: "100%" }}>
|
||
<MapContainer
|
||
center={center}
|
||
zoom={zoom}
|
||
style={{ height: "100%", width: "100%" }}
|
||
>
|
||
<TileLayer
|
||
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
|
||
attribution='© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
|
||
/>
|
||
{renderDataCenterMarkers()}
|
||
{neighbourhoodView
|
||
? renderNeighbourhoodView(selectedDistrict)
|
||
: districtView
|
||
? RenderDistrictView(selectedCity)
|
||
: cities.map((city, index) => {
|
||
return (
|
||
<Polygon
|
||
key={uuidv4()}
|
||
ref={(c) => {
|
||
cityRefs.current[index] = c;
|
||
if (index === cities.length - 1 && !done) {
|
||
setDone(true);
|
||
}
|
||
}}
|
||
fillOpacity={1}
|
||
pathOptions={pathOptions(city.total)}
|
||
positions={convertCoordinates(city.coordinates)}
|
||
eventHandlers={{
|
||
click: () => {
|
||
setSelectedCity(city);
|
||
setDistrictView(true);
|
||
setZoom(8.0);
|
||
|
||
let convertCordinates = convertCoordinates(
|
||
city.coordinates
|
||
);
|
||
let length = convertCordinates[0][0][0].length;
|
||
let mlength = ((length + 1) / 2).toFixed(0);
|
||
let lat1 = convertCordinates[0][0][0][0];
|
||
let lng1 = convertCordinates[0][0][0][1];
|
||
let lat2 = convertCordinates[0][0][mlength][0];
|
||
let lng2 = convertCordinates[0][0][mlength][1];
|
||
setCenter({
|
||
lat: ((lat1 + lat2) / 2).toFixed(2),
|
||
lng: ((lng1 + lng2) / 2).toFixed(2),
|
||
});
|
||
},
|
||
}}
|
||
>
|
||
<Tooltip permanent direction="center">
|
||
{city.name}
|
||
</Tooltip>
|
||
</Polygon>
|
||
);
|
||
})}
|
||
{renderDataInputModal()}
|
||
</MapContainer>
|
||
</div>
|
||
</Card>
|
||
);
|
||
};
|
||
|
||
export default Map;
|