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

jumpinjackie / mapguide-react-layout / 15160437878

21 May 2025 11:00AM UTC coverage: 21.631% (-42.6%) from 64.24%
15160437878

Pull #1552

github

web-flow
Merge 8b7153d9e into 236e2ea07
Pull Request #1552: Feature/package updates 2505

839 of 1165 branches covered (72.02%)

11 of 151 new or added lines in 25 files covered. (7.28%)

1332 existing lines in 50 files now uncovered.

4794 of 22163 relevant lines covered (21.63%)

6.89 hits per line

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

0.0
/src/api/ol-style-map-set.ts
1
import { DEFAULT_STYLE_KEY, isClusteredFeature } from './ol-style-helpers';
×
2
import { ExprEvalContext } from './expr-eval-context';
×
3
import Feature from 'ol/Feature';
4
import Geometry from 'ol/geom/Geometry';
5
import { DynamicStyleMap, IOlStyleMap, IVectorLayerStyle, IVectorFeatureStyle, DEFAULT_POINT_CIRCLE_STYLE, DEFAULT_LINE_STYLE, DEFAULT_POLY_STYLE, IBasicStroke, isEvaluatable, IBasicFill, IVectorLabelSettings, IBasicVectorPointStyle, IBasicVectorLineStyle, IBasicVectorPolygonStyle, IClusterSettings, ClusterClickAction } from './ol-style-contracts';
×
6
import Style from 'ol/style/Style';
×
7
import CircleStyle from 'ol/style/Circle';
×
8
import { buildFill, buildStroke, tryBuildTextStyle, evalFeature } from './ol-style-builders';
×
9
import IconStyle from "ol/style/Icon";
×
10
import { deg2rad } from '../utils/number';
×
11
import { ScopedId } from '../utils/scoped-id';
×
12

13
const scopedId = new ScopedId();
×
14

15
function isDynamicStroke(stroke: IBasicStroke | undefined): boolean {
×
16
    if (!stroke) {
×
17
        return false;
×
18
    }
×
19
    return isEvaluatable(stroke.alpha)
×
20
        || isEvaluatable(stroke.color)
×
21
        || isEvaluatable(stroke.width);
×
22
}
×
23

24
function isDynamicFill(fill: IBasicFill | undefined): boolean {
×
25
    if (!fill) {
×
26
        return false;
×
27
    }
×
28
    return isEvaluatable(fill.alpha)
×
29
        || isEvaluatable(fill.color);
×
30
}
×
31

32
function isDynamicLabel(labelSettings: IVectorLabelSettings): boolean {
×
33
    const { label } = labelSettings;
×
34
    if (!label) {
×
35
        return false;
×
36
    }
×
37
    return isDynamicFill(label.backgroundFill)
×
38
        || isDynamicStroke(label.backgroundStroke)
×
39
        || isDynamicFill(label.fill)
×
40
        || isEvaluatable(label.font)
×
41
        || isEvaluatable(label.maxAngle)
×
42
        || isEvaluatable(label.offsetX)
×
43
        || isEvaluatable(label.offsetY)
×
44
        || isEvaluatable(label.overflow)
×
45
        || isEvaluatable(label.padding)
×
46
        || isEvaluatable(label.placement)
×
47
        || isEvaluatable(label.rotateWithView)
×
48
        || isEvaluatable(label.rotation)
×
49
        || isEvaluatable(label.scale)
×
50
        || isDynamicStroke(label.stroke)
×
51
        || isEvaluatable(label.text)
×
52
        || isEvaluatable(label.textAlign)
×
53
        || isEvaluatable(label.textBaseline);
×
54
}
×
55

56
function isDynamicPointStyle(style: IBasicVectorPointStyle): boolean {
×
57
    const apts: any = style;
×
58
    const isBaseDynamic = isEvaluatable(apts.radius)
×
59
        || isDynamicFill(apts.fill)
×
60
        || isDynamicStroke(apts.stroke);
×
61
    if (isBaseDynamic) {
×
62
        return true;
×
63
    }
×
64
    return isDynamicLabel(style);
×
65
}
×
66

