diff --git a/client/src/components/map/MapComponent.tsx b/client/src/components/map/MapComponent.tsx index 49e6253..67fec24 100644 --- a/client/src/components/map/MapComponent.tsx +++ b/client/src/components/map/MapComponent.tsx @@ -3,8 +3,7 @@ import 'ol/ol.css' import { Modify } from 'ol/interaction' import { ImageStatic, Vector as VectorSource } from 'ol/source' import Feature from 'ol/Feature' -import { IRectCoords, SatelliteMapsProvider } from '../../interfaces/map' -import { Extent, getCenter } from 'ol/extent' +import { getCenter } from 'ol/extent' import { highlightStyleRed, highlightStyleYellow } from './MapStyles' import { customMapSource, googleMapsSatelliteSource, yandexMapsSatelliteSource } from './MapSources' import { Geometry, Point } from 'ol/geom' @@ -14,33 +13,31 @@ import { addInteractions, getFeatureByEntityId, handleImageDrop, loadFeatures, p import useSWR, { SWRConfiguration } from 'swr' import { fetcher } from '../../http/axiosInstance' import { BASE_URL } from '../../constants' -import { IconBoxMultiple, IconBoxPadding, IconChevronLeft, IconPlus, IconUpload, IconX, } from '@tabler/icons-react' -import { ICitySettings, IDistrict, IFigure, ILine } from '../../interfaces/gis' +import { IconBoxPadding, IconChevronLeft, } from '@tabler/icons-react' +import { ICitySettings, IFigure, ILine } from '../../interfaces/gis' import axios from 'axios' import MapToolbar from './MapToolbar/MapToolbar' import MapStatusbar from './MapStatusbar/MapStatusbar' -import { setAlignMode, setSatMapsProvider, setTypeRoles, useMapStore, setMapLabel, } from '../../store/map' +import { setAlignMode, setTypeRoles, useMapStore, setMapLabel, } from '../../store/map' import { useThrottle } from '@uidotdev/usehooks' import ObjectTree from '../Tree/ObjectTree' import { setCurrentObjectId, setSelectedDistrict, setSelectedRegion, setSelectedYear, useObjectsStore } from '../../store/objects' -import MapLayers from './MapLayers/MapLayers' import ObjectParameters from './ObjectParameters/ObjectParameters' import TabsPane, { ITabsPane } from './TabsPane/TabsPane' //import { useSearchParams } from 'react-router-dom' import GeoJSON from 'ol/format/GeoJSON' import MapLegend from './MapLegend/MapLegend' -import GisService from '../../services/GisService' import MapMode from './MapMode' -import { satMapsProviders, schemas } from '../../constants/map' import MapPrint from './MapPrint/MapPrint' -import { Field, Menu, MenuButton, MenuList, MenuPopover, MenuTrigger, Combobox, Option, Button, Divider, Spinner, Portal, Dropdown, Tooltip, Drawer, DrawerHeader, DrawerBody, Text, Link, List } from '@fluentui/react-components' -import { IRegion } from '../../interfaces/fuel' +import { Combobox, Option, Button, Divider, Spinner, Portal, Tooltip, Drawer } from '@fluentui/react-components' import { useAppStore } from '../../store/app' -import { getDistrictData, getRegionData, setDistrictsData, setRegionsData } from '../../store/regions' -import { ArrowLeft24Regular } from '@fluentui/react-icons' +import { setDistrictsData, setRegionsData } from '../../store/regions' import View from 'ol/View' import { Icon, Style } from 'ol/style' import { fromLonLat } from 'ol/proj' +import MapRegionSelect from './MapRegionSelect/MapRegionSelect' +import MapLayersSelect from './MapLayers/MapLayersSelect' +import MapObjectSearch from './MapObjectSearch/MapObjectSearch' const swrOptions: SWRConfiguration = { revalidateOnFocus: false @@ -72,8 +69,7 @@ const MapComponent = ({ const { selectedYear, currentObjectId, selectedRegion, selectedDistrict } = useObjectsStore().id[id] const { mode, map, currentTool, alignMode, satMapsProvider, - selectedObjectType, file, measureDraw, - polygonExtent, rectCoords, draw, snap, translate, + selectedObjectType, measureDraw, draw, snap, translate, drawingLayerSource, satLayer, staticMapLayer, figuresLayer, linesLayer, regionsLayer, districtBoundLayer, districtsLayer, @@ -275,13 +271,6 @@ const MapComponent = ({ } }, [satMapsProvider, satLayer]) - // Upload map overlay - const submitOverlay = async (file: File | null, polygonExtent: Extent | undefined, rectCoords: IRectCoords | undefined) => { - await GisService.uploadOverlay(file, polygonExtent, rectCoords).then(res => { - console.log(res) - }) - } - // const { data: nodes } = useSWR('/nodes/all', () => fetcher('/nodes/all', BASE_URL.ems), { revalidateOnFocus: false }) // useEffect(() => { @@ -303,9 +292,6 @@ const MapComponent = ({ // } // }, [nodes, nodeLayerSource]) - const [searchObject, setSearchObject] = useState("") - const throttledSearchObject = useThrottle(searchObject, 500) - useEffect(() => { if (!selectedObjectType || !map) return @@ -367,12 +353,6 @@ const MapComponent = ({ return res }), swrOptions) - const { data: searchData } = useSWR( - throttledSearchObject !== "" && selectedDistrict && selectedYear ? `/general/search/objects?q=${throttledSearchObject}&id_city=${selectedDistrict}&year=${selectedYear}` : null, - (url) => fetcher(url, BASE_URL.ems), - swrOptions - ) - const { data: figuresData, isValidating: figuresValidating } = useSWR( selectedDistrict && selectedYear ? `/gis/figures/all?city_id=${selectedDistrict}&year=${selectedYear}&offset=0&limit=${10000}` : null, (url) => axios.get(url, { @@ -609,214 +589,18 @@ const MapComponent = ({ {active &&
- { - if (data.optionValue) { - setCurrentObjectId(id, data.optionValue); - setSearchObject( - searchData?.find((item: any) => item.id_object.toString() === data.optionValue)?.value ?? "" - ); - } - }} - onChange={(e) => { - setSearchObject(e.currentTarget.value); // free typing like Mantine's onChange - }} - clearable - style={{ minWidth: 'auto' }} - > - {searchData - ? searchData.map((item: { value: string; id_object: string }) => ( - - )) - : null} - +
- - - - +
}
- - {!!selectedRegion && !selectedYear && - -
e.preventDefault()} onDrop={(e) => handleImageDrop(e, id)}> diff --git a/client/src/components/map/MapLayers/MapLayersSelect.tsx b/client/src/components/map/MapLayers/MapLayersSelect.tsx new file mode 100644 index 0000000..4c5bb09 --- /dev/null +++ b/client/src/components/map/MapLayers/MapLayersSelect.tsx @@ -0,0 +1,67 @@ +import { Button, Dropdown, Field, Menu, MenuButton, MenuList, MenuPopover, MenuTrigger, Option } from '@fluentui/react-components'; +import { IconBoxMultiple, IconPlus, IconUpload } from '@tabler/icons-react'; +import MapLayers from './MapLayers'; +import { setSatMapsProvider, useMapStore } from '../../../store/map'; +import { satMapsProviders } from '../../../constants/map'; +import { IRectCoords, SatelliteMapsProvider } from '../../../interfaces/map'; +import GisService from '../../../services/GisService'; +import { Extent } from 'ol/extent'; + +const MapLayersSelect = ({ + map_id +}: { + map_id: string +}) => { + const { map, satMapsProvider, file, polygonExtent, rectCoords } = useMapStore().id[map_id] + + // Upload map overlay + const submitOverlay = async (file: File | null, polygonExtent: Extent | undefined, rectCoords: IRectCoords | undefined) => { + await GisService.uploadOverlay(file, polygonExtent, rectCoords).then(res => { + console.log(res) + }) + } + + return ( + + + }>Слои + + + + + Настройка видимости слоёв + +
+ + provider.value === satMapsProvider)?.label} + selectedOptions={[satMapsProvider]} + onOptionSelect={(_ev, data) => { + if (data.optionValue) { + setSatMapsProvider(map_id, data.optionValue as SatelliteMapsProvider); + } + }} + > + {satMapsProviders.map((provider) => ( + + ))} + + +
+
+
+ +
+
+
+ ) +} + +export default MapLayersSelect \ No newline at end of file diff --git a/client/src/components/map/MapObjectSearch/MapObjectSearch.tsx b/client/src/components/map/MapObjectSearch/MapObjectSearch.tsx new file mode 100644 index 0000000..78e92c3 --- /dev/null +++ b/client/src/components/map/MapObjectSearch/MapObjectSearch.tsx @@ -0,0 +1,58 @@ +import { Combobox, Option } from '@fluentui/react-components'; +import { useState } from 'react' +import { setCurrentObjectId, useObjectsStore } from '../../../store/objects'; +import useSWR, { SWRConfiguration } from 'swr'; +import { useThrottle } from '@uidotdev/usehooks'; +import { BASE_URL } from '../../../constants'; +import { fetcher } from '../../../http/axiosInstanceNest'; + +const swrOptions: SWRConfiguration = { + revalidateOnFocus: false +} + +const MapObjectSearch = ({ + map_id +}: { + map_id: string +}) => { + const [searchObject, setSearchObject] = useState("") + const throttledSearchObject = useThrottle(searchObject, 500) + + const { selectedYear, selectedDistrict } = useObjectsStore().id[map_id] + + const { data: searchData } = useSWR( + throttledSearchObject !== "" && selectedDistrict && selectedYear ? `/general/search/objects?q=${throttledSearchObject}&id_city=${selectedDistrict}&year=${selectedYear}` : null, + (url) => fetcher(url, BASE_URL.ems), + swrOptions + ) + + return ( + { + if (data.optionValue) { + setCurrentObjectId(map_id, data.optionValue); + setSearchObject( + searchData?.find((item: any) => item.id_object.toString() === data.optionValue)?.value ?? "" + ); + } + }} + onChange={(e) => { + setSearchObject(e.currentTarget.value); // free typing like Mantine's onChange + }} + clearable + style={{ minWidth: 'auto' }} + > + {searchData + ? searchData.map((item: { value: string; id_object: string }) => ( + + )) + : null} + + ) +} + +export default MapObjectSearch \ No newline at end of file diff --git a/client/src/components/map/MapRegionSelect/MapRegionSelect.tsx b/client/src/components/map/MapRegionSelect/MapRegionSelect.tsx new file mode 100644 index 0000000..f245886 --- /dev/null +++ b/client/src/components/map/MapRegionSelect/MapRegionSelect.tsx @@ -0,0 +1,172 @@ +import { Button, Drawer, DrawerBody, DrawerHeader, Dropdown, Field, Link, Option, Text } from '@fluentui/react-components' +import { ArrowLeft24Regular } from '@fluentui/react-icons' +import { setSelectedDistrict, setSelectedRegion, setSelectedYear, useObjectsStore } from '../../../store/objects' +import { useMapStore } from '../../../store/map' +import { fromExtent } from 'ol/geom/Polygon' +import { getDistrictData, getRegionData, setDistrictsData, useRegionsStore } from '../../../store/regions' +import { IconX } from '@tabler/icons-react' +import { IDistrict, IRegion } from '../../../interfaces/gis' +import { getFeatureByEntityId } from '../mapUtils' +import useSWR, { SWRConfiguration } from 'swr' +import { fetcher } from '../../../http/axiosInstanceNest' +import { BASE_URL } from '../../../constants' +import { schemas } from '../../../constants/map' + +const swrOptions: SWRConfiguration = { + revalidateOnFocus: false +} + +const MapRegionSelect = ({ + map_id +}: { + map_id: string +}) => { + const { map, districtSelect, regionsLayer, regionSelect, districtsLayer } = useMapStore().id[map_id] + const { selectedRegion, selectedYear, selectedDistrict } = useObjectsStore().id[map_id] + const { regionsData } = useRegionsStore() + + const { data: districtsData } = useSWR(selectedRegion ? `/general/districts/?region_id=${selectedRegion}` : null, (url) => fetcher(url, BASE_URL.ems).then(res => { + setDistrictsData(res) + return res + }), swrOptions) + + return ( + + {!!selectedRegion && !selectedYear && + +