Projekt

Obecné

Profil

Stáhnout (4.03 KB) Statistiky
| Větev: | Tag: | Revize:
1

    
2
import L, { LatLngTuple, PointExpression } from 'leaflet'
3
import { CatalogItemDto } from '../../swagger/data-contracts'
4

    
5
// For more comprehensive code alias CatalogItemDto[] as path variant
6
export type PathVariant = MapPoint[]
7

    
8
export enum MapPointType {
9
    LocalCatalog, // Fetched from local catalog
10
    ExternalCatalog, // Fetched from external catalog
11
    GeoJson, // From GeoJSON file
12
    FromCoordinates, // From coordinates
13
}
14

    
15
// Represents a point on the map - wrapper for CatalogItemDto to make it easier to work with
16
export interface MapPoint {
17
    id: string // unique id for react
18
    idx: number,
19
    addToPath: boolean, // whether to add the point to the path
20
    catalogItem: CatalogItemDto,
21
    type: MapPointType
22
    hidden?: boolean // if true the point will not be displayed on the map
23
}
24

    
25
export const isMapPointDisplayable = (mapPoint: MapPoint): boolean =>
26
    !!mapPoint.catalogItem.latitude && !!mapPoint.catalogItem.longitude && !mapPoint.hidden
27

    
28
/**
29
 * Based on its type - either imported from local catalog, remote catalogs etc. each type has its own color to differentiate them
30
 * @param item item to get color for
31
 * @returns CSS color string
32
 */
33
export const getMapPointSemanticColor = (item: MapPoint) => {
34
    switch (item.type) {
35
        case MapPointType.LocalCatalog:
36
            return 'inherit'
37
        case MapPointType.FromCoordinates:
38
            return '#21972D'
39
        case MapPointType.ExternalCatalog:
40
            return '#A72020'
41
        case MapPointType.GeoJson:
42
            return '#967520'
43
    }
44
}
45

    
46
const createMapMarkerSvg = (color: string) => {
47
    // return `data:image/svg+xml;utf8, ${encodeURIComponent(`
48
    // <svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="${color}">
49
    //  <path d="M0 0h24v24H0z" fill="none" /><path d="M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z" />
50
    //  </svg>`)}`
51
    return `data:image/svg+xml;utf8, ${encodeURIComponent(`
52
    <svg width="16px" height="16px" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" version="1.1" fill="blue"
53
    stroke="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="1">
54
    <path
55
        fill="${color}"
56
        d="m13.25 7c0 3.75-5.25 7.25-5.25 7.25s-5.25-3.5-5.25-7.25c0-2.89949 2.35051-5.25 5.25-5.25 2.8995 0 5.25 2.35051 5.25 5.25z" />
57
    <circle cx="8" cy="7" r="1.55" fill="white" />
58
    </svg> `)}`
59
}
60

    
61
const mapMarkerSvgs = {
62
    [MapPointType.LocalCatalog]: createMapMarkerSvg('#285CAB'),
63
    [MapPointType.ExternalCatalog]: createMapMarkerSvg('#A72020'),
64
    [MapPointType.GeoJson]: createMapMarkerSvg('#967520'),
65
    [MapPointType.FromCoordinates]: createMapMarkerSvg('#21972D'),
66
}
67

    
68
const iconAnchor = [25, 25] as PointExpression
69
const iconSize = [40, 40] as PointExpression
70

    
71
const mapMarkers = {
72
    [MapPointType.LocalCatalog]: L.icon({
73
        iconAnchor, iconSize,
74
        iconUrl: mapMarkerSvgs[MapPointType.LocalCatalog],
75
    }),
76
    [MapPointType.ExternalCatalog]: L.icon({
77
        iconAnchor, iconSize,
78
        iconUrl: mapMarkerSvgs[MapPointType.ExternalCatalog],
79
    }),
80

    
81
    [MapPointType.GeoJson]: L.icon({
82
        iconAnchor, iconSize,
83
        iconUrl: mapMarkerSvgs[MapPointType.GeoJson],
84
    }),
85
    [MapPointType.FromCoordinates]: L.icon({
86
        iconAnchor, iconSize,
87
        iconUrl: mapMarkerSvgs[MapPointType.FromCoordinates],
88
    }),
89
}
90

    
91
export const getMapPointIcon = (item: MapPoint): L.Icon => mapMarkers[item.type]
92

    
93
export const calculateMapCenter = (pathVariant: PathVariant): LatLngTuple | undefined => {
94
    const displayableItems = pathVariant.filter((item) => isMapPointDisplayable(item))
95
    if (displayableItems.length === 0) {
96
        return undefined
97
    }
98

    
99
    return [
100
        displayableItems
101
            .map((item) => item.catalogItem.latitude ?? 0)
102
            .reduce((a, b) => a + b, 0) / displayableItems.length,
103
        displayableItems
104
            .map((item) => item.catalogItem.longitude ?? 0)
105
            .reduce((a, b) => a + b, 0) / displayableItems.length,
106
    ]
107
}
(5-5/5)