Skip to content

Commit

Permalink
Merge pull request #109 from MTES-MCT/rapportage-v1.3
Browse files Browse the repository at this point in the history
Rapportage v1.3
  • Loading branch information
thoomasbro authored Aug 30, 2022
2 parents 78369a6 + 4fb006d commit c8a166d
Show file tree
Hide file tree
Showing 10 changed files with 353 additions and 69 deletions.
12 changes: 12 additions & 0 deletions frontend/src/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,16 @@

.collapsed {
display: none;
}

.overlay-mission-hover {
z-index: 5000;
width: 0;
height: 0;
}

.overlay-mission-selected {
z-index: 4000;
width: 0;
height: 0;
}
43 changes: 22 additions & 21 deletions frontend/src/features/map/overlays/OverlayPositionOnCentroid.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ import styled from 'styled-components'
import Overlay from 'ol/Overlay'
import { getCenter } from 'ol/extent'

import { getOverlayPosition, getTopLeftMargin } from './position'
import { getOverlayPositionForCentroid, getTopLeftMargin } from './position'

import { COLORS } from '../../../constants/constants'

const overlayHeight = 74
const defaultMarginsWithoutAlert = {
const OVERLAY_HEIGHT = 74

const defaultMargins = {
xRight: -252,
xMiddle: -116,
xLeft: 20,
Expand All @@ -23,63 +24,63 @@ export const OverlayPositionOnCentroid = ({
feature,
children,
options: {
marginsWithoutAlert = defaultMarginsWithoutAlert
margins = defaultMargins
} = {}
}) => {
const overlayRef = useRef(null)
const overlayObjectRef = useRef(null)
const [overlayTopLeftMargin, setOverlayTopLeftMargin] = useState([marginsWithoutAlert.yBottom, marginsWithoutAlert.xMiddle])
const olOverlayObjectRef = useRef(null)
const [overlayTopLeftMargin, setOverlayTopLeftMargin] = useState([margins.yBottom, margins.xMiddle])

const overlayCallback = useCallback(ref => {
overlayRef.current = ref
if (ref) {
overlayObjectRef.current = new Overlay({
olOverlayObjectRef.current = new Overlay({
element: ref,
})
} else {
overlayObjectRef.current = null
olOverlayObjectRef.current = null
}
}, [overlayRef, overlayObjectRef])
}, [overlayRef, olOverlayObjectRef])

useEffect(() => {
if (map) {
map.addOverlay(overlayObjectRef.current)
map.addOverlay(olOverlayObjectRef.current)
}
return () => {
map.removeOverlay(overlayObjectRef.current)
map.removeOverlay(olOverlayObjectRef.current)
}
}, [map, overlayObjectRef])
}, [map, olOverlayObjectRef])

useEffect(() => {
function getNextOverlayPosition (featureCenter) {
const [x, y] = featureCenter
const extent = map.getView().calculateExtent()
const boxSize = map.getView().getResolution() * overlayHeight
return getOverlayPosition(boxSize, x, y, extent)
const boxSize = map.getView().getResolution() * OVERLAY_HEIGHT
return getOverlayPositionForCentroid(boxSize, x, y, extent)
}

if (overlayRef.current && overlayObjectRef.current) {
if (overlayRef.current && olOverlayObjectRef.current) {
if (feature) {
const featureCenter = getCenter(feature.getGeometry().getExtent())
overlayObjectRef.current.setPosition(featureCenter)
olOverlayObjectRef.current.setPosition(featureCenter)
const nextOverlayPosition = getNextOverlayPosition(featureCenter)
setOverlayTopLeftMargin(getTopLeftMargin(nextOverlayPosition, marginsWithoutAlert))
setOverlayTopLeftMargin(getTopLeftMargin(nextOverlayPosition, margins))
overlayRef.current.style.display = 'block'
} else {
overlayRef.current.style.display = 'none'
}
}
}, [feature, overlayRef, overlayObjectRef, map])
}, [feature, overlayRef, olOverlayObjectRef, map])


return (
<MissionCardOverlayComponent ref={overlayCallback} overlayTopLeftMargin={overlayTopLeftMargin}>
<OverlayComponent ref={overlayCallback} overlayTopLeftMargin={overlayTopLeftMargin}>
{ feature && children }
</MissionCardOverlayComponent>
</OverlayComponent>
)
}

const MissionCardOverlayComponent = styled.div`
const OverlayComponent = styled.div`
position: absolute;
top: ${props => props.overlayTopLeftMargin[0]}px;
left: ${props => props.overlayTopLeftMargin[1]}px;
Expand Down
112 changes: 112 additions & 0 deletions frontend/src/features/map/overlays/OverlayPositionOnExtent.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import React, { useCallback, useEffect, useRef, useState } from 'react'
// import { useSelector } from 'react-redux'
import styled from 'styled-components'
import Overlay from 'ol/Overlay'
import { getCenter } from 'ol/extent'

import { getOverlayPositionForExtent, getTopLeftMarginForFeature } from './position'

import { COLORS } from '../../../constants/constants'

const OVERLAY_HEIGHT = 124
const OVERLAY_WIDTH = 365

const defaultMargins = {
top: {
top: 20,
middle: 20,
bottom: 20
},
left: {
right: 20,
center: 20,
left: 20,
}
}

