MapComponent update
This commit is contained in:
@ -3,14 +3,14 @@ import 'ol/ol.css'
|
|||||||
import Map from 'ol/Map'
|
import Map from 'ol/Map'
|
||||||
import View from 'ol/View'
|
import View from 'ol/View'
|
||||||
import { Draw, Modify, Select, Snap, Translate } from 'ol/interaction'
|
import { Draw, Modify, Select, Snap, Translate } from 'ol/interaction'
|
||||||
import { ImageStatic, OSM, Vector as VectorSource, XYZ } from 'ol/source'
|
import { ImageStatic, OSM, Vector as VectorSource } from 'ol/source'
|
||||||
import { Tile as TileLayer, VectorImage, Vector as VectorLayer } from 'ol/layer'
|
import { Tile as TileLayer, VectorImage, Vector as VectorLayer } from 'ol/layer'
|
||||||
import { click, never, platformModifierKeyOnly, primaryAction, shiftKeyOnly } from 'ol/events/condition'
|
import { click, never, platformModifierKeyOnly, primaryAction, shiftKeyOnly } from 'ol/events/condition'
|
||||||
import Feature from 'ol/Feature'
|
import Feature from 'ol/Feature'
|
||||||
import { IRectCoords, SatelliteMapsProvider } from '../../interfaces/map'
|
import { IRectCoords, SatelliteMapsProvider } from '../../interfaces/map'
|
||||||
import { Extent } from 'ol/extent'
|
import { Extent } from 'ol/extent'
|
||||||
import { drawingLayerStyle, highlightStyleRed, highlightStyleYellow, overlayStyle, regionsLayerStyle } from './MapStyles'
|
import { drawingLayerStyle, highlightStyleRed, highlightStyleYellow, overlayStyle, regionsLayerStyle } from './MapStyles'
|
||||||
import { googleMapsSatelliteSource, regionsLayerSource, yandexMapsSatelliteSource } from './MapSources'
|
import { customMapSource, googleMapsSatelliteSource, regionsLayerSource, yandexMapsSatelliteSource } from './MapSources'
|
||||||
import ImageLayer from 'ol/layer/Image'
|
import ImageLayer from 'ol/layer/Image'
|
||||||
import { LineString, Point, SimpleGeometry } from 'ol/geom'
|
import { LineString, Point, SimpleGeometry } from 'ol/geom'
|
||||||
import { fromExtent } from 'ol/geom/Polygon'
|
import { fromExtent } from 'ol/geom/Polygon'
|
||||||
@ -19,10 +19,10 @@ import { Coordinate } from 'ol/coordinate'
|
|||||||
import { addInteractions, calculateCenter, loadFeatures, processFigure, processLine, regionsInit, saveFeatures, updateImageSource } from './mapUtils'
|
import { addInteractions, calculateCenter, loadFeatures, processFigure, processLine, regionsInit, saveFeatures, updateImageSource } from './mapUtils'
|
||||||
import MapBrowserEvent from 'ol/MapBrowserEvent'
|
import MapBrowserEvent from 'ol/MapBrowserEvent'
|
||||||
import { get, transform } from 'ol/proj'
|
import { get, transform } from 'ol/proj'
|
||||||
import useSWR from 'swr'
|
import useSWR, { SWRConfiguration } from 'swr'
|
||||||
import { fetcher } from '../../http/axiosInstance'
|
import { fetcher } from '../../http/axiosInstance'
|
||||||
import { BASE_URL } from '../../constants'
|
import { BASE_URL } from '../../constants'
|
||||||
import { ActionIcon, Autocomplete, Box, CloseButton, Flex, Select as MantineSelect, MantineStyleProp, rem, Slider, useMantineColorScheme, Portal, Menu, Button, Group, Divider, LoadingOverlay } from '@mantine/core'
|
import { ActionIcon, Autocomplete, Box, CloseButton, Flex, Select as MantineSelect, MantineStyleProp, rem, useMantineColorScheme, Portal, Menu, Button, Group, Divider, LoadingOverlay } from '@mantine/core'
|
||||||
import { IconBoxMultiple, IconChevronDown, IconPlus, IconSearch, IconSettings, IconUpload } from '@tabler/icons-react'
|
import { IconBoxMultiple, IconChevronDown, IconPlus, IconSearch, IconSettings, IconUpload } from '@tabler/icons-react'
|
||||||
import { getGridCellPosition } from './mapUtils'
|
import { getGridCellPosition } from './mapUtils'
|
||||||
import { IFigure, ILine } from '../../interfaces/gis'
|
import { IFigure, ILine } from '../../interfaces/gis'
|
||||||
@ -38,7 +38,11 @@ import { setCurrentObjectId, setSelectedDistrict, setSelectedRegion, setSelected
|
|||||||
import MapLayers from './MapLayers/MapLayers'
|
import MapLayers from './MapLayers/MapLayers'
|
||||||
import ObjectParameters from './ObjectParameters/ObjectParameters'
|
import ObjectParameters from './ObjectParameters/ObjectParameters'
|
||||||
import TabsPane, { ITabsPane } from './TabsPane/TabsPane'
|
import TabsPane, { ITabsPane } from './TabsPane/TabsPane'
|
||||||
import { mapExtent } from './MapConstants'
|
import Link from 'ol/interaction/Link'
|
||||||
|
|
||||||
|
const swrOptions: SWRConfiguration = {
|
||||||
|
revalidateOnFocus: false
|
||||||
|
}
|
||||||
|
|
||||||
// Tab settings
|
// Tab settings
|
||||||
const objectsPane: ITabsPane[] = [
|
const objectsPane: ITabsPane[] = [
|
||||||
@ -77,8 +81,19 @@ const paramsPane: ITabsPane[] = [
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
interface ICitySettings {
|
||||||
|
city_id: number;
|
||||||
|
image_width: number;
|
||||||
|
image_height: number;
|
||||||
|
scale: number;
|
||||||
|
offset_x: number;
|
||||||
|
offset_y: number;
|
||||||
|
rotation: number;
|
||||||
|
image_scale: number;
|
||||||
|
}
|
||||||
|
|
||||||
// Settings for cities
|
// Settings for cities
|
||||||
const citySettings = [
|
const citySettings: ICitySettings[] = [
|
||||||
{
|
{
|
||||||
city_id: 145,
|
city_id: 145,
|
||||||
image_width: 8500,
|
image_width: 8500,
|
||||||
@ -87,12 +102,46 @@ const citySettings = [
|
|||||||
scale: 9000,
|
scale: 9000,
|
||||||
offset_x: 14442665.697619518,
|
offset_x: 14442665.697619518,
|
||||||
offset_y: 8884520.63524492,
|
offset_y: 8884520.63524492,
|
||||||
rotation: 0
|
rotation: 0,
|
||||||
|
image_scale: 0.40340
|
||||||
|
},
|
||||||
|
{
|
||||||
|
city_id: 146,
|
||||||
|
image_width: 8500,
|
||||||
|
image_height: 12544,
|
||||||
|
// scale: 10000,
|
||||||
|
scale: 8000,
|
||||||
|
offset_x: 14416475.697619518,
|
||||||
|
offset_y: 8889280.63524492,
|
||||||
|
rotation: 0,
|
||||||
|
image_scale: 0.30340
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
function getCitySettings(
|
||||||
|
city_id: number
|
||||||
|
) {
|
||||||
|
const settings = citySettings.find(el => el.city_id === city_id)
|
||||||
|
|
||||||
|
if (settings) {
|
||||||
|
console.log("City settings found")
|
||||||
|
return settings
|
||||||
|
} else {
|
||||||
|
console.log("City settings NOT found")
|
||||||
|
return {
|
||||||
|
city_id: 0,
|
||||||
|
image_width: 8500,
|
||||||
|
image_height: 12544,
|
||||||
|
scale: 9000,
|
||||||
|
offset_x: 14442665.697619518,
|
||||||
|
offset_y: 8884520.63524492,
|
||||||
|
rotation: 0
|
||||||
|
} as ICitySettings
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const MapComponent = () => {
|
const MapComponent = () => {
|
||||||
const { colorScheme } = useMantineColorScheme();
|
const { colorScheme } = useMantineColorScheme()
|
||||||
|
|
||||||
// States
|
// States
|
||||||
const { selectedYear, currentObjectId, selectedRegion, selectedDistrict } = useObjectsStore()
|
const { selectedYear, currentObjectId, selectedRegion, selectedDistrict } = useObjectsStore()
|
||||||
@ -124,19 +173,13 @@ const MapComponent = () => {
|
|||||||
|
|
||||||
const mapElement = useRef<HTMLDivElement | null>(null)
|
const mapElement = useRef<HTMLDivElement | null>(null)
|
||||||
|
|
||||||
|
const tooltipRef = useRef<HTMLDivElement | null>(null)
|
||||||
|
|
||||||
const map = useRef<Map | null>(null)
|
const map = useRef<Map | null>(null)
|
||||||
|
|
||||||
const gMapsSatSource = useRef<XYZ>(googleMapsSatelliteSource)
|
|
||||||
|
|
||||||
const customMapSource = useRef<XYZ>(new XYZ({
|
|
||||||
url: `${import.meta.env.VITE_API_EMS_URL}/tiles/tile/custom/{z}/{x}/{y}`,
|
|
||||||
attributions: 'Custom map data'
|
|
||||||
}))
|
|
||||||
|
|
||||||
const yMapsSatSource = useRef<XYZ>(yandexMapsSatelliteSource)
|
|
||||||
|
|
||||||
const satLayer = useRef<TileLayer>(new TileLayer({
|
const satLayer = useRef<TileLayer>(new TileLayer({
|
||||||
source: gMapsSatSource.current,
|
source: googleMapsSatelliteSource,
|
||||||
|
visible: false,
|
||||||
properties: {
|
properties: {
|
||||||
id: uuidv4(),
|
id: uuidv4(),
|
||||||
name: 'Спутник'
|
name: 'Спутник'
|
||||||
@ -175,6 +218,7 @@ const MapComponent = () => {
|
|||||||
declutter: true,
|
declutter: true,
|
||||||
properties: {
|
properties: {
|
||||||
id: uuidv4(),
|
id: uuidv4(),
|
||||||
|
type: 'figures',
|
||||||
name: 'Фигуры'
|
name: 'Фигуры'
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
@ -184,6 +228,7 @@ const MapComponent = () => {
|
|||||||
declutter: true,
|
declutter: true,
|
||||||
properties: {
|
properties: {
|
||||||
id: uuidv4(),
|
id: uuidv4(),
|
||||||
|
type: 'lines',
|
||||||
name: 'Линии'
|
name: 'Линии'
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
@ -218,7 +263,7 @@ const MapComponent = () => {
|
|||||||
const staticMapLayer = useRef<ImageLayer<ImageStatic>>(new ImageLayer({
|
const staticMapLayer = useRef<ImageLayer<ImageStatic>>(new ImageLayer({
|
||||||
properties: {
|
properties: {
|
||||||
id: uuidv4(),
|
id: uuidv4(),
|
||||||
name: 'Static image'
|
name: 'Подложка'
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
|
|
||||||
@ -420,7 +465,7 @@ const MapComponent = () => {
|
|||||||
//zoom: 16,
|
//zoom: 16,
|
||||||
zoom: 5,
|
zoom: 5,
|
||||||
maxZoom: 21,
|
maxZoom: 21,
|
||||||
extent: mapExtent,
|
//extent: mapExtent,
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -431,6 +476,15 @@ const MapComponent = () => {
|
|||||||
setCurrentZ(Number(map.current?.getView().getZoom()?.toFixed(0)))
|
setCurrentZ(Number(map.current?.getView().getZoom()?.toFixed(0)))
|
||||||
setCurrentX(tileX)
|
setCurrentX(tileX)
|
||||||
setCurrentY(tileY)
|
setCurrentY(tileY)
|
||||||
|
|
||||||
|
const pixel = map.current?.getEventPixel(e.originalEvent)
|
||||||
|
if (pixel) {
|
||||||
|
map.current?.forEachFeatureAtPixel(pixel, function (feature) {
|
||||||
|
if (feature.get('geometry_type') === 'line') {
|
||||||
|
console.log(feature.getProperties())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
map.current.on('click', function (e: MapBrowserEvent<UIEvent>) {
|
map.current.on('click', function (e: MapBrowserEvent<UIEvent>) {
|
||||||
@ -492,33 +546,22 @@ const MapComponent = () => {
|
|||||||
}
|
}
|
||||||
}, [currentTool])
|
}, [currentTool])
|
||||||
|
|
||||||
const [satelliteOpacity, setSatelliteOpacity] = useState<number>(0)
|
|
||||||
|
|
||||||
// Visibility setting
|
|
||||||
useEffect(() => {
|
|
||||||
satLayer.current?.setOpacity(satelliteOpacity)
|
|
||||||
|
|
||||||
if (satelliteOpacity == 0) {
|
|
||||||
baseLayer.current?.setVisible(true)
|
|
||||||
satLayer.current?.setVisible(false)
|
|
||||||
} if (satelliteOpacity == 1) {
|
|
||||||
baseLayer.current?.setVisible(false)
|
|
||||||
satLayer.current?.setVisible(true)
|
|
||||||
} else if (satelliteOpacity > 0 && satelliteOpacity < 1) {
|
|
||||||
baseLayer.current?.setVisible(true)
|
|
||||||
satLayer.current?.setVisible(true)
|
|
||||||
}
|
|
||||||
}, [satelliteOpacity])
|
|
||||||
|
|
||||||
// Satellite tiles setting
|
// Satellite tiles setting
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
satLayer.current?.setSource(
|
if (satLayer.current) {
|
||||||
satMapsProvider == 'google' ? gMapsSatSource.current :
|
if (satMapsProvider === 'google') {
|
||||||
satMapsProvider == 'yandex' ? yMapsSatSource.current :
|
satLayer.current.setSource(googleMapsSatelliteSource)
|
||||||
satMapsProvider == 'custom' ? customMapSource.current :
|
}
|
||||||
gMapsSatSource.current)
|
|
||||||
satLayer.current?.getSource()?.refresh()
|
if (satMapsProvider === 'yandex') {
|
||||||
}, [satMapsProvider])
|
satLayer.current.setSource(yandexMapsSatelliteSource)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (satMapsProvider === 'custom') {
|
||||||
|
satLayer.current.setSource(customMapSource)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [satMapsProvider, satLayer])
|
||||||
|
|
||||||
const submitOverlay = async () => {
|
const submitOverlay = async () => {
|
||||||
if (file && polygonExtent && rectCoords?.bl && rectCoords?.tl && rectCoords?.tr && rectCoords?.br) {
|
if (file && polygonExtent && rectCoords?.bl && rectCoords?.tl && rectCoords?.tr && rectCoords?.br) {
|
||||||
@ -639,38 +682,18 @@ const MapComponent = () => {
|
|||||||
}
|
}
|
||||||
}, [currentObjectId])
|
}, [currentObjectId])
|
||||||
|
|
||||||
const { data: regionsData } = useSWR(
|
const { data: regionsData } = useSWR(`/general/regions/all`, (url) => fetcher(url, BASE_URL.ems), swrOptions)
|
||||||
`/general/regions/all`,
|
|
||||||
(url) => fetcher(url, BASE_URL.ems),
|
|
||||||
{
|
|
||||||
revalidateOnFocus: false
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
const { data: districtsData } = useSWR(
|
const { data: districtsData } = useSWR(selectedRegion ? `/general/districts/all?region_id=${selectedRegion}` : null, (url) => fetcher(url, BASE_URL.ems), swrOptions)
|
||||||
selectedRegion ? `/general/districts/all?region_id=${selectedRegion}` : null,
|
|
||||||
(url) => fetcher(url, BASE_URL.ems),
|
|
||||||
{
|
|
||||||
revalidateOnFocus: false
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
const { data: searchData } = useSWR(
|
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)
|
||||||
throttledSearchObject !== "" && selectedDistrict && selectedYear ? `/general/search/objects?q=${throttledSearchObject}&id_city=${selectedDistrict}&year=${selectedYear}` : null,
|
|
||||||
(url) => fetcher(url, BASE_URL.ems),
|
|
||||||
{
|
|
||||||
revalidateOnFocus: false
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
const { data: figuresData, isValidating: figuresValidating } = useSWR(
|
const { data: figuresData, isValidating: figuresValidating } = useSWR(
|
||||||
selectedDistrict && selectedYear ? `/gis/figures/all?city_id=${selectedDistrict}&year=${selectedYear}&offset=0&limit=${10000}` : null,
|
selectedDistrict && selectedYear ? `/gis/figures/all?city_id=${selectedDistrict}&year=${selectedYear}&offset=0&limit=${10000}` : null,
|
||||||
(url) => axios.get(url, {
|
(url) => axios.get(url, {
|
||||||
baseURL: BASE_URL.ems
|
baseURL: BASE_URL.ems
|
||||||
}).then((res) => res.data),
|
}).then((res) => res.data),
|
||||||
{
|
swrOptions
|
||||||
revalidateOnFocus: false
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const { data: linesData, isValidating: linesValidating } = useSWR(
|
const { data: linesData, isValidating: linesValidating } = useSWR(
|
||||||
@ -680,132 +703,90 @@ const MapComponent = () => {
|
|||||||
}).then((res) => {
|
}).then((res) => {
|
||||||
return res.data
|
return res.data
|
||||||
}),
|
}),
|
||||||
{
|
swrOptions
|
||||||
revalidateOnFocus: false
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const link = useRef<Link>(new Link())
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let offset_x = 14444582.697619518
|
if (link.current) {
|
||||||
let offset_y = 8866450.63524492
|
if (selectedRegion) {
|
||||||
let scale = {
|
link.current.update('r', selectedRegion?.toString())
|
||||||
w: 100000,
|
}
|
||||||
h: 100000
|
|
||||||
|
if (selectedDistrict) {
|
||||||
|
link.current.update('d', selectedDistrict?.toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selectedYear) {
|
||||||
|
link.current.update('y', selectedYear?.toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentObjectId) {
|
||||||
|
link.current.update('o', currentObjectId?.toString())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//let rotation = 0
|
}, [link, selectedRegion, selectedDistrict, selectedYear, currentObjectId])
|
||||||
|
|
||||||
const settings = citySettings.find(el => el.city_id === selectedDistrict)
|
useEffect(() => {
|
||||||
|
if (selectedDistrict) {
|
||||||
|
const settings = getCitySettings(selectedDistrict)
|
||||||
|
|
||||||
if (settings) {
|
if (Array.isArray(figuresData)) {
|
||||||
console.log("City settings found")
|
figuresLayer.current.getSource()?.clear()
|
||||||
|
if (figuresData.length > 0) {
|
||||||
|
figuresData.map((figure: IFigure) => {
|
||||||
|
processFigure(
|
||||||
|
figure,
|
||||||
|
settings.scale,
|
||||||
|
[settings.offset_x, settings.offset_y],
|
||||||
|
figuresLayer
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
if (settings.scale) {
|
if (map.current) {
|
||||||
scale = {
|
const extent = figuresLayer.current.getSource()?.getExtent()
|
||||||
w: settings.scale,
|
|
||||||
h: settings.scale
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (settings.offset_x && settings.offset_y) {
|
|
||||||
offset_x = settings.offset_x
|
|
||||||
offset_y = settings.offset_y
|
|
||||||
}
|
|
||||||
|
|
||||||
if (settings.rotation) {
|
if (extent) {
|
||||||
//rotation = settings.rotation
|
map.current.getView().fit(fromExtent(extent), { duration: 500 })
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
console.log("City settings NOT found")
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Array.isArray(figuresData)) {
|
|
||||||
figuresLayer.current.getSource()?.clear()
|
|
||||||
if (figuresData.length > 0) {
|
|
||||||
const scaling = {
|
|
||||||
w: scale.w, // responseData[0].width
|
|
||||||
h: scale.h // responseData[0].width
|
|
||||||
}
|
|
||||||
|
|
||||||
figuresData.map((figure: IFigure) => {
|
|
||||||
processFigure(figure, scaling, [offset_x, offset_y], figuresLayer)
|
|
||||||
})
|
|
||||||
|
|
||||||
if (map.current) {
|
|
||||||
const extent = figuresLayer.current.getSource()?.getExtent()
|
|
||||||
|
|
||||||
if (extent) {
|
|
||||||
map.current.getView().fit(fromExtent(extent), { duration: 500 })
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (Array.isArray(linesData)) {
|
if (Array.isArray(linesData)) {
|
||||||
linesLayer.current.getSource()?.clear()
|
linesLayer.current.getSource()?.clear()
|
||||||
if (linesData.length > 0) {
|
if (linesData.length > 0) {
|
||||||
const scaling = {
|
linesData.map((line: ILine) => {
|
||||||
w: scale.w, // responseData[0].width
|
processLine(line, settings.scale, [settings.offset_x, settings.offset_y], linesLayer)
|
||||||
h: scale.h // responseData[0].width
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
linesData.map((line: ILine) => {
|
|
||||||
processLine(line, scaling, [offset_x, offset_y], linesLayer)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}, [figuresData, linesData, selectedDistrict, selectedYear])
|
}, [figuresData, linesData, selectedDistrict, selectedYear])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (selectedDistrict) {
|
if (selectedDistrict) {
|
||||||
let offset_x = 14442665.697619518
|
const settings = getCitySettings(selectedDistrict)
|
||||||
let offset_y = 8884520.63524492
|
|
||||||
//let scale = 9000
|
|
||||||
//let rotation = 0
|
|
||||||
//let image_width = 8500
|
|
||||||
//let image_height = 12544
|
|
||||||
|
|
||||||
const settings = citySettings.find(el => el.city_id === selectedDistrict)
|
|
||||||
|
|
||||||
if (settings) {
|
|
||||||
console.log("City settings found")
|
|
||||||
|
|
||||||
if (settings.scale) {
|
|
||||||
//scale = settings.scale
|
|
||||||
}
|
|
||||||
if (settings.offset_x && settings.offset_y) {
|
|
||||||
offset_x = settings.offset_x
|
|
||||||
offset_y = settings.offset_y
|
|
||||||
}
|
|
||||||
|
|
||||||
if (settings.image_width && settings.image_height) {
|
|
||||||
//image_width = settings.image_width
|
|
||||||
//image_height = settings.image_height
|
|
||||||
}
|
|
||||||
|
|
||||||
if (settings.rotation) {
|
|
||||||
//rotation = settings.rotation
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.log("City settings NOT found")
|
|
||||||
}
|
|
||||||
|
|
||||||
const imageUrl = `${import.meta.env.VITE_API_EMS_URL}/static/${selectedDistrict}`;
|
const imageUrl = `${import.meta.env.VITE_API_EMS_URL}/static/${selectedDistrict}`;
|
||||||
const img = new Image();
|
const img = new Image();
|
||||||
img.src = imageUrl;
|
img.src = imageUrl;
|
||||||
img.onload = () => {
|
img.onload = () => {
|
||||||
if (map.current) {
|
if (map.current) {
|
||||||
|
const width = img.naturalWidth
|
||||||
const width = img.naturalWidth;
|
const height = img.naturalHeight
|
||||||
const height = img.naturalHeight;
|
|
||||||
console.log(width, height)
|
console.log(width, height)
|
||||||
//const k = (width < height ? width / height : height / width)
|
//const k = (width < height ? width / height : height / width)
|
||||||
const k = 0.40340
|
const k = settings.image_scale
|
||||||
|
|
||||||
console.log(k)
|
console.log(k)
|
||||||
|
|
||||||
const wk = width * k
|
const wk = width * k
|
||||||
const hk = height * k
|
const hk = height * k
|
||||||
|
|
||||||
const center = [offset_x + (wk), offset_y - (hk)];
|
const center = [settings.offset_x + (wk), settings.offset_y - (hk)];
|
||||||
|
|
||||||
const extent = [
|
const extent = [
|
||||||
center[0] - (wk),
|
center[0] - (wk),
|
||||||
@ -828,16 +809,6 @@ const MapComponent = () => {
|
|||||||
}, [selectedDistrict])
|
}, [selectedDistrict])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// if (map.current) {
|
|
||||||
// map.current.on('postcompose', function () {
|
|
||||||
// if (colorScheme === 'dark') {
|
|
||||||
// document.querySelector('canvas').style.filter = 'grayscale(80%) invert(100%) hue-rotate(180deg)'
|
|
||||||
// } else {
|
|
||||||
// document.querySelector('canvas').style.filter = 'grayscale(0%) invert(0%) hue-rotate(0deg)'
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
|
|
||||||
if (baseLayer.current) {
|
if (baseLayer.current) {
|
||||||
baseLayer.current.on('prerender', function (e) {
|
baseLayer.current.on('prerender', function (e) {
|
||||||
if (colorScheme === 'dark') {
|
if (colorScheme === 'dark') {
|
||||||
@ -913,7 +884,8 @@ const MapComponent = () => {
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<MantineSelect
|
<MantineSelect
|
||||||
w='84px'
|
placeholder='Схема'
|
||||||
|
w='92px'
|
||||||
data={['2018', '2019', '2020', '2021', '2022', '2023', '2024'].map(el => ({ label: el, value: el }))}
|
data={['2018', '2019', '2020', '2021', '2022', '2023', '2024'].map(el => ({ label: el, value: el }))}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
setSelectedYear(Number(e))
|
setSelectedYear(Number(e))
|
||||||
@ -935,13 +907,22 @@ const MapComponent = () => {
|
|||||||
</Group>
|
</Group>
|
||||||
</Button>
|
</Button>
|
||||||
</Menu.Target>
|
</Menu.Target>
|
||||||
<Menu.Dropdown>
|
<Menu.Dropdown miw={300}>
|
||||||
<Menu.Label>{'Настройка видимости слоёв'}</Menu.Label>
|
<Menu.Label>{'Настройка видимости слоёв'}</Menu.Label>
|
||||||
|
|
||||||
<Flex p='sm' direction='column' gap='xs'>
|
<Flex p='sm' direction='column' gap='xs'>
|
||||||
<Flex align='center' direction='row' gap='sm'>
|
<Flex align='center' direction='row' gap='sm'>
|
||||||
<Slider w='100%' min={0} max={1} step={0.001} value={satelliteOpacity} defaultValue={satelliteOpacity} onChange={(value) => setSatelliteOpacity(Array.isArray(value) ? value[0] : value)} />
|
<MantineSelect
|
||||||
<MantineSelect variant='filled' value={satMapsProvider} data={[{ label: 'Google', value: 'google' }, { label: 'Яндекс', value: 'yandex' }, { label: 'Подложка', value: 'custom' }, { label: 'Static', value: 'static' }]} onChange={(value) => setSatMapsProvider(value as SatelliteMapsProvider)} />
|
value={satMapsProvider}
|
||||||
|
data={[
|
||||||
|
{ label: 'Google', value: 'google' },
|
||||||
|
{ label: 'Яндекс', value: 'yandex' },
|
||||||
|
{ label: 'Подложка', value: 'custom' },
|
||||||
|
{ label: 'Static', value: 'static' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
onChange={(value) => setSatMapsProvider(value as SatelliteMapsProvider)}
|
||||||
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex direction='row'>
|
<Flex direction='row'>
|
||||||
<ActionIcon size='lg' variant='transparent' onClick={() => submitOverlay()}>
|
<ActionIcon size='lg' variant='transparent' onClick={() => submitOverlay()}>
|
||||||
@ -954,7 +935,6 @@ const MapComponent = () => {
|
|||||||
</Flex>
|
</Flex>
|
||||||
<MapLayers map={map} />
|
<MapLayers map={map} />
|
||||||
</Flex>
|
</Flex>
|
||||||
|
|
||||||
</Menu.Dropdown>
|
</Menu.Dropdown>
|
||||||
</Menu>
|
</Menu>
|
||||||
|
|
||||||
@ -967,14 +947,14 @@ const MapComponent = () => {
|
|||||||
<LoadingOverlay visible={linesValidating || figuresValidating} />
|
<LoadingOverlay visible={linesValidating || figuresValidating} />
|
||||||
|
|
||||||
<Flex w={'100%'} h={'100%'} pos={'absolute'}>
|
<Flex w={'100%'} h={'100%'} pos={'absolute'}>
|
||||||
{selectedRegion && selectedDistrict &&
|
{selectedRegion && selectedDistrict && selectedYear &&
|
||||||
<MapToolbar
|
<MapToolbar
|
||||||
onSave={() => saveFeatures(drawingLayer)}
|
onSave={() => saveFeatures(drawingLayer)}
|
||||||
onRemove={() => draw.current?.removeLastPoint()}
|
onRemove={() => draw.current?.removeLastPoint()}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
|
|
||||||
{selectedRegion && selectedDistrict &&
|
{selectedRegion && selectedDistrict && selectedYear &&
|
||||||
<Flex direction='column' mah={'94%'} h={'100%'} pl='sm' style={{
|
<Flex direction='column' mah={'94%'} h={'100%'} pl='sm' style={{
|
||||||
...mapControlsStyle,
|
...mapControlsStyle,
|
||||||
maxWidth: '340px',
|
maxWidth: '340px',
|
||||||
@ -993,12 +973,19 @@ const MapComponent = () => {
|
|||||||
/>
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
|
|
||||||
<div
|
<Flex
|
||||||
id="map-container"
|
id="map-container"
|
||||||
ref={mapElement}
|
ref={mapElement}
|
||||||
style={{ width: '100%', height: '100%', maxHeight: '100%', position: 'fixed', flexGrow: 1 }}
|
style={{
|
||||||
|
width: '100%',
|
||||||
|
height: '100%',
|
||||||
|
maxHeight: '100%',
|
||||||
|
position: 'absolute',
|
||||||
|
flexGrow: 1
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
</div>
|
<div ref={tooltipRef}></div>
|
||||||
|
</Flex>
|
||||||
</Box >
|
</Box >
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -18,22 +18,22 @@ import { uploadCoordinates } from "../../actions/map";
|
|||||||
import { ImageStatic } from "ol/source";
|
import { ImageStatic } from "ol/source";
|
||||||
import ImageLayer from "ol/layer/Image";
|
import ImageLayer from "ol/layer/Image";
|
||||||
import { IFigure, ILine } from "../../interfaces/gis";
|
import { IFigure, ILine } from "../../interfaces/gis";
|
||||||
import { fromCircle } from "ol/geom/Polygon";
|
import { fromCircle, fromExtent } from "ol/geom/Polygon";
|
||||||
import { measureStyleFunction, modifyStyle } from "./Measure/MeasureStyles";
|
import { measureStyleFunction, modifyStyle } from "./Measure/MeasureStyles";
|
||||||
import { getCurrentTool, getMeasureClearPrevious, getMeasureType, getTipPoint, setStatusText } from "../../store/map";
|
import { getCurrentTool, getMeasureClearPrevious, getMeasureType, getTipPoint, setStatusText } from "../../store/map";
|
||||||
import { MutableRefObject } from "react";
|
import { MutableRefObject } from "react";
|
||||||
import { setSelectedRegion } from "../../store/objects";
|
import { getSelectedCity, getSelectedYear, setSelectedRegion } from "../../store/objects";
|
||||||
|
|
||||||
export function processLine(
|
export function processLine(
|
||||||
line: ILine,
|
line: ILine,
|
||||||
scaling: { w: number, h: number },
|
scaling: number,
|
||||||
mapCenter: Coordinate,
|
mapCenter: Coordinate,
|
||||||
linesLayer: MutableRefObject<VectorLayer<VectorSource>>
|
linesLayer: MutableRefObject<VectorLayer<VectorSource>>
|
||||||
) {
|
) {
|
||||||
const x1 = line.x1 * scaling.w
|
const x1 = line.x1 * scaling
|
||||||
const y1 = line.y1 * scaling.h
|
const y1 = line.y1 * scaling
|
||||||
const x2 = line.x2 * scaling.w
|
const x2 = line.x2 * scaling
|
||||||
const y2 = line.y2 * scaling.h
|
const y2 = line.y2 * scaling
|
||||||
|
|
||||||
const center = [mapCenter[0], mapCenter[1]]
|
const center = [mapCenter[0], mapCenter[1]]
|
||||||
|
|
||||||
@ -44,7 +44,9 @@ export function processLine(
|
|||||||
|
|
||||||
const feature = new Feature(new LineString(testCoords))
|
const feature = new Feature(new LineString(testCoords))
|
||||||
feature.setStyle(styleFunction(feature))
|
feature.setStyle(styleFunction(feature))
|
||||||
|
|
||||||
feature.set('type', line.type)
|
feature.set('type', line.type)
|
||||||
|
feature.set('geometry_type', 'line')
|
||||||
feature.set('planning', line.planning)
|
feature.set('planning', line.planning)
|
||||||
feature.set('object_id', line.object_id)
|
feature.set('object_id', line.object_id)
|
||||||
|
|
||||||
@ -53,16 +55,16 @@ export function processLine(
|
|||||||
|
|
||||||
export function processFigure(
|
export function processFigure(
|
||||||
figure: IFigure,
|
figure: IFigure,
|
||||||
scaling: { w: number, h: number },
|
scaling: number,
|
||||||
mapCenter: Coordinate,
|
mapCenter: Coordinate,
|
||||||
figuresLayer: MutableRefObject<VectorLayer<VectorSource>>
|
figuresLayer: MutableRefObject<VectorLayer<VectorSource>>
|
||||||
) {
|
) {
|
||||||
if (figure.figure_type_id == 1) {
|
if (figure.figure_type_id == 1) {
|
||||||
const width = figure.width * scaling.w
|
const width = figure.width * scaling
|
||||||
const height = figure.height * scaling.h
|
const height = figure.height * scaling
|
||||||
|
|
||||||
const left = figure.left * scaling.w
|
const left = figure.left * scaling
|
||||||
const top = figure.top * scaling.h
|
const top = figure.top * scaling
|
||||||
|
|
||||||
const centerX = mapCenter[0] + left + (width / 2)
|
const centerX = mapCenter[0] + left + (width / 2)
|
||||||
const centerY = mapCenter[1] - top - (height / 2)
|
const centerY = mapCenter[1] - top - (height / 2)
|
||||||
@ -83,16 +85,16 @@ export function processFigure(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (figure.figure_type_id == 3) {
|
if (figure.figure_type_id == 3) {
|
||||||
const x = figure.left * scaling.w
|
const x = figure.left * scaling
|
||||||
const y = figure.top * scaling.h
|
const y = figure.top * scaling
|
||||||
|
|
||||||
const center = [mapCenter[0] + x, mapCenter[1] - y]
|
const center = [mapCenter[0] + x, mapCenter[1] - y]
|
||||||
|
|
||||||
const coords = figure.points?.split(' ').map(pair => {
|
const coords = figure.points?.split(' ').map(pair => {
|
||||||
const [x, y] = pair.split(';').map(Number)
|
const [x, y] = pair.split(';').map(Number)
|
||||||
return [
|
return [
|
||||||
center[0] + (x * scaling.w),
|
center[0] + (x * scaling),
|
||||||
center[1] - (y * scaling.h)
|
center[1] - (y * scaling)
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -112,10 +114,10 @@ export function processFigure(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (figure.figure_type_id == 4) {
|
if (figure.figure_type_id == 4) {
|
||||||
const width = figure.width * scaling.w
|
const width = figure.width * scaling
|
||||||
const height = figure.height * scaling.h
|
const height = figure.height * scaling
|
||||||
const left = figure.left * scaling.w
|
const left = figure.left * scaling
|
||||||
const top = figure.top * scaling.h
|
const top = figure.top * scaling
|
||||||
|
|
||||||
const halfWidth = width / 2
|
const halfWidth = width / 2
|
||||||
const halfHeight = height / 2
|
const halfHeight = height / 2
|
||||||
@ -193,7 +195,7 @@ export const addInteractions = (
|
|||||||
const measureType = getMeasureType()
|
const measureType = getMeasureType()
|
||||||
const tipPoint = getTipPoint()
|
const tipPoint = getTipPoint()
|
||||||
|
|
||||||
if (currentTool !== 'Measure' && currentTool !== 'Mover') {
|
if (currentTool !== 'Measure' && currentTool !== 'Mover' && currentTool !== 'Edit') {
|
||||||
draw.current = new Draw({
|
draw.current = new Draw({
|
||||||
source: drawingLayerSource.current,
|
source: drawingLayerSource.current,
|
||||||
type: currentTool as Type,
|
type: currentTool as Type,
|
||||||
@ -262,6 +264,11 @@ export const addInteractions = (
|
|||||||
translate.current = new Translate()
|
translate.current = new Translate()
|
||||||
map?.current?.addInteraction(translate.current)
|
map?.current?.addInteraction(translate.current)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (currentTool == 'Edit') {
|
||||||
|
//const modify = new Modify()
|
||||||
|
//map?.current?.addInteraction(translate.current)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function regionsInit(
|
export function regionsInit(
|
||||||
@ -269,6 +276,16 @@ export function regionsInit(
|
|||||||
selectedRegion: React.MutableRefObject<Feature<Geometry> | null>,
|
selectedRegion: React.MutableRefObject<Feature<Geometry> | null>,
|
||||||
regionsLayer: React.MutableRefObject<VectorImageLayer<Feature<Geometry>, VectorSource<Feature<Geometry>>>>,
|
regionsLayer: React.MutableRefObject<VectorImageLayer<Feature<Geometry>, VectorSource<Feature<Geometry>>>>,
|
||||||
) {
|
) {
|
||||||
|
regionsLayer.current.once('change', function () {
|
||||||
|
if (getSelectedCity() === null || getSelectedYear() === null) {
|
||||||
|
const extent = regionsLayer.current.getSource()?.getExtent()
|
||||||
|
|
||||||
|
if (extent && !extent?.every(val => Math.abs(val) === Infinity)) {
|
||||||
|
map.current?.getView().fit(fromExtent(extent) as SimpleGeometry, { duration: 500, maxZoom: 18, padding: [60, 60, 60, 60] })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
map.current?.on('click', function (e) {
|
map.current?.on('click', function (e) {
|
||||||
if (selectedRegion.current !== null) {
|
if (selectedRegion.current !== null) {
|
||||||
selectedRegion.current = null
|
selectedRegion.current = null
|
||||||
|
Reference in New Issue
Block a user