67
function isDynamicLineStyle(style: IBasicVectorLineStyle): boolean {
×
68
    return isDynamicStroke(style)
×
69
        || isDynamicLabel(style);
×
70
}
×
71

72
function isDynamicPolygonStyle(style: IBasicVectorPolygonStyle): boolean {
×
73
    return isDynamicStroke(style.stroke)
×
74
        || isDynamicFill(style.fill)
×
75
        || isDynamicLabel(style);
×
76
}
×
77

78
function buildStyleMap(pts: Style, lns: Style, pls: Style) {
×
79
    //For GeometryCollection, combine point and polygon styles
80
    const cpts = pts.clone();
×
81
    const cpls = pls.clone();
×
82
    const gcs = new Style({
×
NEW
83
        image: cpts.getImage() ?? undefined,
×
NEW
84
        stroke: cpls.getStroke() ?? undefined,
×
NEW
85
        fill: cpls.getFill() ?? undefined
×
86
    });
×
87
    return {
×
88
        id: `${scopedId.next()}`,
×
89
        Point: pts,
×
90
        MultiPoint: pts,
×
91
        LineString: lns,
×
92
        MultiLineString: lns,
×
93
        Polygon: pls,
×
94
        MultiPolygon: pls,
×
95
        Circle: pls,
×
96
        GeometryCollection: gcs
×
97
    };
×
98
}
×
99

100
export function vectorStyleToStyleMap(style: IVectorFeatureStyle): IOlStyleMap | DynamicStyleMap {
×
101
    const ptStyle = style.point ?? DEFAULT_POINT_CIRCLE_STYLE;
×
102
    const lnStyle = style.line ?? DEFAULT_LINE_STYLE;
×
103
    const plStyle = style.polygon ?? DEFAULT_POLY_STYLE;
×
104

105
    const builder: DynamicStyleMap = (feat, context) => {
×
106
        const pts = new Style();
×
107
        if (ptStyle.type == "Circle") {
×
108
            pts.setImage(new CircleStyle({
×
109
                radius: evalFeature(ptStyle.radius, feat, context),
×
110
                fill: buildFill(ptStyle.fill, feat, context),
×
111
                stroke: buildStroke(ptStyle.stroke, feat, context)
×
112
            }));
×
113
        } else {
×
114
            pts.setImage(new IconStyle({
×
115
                anchor: ptStyle.anchor,
×
116
                src: evalFeature(ptStyle.src, feat, context),
×
117
                rotateWithView: evalFeature(ptStyle.rotateWithView, feat, context),
×
118
                rotation: deg2rad(evalFeature(ptStyle.rotation, feat, context)),
×
119
                scale: evalFeature(ptStyle.scale, feat, context)
×
120
            }));
×
121
        }
×
122
        const lns = new Style({
×
123
            stroke: buildStroke(lnStyle, feat, context)
×
124
        });
×
125
        const pls = new Style({
×
126
            stroke: buildStroke(plStyle.stroke, feat, context),
×
127
            fill: buildFill(plStyle.fill, feat, context)
×
128
        });
×
129

130
        const ptText = tryBuildTextStyle(ptStyle, feat, context);
×
131
        const lnText = tryBuildTextStyle(lnStyle, feat, context);
×
132
        const plsText = tryBuildTextStyle(plStyle, feat, context);
×
133
        if (ptText) {
×
134
            pts.setText(ptText);
×
135
        }
×
136
        if (lnText) {
×
137
            lns.setText(lnText);
×
138
        }
×
139
        if (plsText) {
×
140
            pls.setText(plsText);
×
141
        }
×
142
        return buildStyleMap(pts, lns, pls);
×
143
    }
×
144

145
    const isDynamic = isDynamicPointStyle(ptStyle)
×
146
        || isDynamicLineStyle(lnStyle)
×
147
        || isDynamicPolygonStyle(plStyle);
×
148

149
    if (isDynamic) {
×
150
        return builder;
×
151
    } else {
×
152
        return builder(undefined, undefined);
×
153
    }
×
154
}
×
155