export const OverlayPositionOnExtent = ({
map,
feature,
appClassName,
children,
options: {
margins = defaultMargins
} = {}
}) => {
const overlayRef = useRef(null)
const olOverlayObjectRef = useRef(null)
const [overlayTopLeftMargin, setOverlayTopLeftMargin] = useState([margins.yBottom, margins.xMiddle])

const overlayCallback = useCallback(ref => {
overlayRef.current = ref
if (ref) {
olOverlayObjectRef.current = new Overlay({
element: ref,
className: `ol-overlay-container ol-selectable ${appClassName}`
})
} else {
olOverlayObjectRef.current = null
}
}, [overlayRef, olOverlayObjectRef])

useEffect(() => {
if (map) {
map.addOverlay(olOverlayObjectRef.current)
}
return () => {
map.removeOverlay(olOverlayObjectRef.current)
}
}, [map, olOverlayObjectRef])

useEffect(() => {

if (overlayRef.current && olOverlayObjectRef.current) {
if (feature) {
const featureExtent = feature.getGeometry().getExtent()
const featureCenter = getCenter(featureExtent)
const resolution = map.getView().getResolution()
const extent = map.getView().calculateExtent()

const nextOverlayPosition = getOverlayPositionForExtent(
featureExtent,
extent,
margins,
{width: OVERLAY_WIDTH, height: OVERLAY_HEIGHT, resolution}
)
console.log('position', nextOverlayPosition, featureExtent,
extent,
margins,
{width: OVERLAY_WIDTH, height: OVERLAY_HEIGHT, resolution})
const containerMargins = getTopLeftMarginForFeature(
nextOverlayPosition,
margins,
featureExtent,
featureCenter,
{width: OVERLAY_WIDTH, height: OVERLAY_HEIGHT, resolution}
)

olOverlayObjectRef.current.setPosition(featureCenter)
setOverlayTopLeftMargin(containerMargins)
overlayRef.current.style.display = 'block'
} else {
overlayRef.current.style.display = 'none'
}
}
}, [feature, overlayRef, olOverlayObjectRef, map])


return (
<OverlayComponent ref={overlayCallback} overlayTopLeftMargin={overlayTopLeftMargin}>
{ feature && children }
</OverlayComponent>
)
}

const OverlayComponent = styled.div`
position: relative;
top: ${props => props.overlayTopLeftMargin[0]}px;
left: ${props => props.overlayTopLeftMargin[1]}px;
text-align: left;
background-color: ${COLORS.white};
border-radius: 2px;
`
11 changes: 9 additions & 2 deletions frontend/src/features/map/overlays/missions/MissionCard.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,9 @@ const MissionCardHeader = styled.div`
border-top-left-radius: 2px;
border-top-right-radius: 2px;
display: flex;
width: 265px;
z-index: ${props=> props.selected ? 4900 : 5000}
width: 380px;
height: 124px;
box-shadow: 0px 3px 6px rgba(0,0,0,.3);
`

const MissionDate = styled.div`
Expand All @@ -85,6 +86,11 @@ const MissionType = styled.div`
const MissionReources = styled.div`
font-size: 12px;
color: ${COLORS.slateGray};
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
`
const Actions = styled.div`
`
Expand All @@ -96,5 +102,6 @@ const Col2 = styled.div`
padding: 8px 8px 4px 8px;
`
const Col3 = styled.div`
margin-left: auto;
padding-right: 4px;
`
20 changes: 14 additions & 6 deletions frontend/src/features/map/overlays/missions/MissionOverlays.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import React from 'react'
import { useSelector } from 'react-redux'

import { OverlayPositionOnCentroid } from '../OverlayPositionOnCentroid'
import { MissionCard } from './MissionCard'
import Layers from '../../../../domain/entities/layers'
import { OverlayPositionOnExtent } from '../OverlayPositionOnExtent'


export const MissionOverlays = ({map, currentFeatureOver}) => {
Expand All @@ -13,12 +13,20 @@ export const MissionOverlays = ({map, currentFeatureOver}) => {
const displayHoveredFeature = currentFeatureOver?.getId()?.startsWith(Layers.MISSIONS.code) && currentFeatureOver?.getId() !== `${Layers.MISSIONS.code}:${selectedMissionId}`
return (
<>
<OverlayPositionOnCentroid feature={displayMissionsOverlay && feature} map={map}>
<OverlayPositionOnExtent
feature={displayMissionsOverlay && feature}
map={map}
appClassName={'overlay-mission-selected'}
>
<MissionCard feature={feature} selected />
</OverlayPositionOnCentroid>
<OverlayPositionOnCentroid feature={displayMissionsOverlay && displayHoveredFeature && currentFeatureOver} map={map} >
</OverlayPositionOnExtent>
<OverlayPositionOnExtent
feature={displayMissionsOverlay && displayHoveredFeature && currentFeatureOver}
map={map}
appClassName={'overlay-mission-hover'}
>
<MissionCard feature={currentFeatureOver} />
</OverlayPositionOnCentroid>
</OverlayPositionOnExtent>
</>
)
}
}
Loading

0 comments on commit c8a166d

Please sign in to comment.