Projekt

Obecné

Profil

« Předchozí | Další » 

Revize 91fd3fa6

Přidáno uživatelem Václav Honzík před asi 2 roky(ů)

Nonrecursive algorithm for path building + path rendering on map

re #9629

Zobrazit rozdíly:

frontend/src/features/TrackingTool/TrackingTool.tsx
8 8
    Stack,
9 9
    Typography,
10 10
} from '@mui/material'
11
import { Fragment, useState } from 'react'
11
import { Fragment, useEffect, useState } from 'react'
12 12
import AddIcon from '@mui/icons-material/Add'
13 13
import { MapContainer, Marker, Polyline, Popup, TileLayer } from 'react-leaflet'
14 14
import mapConfig from '../../config/mapConfig'
......
19 19
import DeleteIcon from '@mui/icons-material/Delete'
20 20
import { PathDto } from '../../swagger/data-contracts'
21 21
import { formatHtmlStringToReactDom } from '../../utils/formatting/HtmlUtils'
22
import buildPathVariants, { PathVariant } from './buildPathVariants'
22 23

  
23 24
// Page with tracking tool
24 25
const TrackingTool = () => {
25 26
    // Path response from the API
26 27
    const [pathDto, setPathDto] = useState<PathDto | undefined>(undefined)
27 28

  
28
    const createDummyPathCoords = () => {
29
        // Sample dummy path to display
30
        const dummyPath = []
31
        for (let i = 0; i < 10; i += 1) {
32
            dummyPath.push({
33
                latitude:
34
                    mapConfig.defaultCoordinates[0] +
35
                    i * 0.1 +
36
                    Math.random() * 0.1,
37
                longitude:
38
                    mapConfig.defaultCoordinates[1] +
39
                    i * 0.1 +
40
                    Math.random() * 0.1,
41
            })
42
        }
43
        return dummyPath
44
    }
29
    // Whether the path variants are building
30
    const [buildingPathVariants, setBuildingPathVariants] =
31
        useState<boolean>(false)
45 32

  
46
    const createDummyPath = () => {
47
        const coords = createDummyPathCoords()
48
        const polylines: any[] = []
33
    // List of all computed path variants
34
    const [pathVariants, setPathVariants] = useState<PathVariant[] | undefined>(
35
        undefined
36
    )
49 37

  
50
        if (coords.length < 2) {
51
            return []
52
        }
38
    // List of all rendered paths to display
39
    const [renderedPaths, setRenderedPaths] = useState<any[]>([])
53 40

  
54
        for (let i = 0; i < coords.length - 1; i += 1) {
55
            polylines.push(
56
                <TextPath
57
                    positions={[
58
                        [coords[i].latitude, coords[i].longitude],
59
                        [coords[i + 1].latitude, coords[i + 1].longitude],
60
                    ]}
61
                    text="►"
62
                    attributes={{
63
                        'font-size': 25,
64
                        fill: 'blue',
65
                    }}
66
                    repeat
67
                    center
68
                    weight={10}
69
                ></TextPath>
70
            )
71
        }
41
    const [mapCenter, setMapCenter] = useState<number[]>([
42
        mapConfig.defaultCoordinates[0],
43
        mapConfig.defaultCoordinates[1],
44
    ])
45

  
46
    // Returns tuple of average latitude and longitude
47
    const calculateMapCenter = (pathVariant: PathVariant) => [
48
        pathVariant
49
            .map((item) => item.latitude ?? 0)
50
            .reduce((a, b) => a + b, 0) / pathVariant.length,
51
        pathVariant
52
            .map((item) => item.longitude ?? 0)
53
            .reduce((a, b) => a + b, 0) / pathVariant.length,
54
    ]
72 55

  
73
        return [polylines, coords]
74
    }
56
    useEffect(() => {
57
        if (!pathDto) {
58
            return
59
        }
75 60

  
76
    const [polylines, coords] = createDummyPath()
61
        setBuildingPathVariants(true)
62
        buildPathVariants(pathDto).then((pathVariants) => {
63
            setPathVariants(pathVariants)
64
            setBuildingPathVariants(false)
65
            const paths: any[] = []
66
            let first = true
67
            pathVariants?.forEach((pathVariant) => {
68
                if (first) {
69
                    setMapCenter(calculateMapCenter(pathVariant))
70
                }
71
                for (let i = 0; i < pathVariant.length - 1; i++) {
72
                    paths.push(
73
                        <TextPath
74
                            positions={[
75
                                [
76
                                    pathVariant[i].latitude,
77
                                    pathVariant[i].longitude,
78
                                ],
79
                                [
80
                                    pathVariant[i + 1].latitude,
81
                                    pathVariant[i + 1].longitude,
82
                                ],
83
                            ]}
84
                            text="►"
85
                            attributes={{
86
                                'font-size': 25,
87
                                fill: first ? 'blue' : 'gray',
88
                            }}
89
                            repeat
90
                            center
91
                            weight={10}
92
                        />
93
                    )
94
                }
95
                first = false
96
            })
97
            console.log(paths)
98
            setRenderedPaths(paths)
99
        })
100
    }, [pathDto])
77 101

  
78 102
    return (
79 103
        <Fragment>
......
146 170
                    }}
147 171
                >
148 172
                    <MapContainer
149
                        center={[
150
                            mapConfig.defaultCoordinates[0],
151
                            mapConfig.defaultCoordinates[1],
152
                        ]}
173
                        center={[mapCenter[0], mapCenter[1]]}
153 174
                        zoom={mapConfig.defaultZoom}
154 175
                        style={{ height: '100%', minHeight: '100%' }}
155 176
                    >
......
157 178
                            attribution={mapConfig.attribution}
158 179
                            url={mapConfig.url}
159 180
                        />
160
                        {coords.map(({ latitude, longitude }, idx) => (
161
                            <Marker position={[latitude, longitude]} />
162
                        ))}
163
                        {polylines}
181
                        {renderedPaths}
164 182
                    </MapContainer>
165 183
                </Grid>
166 184
            </Grid>

Také k dispozici: Unified diff