• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

geosolutions-it / MapStore2 / 19700584114

26 Nov 2025 10:28AM UTC coverage: 76.667%. Remained the same
19700584114

Pull #11737

github

web-flow
Merge 6de2f2444 into c0b948793
Pull Request #11737: Fix #11731 Support for Burgermenu in Itinerary and Isochrone plugin

32267 of 50209 branches covered (64.27%)

40158 of 52380 relevant lines covered (76.67%)

37.88 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

97.5
/web/client/components/styleeditor/RuleLegendIcon.jsx
1
/*
2
 * Copyright 2023, GeoSolutions Sas.
3
 * All rights reserved.
4
 *
5
 * This source code is licensed under the BSD-style license found in the
6
 * LICENSE file in the root directory of this source tree.
7
 */
8

9
import React, { useState, useEffect, useRef } from 'react';
10
import { Glyphicon } from 'react-bootstrap';
11
import {
12
    parseSymbolizerExpressions,
13
    getWellKnownNameImageFromSymbolizer
14
} from '../../utils/styleparser/StyleParserUtils';
15

16
const icon = {
1✔
17
    Line: ({ symbolizer }) => {
18
        const displayWidth = symbolizer.width === 0
10✔
19
            ? 1
20
            : symbolizer.width > 7
9✔
21
                ? 7
22
                : symbolizer.width;
23
        return (
10✔
24
            <svg viewBox="0 0 50 50">
25
                <path d={`M ${displayWidth} ${displayWidth} L ${50 - displayWidth} ${50 - displayWidth}`}
26
                    stroke={symbolizer.color}
27
                    strokeWidth={displayWidth}
28
                    strokeDasharray={symbolizer.dasharray ? "18 18" : null}
10✔
29
                    strokeLinecap={symbolizer.cap}
30
                    strokeLinejoin={symbolizer.join}
31
                    strokeOpacity={symbolizer.opacity}
32
                />
33
            </svg>
34
        );
35
    },
36
    Fill: ({ symbolizer }) => {
37
        return (
24✔
38
            <svg viewBox="0 0 50 50">
39
                <path d="M 1 1 L 1 49 L 49 49 L 49 1 L 1 1"
40
                    fill={symbolizer.color}
41
                    opacity={symbolizer.fillOpacity}
42
                    stroke={symbolizer.outlineColor}
43
                    strokeWidth={symbolizer.outlineWidth}
44
                    strokeOpacity={symbolizer.outlineOpacity}
45
                />
46
            </svg>
47
        );
48
    },
49
    Circle: ({ symbolizer }) => {
50
        return (
2✔
51
            <svg viewBox="0 0 50 50">
52
                <circle cx="25" cy="25" r="25"
53
                    fill={symbolizer.color}
54
                    opacity={symbolizer.opacity}
55
                    stroke={symbolizer.outlineColor}
56
                    strokeWidth={symbolizer.outlineWidth}
57
                    strokeOpacity={symbolizer.outlineOpacity}
58
                />
59
            </svg>
60
        );
61
    },
62
    Mark: ({ symbolizer }) => {
63

64
        const [iconData, setIconData] = useState(null);
12✔
65
        const isMounted = useRef();
12✔
66

67
        useEffect(() => {
12✔
68
            isMounted.current = true;
6✔
69
            return () => {
6✔
70
                isMounted.current = false;
6✔
71
            };
72
        }, []);
73

74
        useEffect(() => {
12✔
75
            getWellKnownNameImageFromSymbolizer(symbolizer)
6✔
76
                .then((data) => {
77
                    if (isMounted.current) {
6!
78
                        setIconData(data);
6✔
79
                    }
80
                });
81
        }, [symbolizer]);
82

83
        const { rotate, opacity } = symbolizer;
12✔
84
        const svgStyle = { transform: `rotate(${rotate}deg)`, opacity };
12✔
85
        return (
12✔
86
            <svg viewBox="0 0 50 50" style={svgStyle}>
87
                {iconData && <image href={iconData.src} height="50" width="50" />}
18✔
88
            </svg>
89
        );
90
    },
91
    Icon: ({ symbolizer }) => {
92
        const [iconData, setIconData] = useState(null);
9✔
93
        const isMounted = useRef();
9✔
94

95
        useEffect(() => {
9✔
96
            isMounted.current = true;
7✔
97
            return () => {
7✔
98
                isMounted.current = false;
7✔
99
            };
100
        }, []);
101

102
        useEffect(() => {
9✔
103
            if (symbolizer?.image) {
8✔
104
                const img = new Image();
6✔
105
                img.onload = () => {
6✔
106
                    if (isMounted.current) {
1!
107
                        setIconData(img);
1✔
108
                    }
109
                };
110
                img.onerror = () => {
6✔
111
                    if (isMounted.current) {
5!
112
                        setIconData(null);
×
113
                    }
114
                };
115
                img.src = symbolizer.image;
6✔
116
            }
117
        }, [symbolizer?.image]);
118
        return iconData
9✔
119
            ? (<svg viewBox="0 0 50 50" style={{ transform: `rotate(${symbolizer.rotate}deg)`, opacity: symbolizer.opacity }}>
120
                <image href={iconData.src} height="50" width="50" />
121
            </svg>)
122
            : <Glyphicon glyph="point"/>;
123
    },
124
    Model: () => <Glyphicon glyph="model"/>,
1✔
125
    Text: ({ symbolizer }) => {
126
        return (
4✔
127
            <svg viewBox="0 0 16 16">
128
                <text x="8" y="8" textAnchor="middle" alignmentBaseline="middle" style={{
129
                    fontSize: symbolizer.size < 14 ? symbolizer.size : 14,
4!
130
                    fill: symbolizer.color,
131
                    fontFamily: symbolizer?.font?.join(', '),
132
                    fontStyle: symbolizer.fontStyle,
133
                    fontWeight: symbolizer.fontWeight,
134
                    ...((symbolizer.haloWidth && symbolizer.haloColor) && {
6✔
135
                        paintOrder: 'stroke',
136
                        stroke: symbolizer.haloColor,
137
                        strokeWidth: 1,
138
                        strokeLinecap: 'round',
139
                        strokeLinejoin: 'round'
140
                    })
141
                }} >T</text>
142
            </svg>
143
        );
144
    }
145
};
146

147
function RuleLegendIcon({
148
    rule
149
}) {
150
    const symbolizer = parseSymbolizerExpressions(rule?.symbolizers?.[0] || {}, { properties: {} });
61✔
151
    const Icon = icon[symbolizer.kind];
61✔
152
    return Icon ? <div className="ms-legend-icon"><Icon symbolizer={symbolizer}/></div> : null;
61✔
153
}
154

155
export default RuleLegendIcon;
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc