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

terrestris / react-geo / 18274503963

06 Oct 2025 08:18AM UTC coverage: 63.354%. Remained the same
18274503963

push

github

web-flow
Merge pull request #4396 from terrestris/dependabot/npm_and_yarn/commitlint/cli-20.1.0

build(deps-dev): bump @commitlint/cli from 19.8.1 to 20.1.0

597 of 1040 branches covered (57.4%)

Branch coverage included in aggregate %.

1137 of 1697 relevant lines covered (67.0%)

11.77 hits per line

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

58.06
/src/BackgroundLayerPreview/BackgroundLayerPreview.tsx
1
import './BackgroundLayerPreview.less';
2

3
import React, {
4
  useEffect,
5
  useMemo,
6
  useState
7
} from 'react';
8

9
import { Spin } from 'antd';
10

11
import { Coordinate } from 'ol/coordinate';
12
import OlLayerBase from 'ol/layer/Base';
13
import OlLayerGroup from 'ol/layer/Group';
14
import OlLayerImage from 'ol/layer/Image';
15
import OlLayer from 'ol/layer/Layer';
16
import OlLayerTile from 'ol/layer/Tile';
17
import OlMap from 'ol/Map';
18
import { getUid } from 'ol/util';
19
import OlView from 'ol/View';
20

21
import { MapUtil } from '@terrestris/ol-util';
22

23
import useMap from '@terrestris/react-util/dist/Hooks/useMap/useMap';
24

25
import MapComponent from '../Map/MapComponent/MapComponent';
26

27
export interface BackgroundLayerPreviewProps {
28
  width?: number;
29
  height?: number;
30
  layer: OlLayer;
31
  activeLayer?: OlLayer;
32
  onClick: (l: OlLayer) => void;
33
  zoom?: number;
34
  center?: Coordinate;
35
  backgroundLayerFilter: (l: OlLayerBase) => boolean;
36
  titleRenderer?: (layer: OlLayer) => React.ReactNode;
37
}
38

39
export const BackgroundLayerPreview: React.FC<BackgroundLayerPreviewProps> = ({
2✔
40
  layer,
41
  activeLayer,
42
  width = 128,
11✔
43
  height = 128,
11✔
44
  onClick,
45
  zoom,
46
  center,
47
  backgroundLayerFilter,
48
  titleRenderer
49
}) => {
50

51
  const [loading, setLoading] = useState(false);
12✔
52

53
  const mainMap = useMap();
12✔
54

55
  const previewLayer = useMemo(() => {
12✔
56
    if (layer instanceof OlLayerTile) {
12!
57
      return new OlLayerTile({
12✔
58
        source: layer.getSource()
59
      });
60
    } else if (layer instanceof OlLayerImage) {
×
61
      return new OlLayerImage({
×
62
        source: layer.getSource()
63
      });
64
    }
65
    return undefined;
×
66
  }, [layer]);
67

68
  const previewMap = useMemo(() => {
12✔
69
    return new OlMap({
12✔
70
      view: new OlView({
71
        projection: mainMap?.getView().getProjection(),
72
        resolutions: mainMap?.getView().getResolutions(),
73
        center: center,
74
        zoom: zoom
75
      }),
76
      controls: [],
77
      interactions: [],
78
      layers: previewLayer && [previewLayer]
24✔
79
    });
80
  }, [center, mainMap, previewLayer, zoom]);
81

82
  useEffect(() => {
12✔
83
    const setTrue = () => setLoading(true);
12✔
84
    const setFalse = () => setLoading(false);
12✔
85
    previewMap.on('loadstart', setTrue);
12✔
86
    previewMap.on('loadend', setFalse);
12✔
87

88
    return () => {
12✔
89
      previewMap.un('loadstart', setTrue);
12✔
90
      previewMap.un('loadend', setFalse);
12✔
91
    };
92
  }, [previewMap]);
93

94
  useEffect(() => {
12✔
95
    if (zoom) {
12!
96
      previewMap.getView().setZoom(zoom);
×
97
    }
98
    if (center) {
12!
99
      previewMap.getView().setCenter(center);
×
100
    }
101
  }, [zoom, center, previewMap]);
102

103
  const getBgLayersFromMap = (): OlLayer[] => {
12✔
104
    const collectBgLayers = (layerGroup: OlLayerGroup | undefined): OlLayer[] => {
1✔
105
      if (!layerGroup) {
×
106
        return [];
×
107
      }
108

109
      const layers: OlLayer[] = [];
×
110
      const layerArray = layerGroup.getLayers().getArray();
×
111

112
      for (const l of layerArray) {
×
113
        if (backgroundLayerFilter(l)) {
×
114
          layers.push(l as OlLayer);
×
115
        }
116

117
        if (l instanceof OlLayerGroup) {
×
118
          layers.push(...collectBgLayers(l));
×
119
        }
120
      }
121

122
      return layers;
×
123
    };
124

125
    const mainLayerGroup = mainMap?.getLayerGroup();
1✔
126
    return mainLayerGroup ? collectBgLayers(mainLayerGroup) : [];
1!
127
  };
128

129
  const updateBgLayerVisibility = (evt: React.MouseEvent<HTMLDivElement>) => {
12✔
130
    const target = evt?.currentTarget;
2✔
131
    const layerId = target?.dataset?.uid;
2✔
132

133
    if (!layerId || !mainMap) {
2!
134
      return;
2✔
135
    }
136

137
    const newBgLayer = MapUtil.getLayerByOlUid(mainMap, layerId);
×
138

139
    if (!newBgLayer) {
×
140
      return;
×
141
    }
142

143
    getBgLayersFromMap().forEach(l => l.setVisible(false));
×
144
    newBgLayer.setVisible(true);
×
145

146
    if (evt.type === 'click') {
×
147
      onClick(newBgLayer as OlLayer);
×
148
    }
149
  };
150

151
  const restoreBgLayerVisibility = () => {
12✔
152
    getBgLayersFromMap().forEach(l => l.setVisible(false));
1✔
153
    activeLayer?.setVisible(true);
1✔
154
  };
155

156
  let isActive = false;
12✔
157
  const uid = getUid(layer);
12✔
158
  if (activeLayer) {
12✔
159
    const activeUid = getUid(activeLayer);
7✔
160
    isActive = uid === activeUid;
7✔
161
  }
162

163
  return (
12✔
164
    <div
165
      className={`layer-preview${isActive ? ' selected' : ''}`}
12✔
166
      key={uid}
167
      data-uid={uid}
168
      onMouseOver={updateBgLayerVisibility}
169
      onMouseLeave={restoreBgLayerVisibility}
170
      onClick={updateBgLayerVisibility}
171
    >
172
      <Spin
173
        spinning={loading}
174
      >
175
        <MapComponent
176
          mapDivId={`previewmap-${uid}`}
177
          style={{
178
            height,
179
            width
180
          }}
181
          map={previewMap}
182
        />
183
        <span
184
          className="layer-title"
185
        >
186
          {titleRenderer ? titleRenderer(layer) : layer.get('name')}
12✔
187
        </span>
188
      </Spin>
189
    </div>
190
  );
191
};
192

193
export default BackgroundLayerPreview;
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