1 |
48690561
|
Vaclav Honzik
|
|
2 |
|
|
import L, { LatLngTuple, PointExpression } from 'leaflet'
|
3 |
c0b66eaf
|
Vaclav Honzik
|
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 |
08854c45
|
Vaclav Honzik
|
// 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 |
c0b66eaf
|
Vaclav Honzik
|
return `data:image/svg+xml;utf8, ${encodeURIComponent(`
|
52 |
08854c45
|
Vaclav Honzik
|
<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 |
c0b66eaf
|
Vaclav Honzik
|
}
|
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 |
26f9c9ff
|
Vaclav Honzik
|
const iconAnchor = [25, 25] as PointExpression
|
69 |
|
|
const iconSize = [40, 40] as PointExpression
|
70 |
c0b66eaf
|
Vaclav Honzik
|
|
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 |
48690561
|
Vaclav Honzik
|
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 |
|
|
}
|