156
/**
157
 * @since 0.14
158
 */
159
export class OLStyleMapSet {
×
160
    private rules: {
161
        [filter: string]: IOlStyleMap | DynamicStyleMap;
162
        default: IOlStyleMap | DynamicStyleMap;
163
    };
164
    private clusterRules: {
165
        [filter: string]: IOlStyleMap | DynamicStyleMap;
166
        default: IOlStyleMap | DynamicStyleMap;
167
    } | undefined;
168
    private exprContext: ExprEvalContext;
169
    private defaultStyleMap: IOlStyleMap | DynamicStyleMap;
170
    constructor(private readonly origStyleDef: IVectorLayerStyle, private readonly clusterStyleDef: IClusterSettings | undefined) {
×
171
        this.rules = {
×
172
            default: vectorStyleToStyleMap(origStyleDef.default)
×
173
        };
×
174
        this.exprContext = new ExprEvalContext();
×
175
        for (const k in origStyleDef) {
×
176
            if (k != DEFAULT_STYLE_KEY && origStyleDef[k]) {
×
177
                this.rules[k] = vectorStyleToStyleMap(origStyleDef[k]);
×
178
            }
×
179
            if (k != DEFAULT_STYLE_KEY) {
×
180
                this.exprContext.addFilter(k);
×
181
            }
×
182
        }
×
183
        if (clusterStyleDef?.style) {
×
184
            const { style } = clusterStyleDef;
×
185
            this.clusterRules = {
×
186
                default: vectorStyleToStyleMap(style.default)
×
187
            };
×
188
            for (const k in style) {
×
189
                if (k != DEFAULT_STYLE_KEY && style[k]) {
×
190
                    this.clusterRules[k] = vectorStyleToStyleMap(style[k]);
×
191
                }
×
192
                if (k != DEFAULT_STYLE_KEY) {
×
193
                    this.exprContext.addClusterFilter(k);
×
194
                }
×
195
            }
×
196
        }
×
197
        this.defaultStyleMap = vectorStyleToStyleMap({});
×
198
    }
×
199
    public toVectorLayerStyle(): IVectorLayerStyle {
×
200
        return this.origStyleDef;
×
201
    }
×
202
    public toClusterSettings(): IClusterSettings | undefined {
×
203
        return this.clusterStyleDef;
×
204
    }
×
205
    public getClusterClickAction(): ClusterClickAction | undefined {
×
206
        return this.clusterStyleDef?.onClick;
×
207
    }
×
208
    public evaluateStyle(feature: Feature<Geometry>) {
×
209
        try {
×
210
            const g = feature.getGeometry();
×
211
            if (!g) {
×
212
                return null;
×
213
            }
×
214
            const gt: any = g.getType();
×
215
            const filter = this.exprContext.evaluateFilter(feature);
×
216
            let matchingStyle: IOlStyleMap | DynamicStyleMap;
×
217
            const r = isClusteredFeature(feature) ? this.clusterRules : this.rules;
×
218
            if (filter) {
×
219
                matchingStyle = r?.[filter] ?? this.defaultStyleMap;
×
220
            } else {
×
221
                //Fallback to default
222
                matchingStyle = r?.default ?? this.defaultStyleMap;
×
223
            }
×
224
            if (typeof (matchingStyle) == 'function') {
×
225
                const esm = matchingStyle(feature, this.exprContext);
×
226
                return (esm as any)[gt];
×
227
            } else {
×
228
                return (matchingStyle as any)[gt];
×
229
            }
×
230
        } catch (e) {
×
231
            console.error(e);
×
232
            return null;
×
233
        }
×
234
    }
×
235
}
×
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

© 2026 Coveralls, Inc