Report test; Map printing test
This commit is contained in:
@ -14,13 +14,13 @@ import { addInteractions, handleImageDrop, loadFeatures, processFigure, processL
|
||||
import useSWR, { SWRConfiguration } from 'swr'
|
||||
import { fetcher } from '../../http/axiosInstance'
|
||||
import { BASE_URL } from '../../constants'
|
||||
import { ActionIcon, Autocomplete, CloseButton, Flex, Select as MantineSelect, MantineStyleProp, rem, useMantineColorScheme, Portal, Menu, Button, Group, Divider, LoadingOverlay, Stack, Container } from '@mantine/core'
|
||||
import { ActionIcon, Autocomplete, CloseButton, Flex, Select as MantineSelect, MantineStyleProp, rem, useMantineColorScheme, Portal, Menu, Button, Group, Divider, LoadingOverlay, Stack, Container, Modal, Transition } from '@mantine/core'
|
||||
import { IconBoxMultiple, IconBoxPadding, IconChevronDown, IconPlus, IconSearch, IconUpload } 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, setSatMapsProvider, setTypeRoles, useMapStore, setMapLabel, clearPrintArea } from '../../store/map'
|
||||
import { useThrottle } from '@uidotdev/usehooks'
|
||||
import ObjectTree from '../Tree/ObjectTree'
|
||||
import { setCurrentObjectId, setSelectedDistrict, setSelectedRegion, setSelectedYear, useObjectsStore } from '../../store/objects'
|
||||
@ -73,6 +73,7 @@ const MapComponent = ({
|
||||
nodeLayerSource, drawingLayerSource,
|
||||
satLayer, staticMapLayer, figuresLayer, linesLayer,
|
||||
regionsLayer, districtBoundLayer, baseLayer,
|
||||
printArea, printSource, printAreaDraw
|
||||
} = useMapStore().id[id]
|
||||
|
||||
// Tab settings
|
||||
@ -383,6 +384,17 @@ const MapComponent = ({
|
||||
// }
|
||||
// }, [searchParams, figuresData, linesData])
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedDistrict === null) {
|
||||
setSelectedYear(id, null)
|
||||
}
|
||||
|
||||
if (selectedRegion === null) {
|
||||
setSelectedYear(id, null)
|
||||
setSelectedDistrict(id, null)
|
||||
}
|
||||
}, [selectedDistrict, selectedRegion, id])
|
||||
|
||||
useEffect(() => {
|
||||
const districtBoundSource = districtBoundLayer.getSource()
|
||||
|
||||
@ -505,8 +517,42 @@ const MapComponent = ({
|
||||
}
|
||||
}, [colorScheme])
|
||||
|
||||
useEffect(() => {
|
||||
if (map) {
|
||||
if (mode === 'print') {
|
||||
map.addInteraction(printAreaDraw)
|
||||
} else {
|
||||
map.removeInteraction(printAreaDraw)
|
||||
}
|
||||
}
|
||||
|
||||
}, [mode, map, printAreaDraw])
|
||||
|
||||
useEffect(() => {
|
||||
if (printArea) {
|
||||
map?.setTarget('print-portal')
|
||||
// map?.setView(new View({
|
||||
// extent: printArea
|
||||
// }))
|
||||
printSource.clear()
|
||||
map?.getView().setCenter(getCenter(printArea))
|
||||
map?.getView().fit(printArea, {
|
||||
size: [640, 320]
|
||||
})
|
||||
}
|
||||
}, [printArea, map])
|
||||
|
||||
return (
|
||||
<>
|
||||
<Modal keepMounted size='auto' opened={!!printArea} onClose={() => {
|
||||
clearPrintArea(id)
|
||||
map?.setTarget(mapElement.current as HTMLDivElement)
|
||||
}} title="Предпросмотр области">
|
||||
<div id='print-portal' style={{ width: '640px', height: '320px' }}>
|
||||
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
{active &&
|
||||
<Portal target='#header-portal'>
|
||||
<Flex gap={'sm'} direction={'row'}>
|
||||
@ -636,22 +682,40 @@ const MapComponent = ({
|
||||
<TabsPane defaultTab='parameters' tabs={paramsPane} />
|
||||
</Flex>
|
||||
}
|
||||
|
||||
<Transition
|
||||
mounted={!!selectedRegion && !!selectedDistrict && !!selectedYear}
|
||||
transition="slide-right"
|
||||
duration={200}
|
||||
timingFunction="ease"
|
||||
>
|
||||
{(styles) => <Flex direction='column' h={'100%'} w={'100%'} style={{ ...mapControlsStyle, ...styles }}>
|
||||
<TabsPane defaultTab='objects' tabs={objectsPane} />
|
||||
<Divider />
|
||||
<TabsPane defaultTab='parameters' tabs={paramsPane} />
|
||||
</Flex>}
|
||||
</Transition>
|
||||
</Stack>
|
||||
|
||||
<Stack w='100%' align='center'>
|
||||
<Flex style={mapControlsStyle} w='fit-content'>
|
||||
<Stack style={mapControlsStyle} w='fit-content'>
|
||||
<MapMode map_id={id} />
|
||||
</Flex>
|
||||
</Stack>
|
||||
</Stack>
|
||||
|
||||
<Stack w='100%' maw='340px' align='flex-end' justify='space-between'>
|
||||
{selectedRegion && selectedDistrict && selectedYear && mode === 'edit' &&
|
||||
<MapToolbar map_id={id} />
|
||||
}
|
||||
|
||||
{selectedRegion && selectedDistrict && selectedYear &&
|
||||
<MapLegend selectedDistrict={selectedDistrict} selectedYear={selectedYear} />
|
||||
}
|
||||
|
||||
<Transition
|
||||
mounted={!!selectedRegion && !!selectedDistrict && !!selectedYear}
|
||||
transition="slide-left"
|
||||
duration={200}
|
||||
timingFunction="ease"
|
||||
>
|
||||
{(styles) => <MapLegend style={styles} selectedDistrict={selectedDistrict} selectedYear={selectedYear} />}
|
||||
</Transition>
|
||||
</Stack>
|
||||
</Flex>
|
||||
|
||||
|
@ -1,14 +1,16 @@
|
||||
import { Accordion, ColorSwatch, Flex, ScrollAreaAutosize, Stack, Text, useMantineColorScheme } from '@mantine/core'
|
||||
import { Accordion, ColorSwatch, Flex, MantineStyleProp, ScrollAreaAutosize, Stack, Text, useMantineColorScheme } from '@mantine/core'
|
||||
import useSWR from 'swr';
|
||||
import { fetcher } from '../../../http/axiosInstance';
|
||||
import { BASE_URL } from '../../../constants';
|
||||
|
||||
const MapLegend = ({
|
||||
selectedDistrict,
|
||||
selectedYear
|
||||
selectedYear,
|
||||
style
|
||||
}: {
|
||||
selectedDistrict: number | null,
|
||||
selectedYear: number | null
|
||||
selectedYear: number | null,
|
||||
style: MantineStyleProp
|
||||
}) => {
|
||||
const { colorScheme } = useMantineColorScheme();
|
||||
|
||||
@ -29,7 +31,7 @@ const MapLegend = ({
|
||||
)
|
||||
|
||||
return (
|
||||
<ScrollAreaAutosize offsetScrollbars maw='300px' w='100%' fz='xs' mt='auto' style={{ zIndex: 1, backdropFilter: 'blur(8px)', backgroundColor: colorScheme === 'light' ? '#FFFFFFAA' : '#000000AA', borderRadius: '4px' }}>
|
||||
<ScrollAreaAutosize offsetScrollbars maw='300px' w='100%' fz='xs' mt='auto' style={{...style, zIndex: 1, backdropFilter: 'blur(8px)', backgroundColor: colorScheme === 'light' ? '#FFFFFFAA' : '#000000AA', borderRadius: '4px' }}>
|
||||
<Stack gap='sm' p='sm'>
|
||||
<Text fz='xs'>
|
||||
Легенда
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { Center, SegmentedControl } from '@mantine/core'
|
||||
import { getMode, Mode, setMode } from '../../store/map'
|
||||
import { IconEdit, IconEye } from '@tabler/icons-react'
|
||||
import { IconEdit, IconEye, IconPrinter } from '@tabler/icons-react'
|
||||
|
||||
const MapMode = ({
|
||||
map_id
|
||||
@ -25,6 +25,15 @@ const MapMode = ({
|
||||
</Center>
|
||||
),
|
||||
},
|
||||
{
|
||||
value: 'print',
|
||||
label: (
|
||||
<Center style={{ gap: 10 }}>
|
||||
<IconPrinter size={16} />
|
||||
<span>Печать</span>
|
||||
</Center>
|
||||
),
|
||||
},
|
||||
]} />
|
||||
)
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ import { fromCircle, fromExtent } from "ol/geom/Polygon";
|
||||
import { measureStyleFunction, modifyStyle } from "./Measure/MeasureStyles";
|
||||
import { getCurrentTool, getDraw, getDrawingLayerSource, getImageLayer, getMap, getMeasureClearPrevious, getMeasureDraw, getMeasureModify, getMeasureSource, getMeasureType, getOverlayLayerSource, getSnap, getTipPoint, getTranslate, setDraw, setFile, setMeasureDraw, setPolygonExtent, setRectCoords, setSnap, setTranslate } from "../../store/map";
|
||||
import Collection from "ol/Collection";
|
||||
import { GeometryFunction, SketchCoordType } from "ol/interaction/Draw";
|
||||
|
||||
const calculateAngle = (coords: [number, number][]) => {
|
||||
const [start, end] = coords;
|
||||
@ -341,9 +342,47 @@ export const updateImageSource = (
|
||||
}
|
||||
};
|
||||
|
||||
export const fixedAspectRatioBox: GeometryFunction = (
|
||||
coordinates: SketchCoordType,
|
||||
geometry: SimpleGeometry | undefined,
|
||||
): SimpleGeometry => {
|
||||
// Ensure coordinates is an array of at least two points
|
||||
if (!Array.isArray(coordinates) || coordinates.length < 2) {
|
||||
return geometry ?? new Polygon([]);
|
||||
}
|
||||
|
||||
const [start, end] = coordinates as Coordinate[]; // Ensure it's a Coordinate array
|
||||
const minX = start[0];
|
||||
const minY = start[1];
|
||||
const maxX = end[0];
|
||||
let maxY = end[1];
|
||||
|
||||
const width = maxX - minX;
|
||||
const height = width / 2; // Enforce 2:1 aspect ratio
|
||||
maxY = minY + height;
|
||||
|
||||
// Define the rectangle's coordinates
|
||||
const boxCoords: Coordinate[][] = [[
|
||||
[minX, minY],
|
||||
[maxX, minY],
|
||||
[maxX, maxY],
|
||||
[minX, maxY],
|
||||
[minX, minY], // Close the polygon
|
||||
]];
|
||||
|
||||
if (geometry) {
|
||||
geometry.setCoordinates(boxCoords);
|
||||
return geometry;
|
||||
}
|
||||
return new Polygon(boxCoords);
|
||||
};
|
||||
|
||||
|
||||
|
||||
export const addInteractions = (
|
||||
map_id: string
|
||||
) => {
|
||||
console.log("Adding interactions")
|
||||
const currentTool = getCurrentTool(map_id)
|
||||
const clearPrevious = getMeasureClearPrevious(map_id)
|
||||
const measureType = getMeasureType(map_id)
|
||||
|
Reference in New Issue
Block a user