src/components/Map/Map.jsx   A
last analyzed

Complexity

Total Complexity 16
Complexity/F 2.29

Size

Lines of Code 205
Function Count 7

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 148
dl 0
loc 205
rs 10
c 0
b 0
f 0
wmc 16
mnd 9
bc 9
fnc 7
bpm 1.2857
cpm 2.2857
noi 0

5 Functions

Rating   Name   Duplication   Size   Complexity  
A Map.jsx ➔ AddSinglePoint 0 12 3
A Map.jsx ➔ MarkersDisplay 0 36 2
A Map.jsx ➔ AreasDisplay 0 28 3
A Map.jsx ➔ Search 0 9 3
A Map.jsx ➔ AddPoints 0 11 2
1
import React from "react";
2
import {
3
  MapContainer,
4
  TileLayer,
5
  Marker,
6
  Popup,
7
  useMap,
8
  GeoJSON,
9
  Polyline,
10
  useMapEvents,
11
} from "react-leaflet";
12
import utils from "../../utils/utils";
13
import * as L from "leaflet";
14
import ScooterIcon from "../../assets/icons/ScooterMarker.svg";
15
import "../../Map.css";
16
import scooterutils from "../../utils/utils";
17
18
const Map = ({
19
  center,
20
  zoom,
21
  features,
22
  scooters,
23
  cities,
24
  zoneId,
25
  add,
26
  noPopup,
27
  zoneMarkers,
28
  setZoneMarkers,
29
  reverse,
30
  setReverse,
31
  setIsLive,
32
  singleMode,
33
  setSingleMarker,
34
  singleMarker,
35
  setLatLng,
36
}) => {
37
  const LeafIcon = L.Icon.extend({
38
    options: {},
39
  });
40
41
  const scooterIcon = new LeafIcon({
42
    iconUrl: ScooterIcon,
43
    iconSize: [68, 95],
44
    iconAnchor: [34, 95],
45
    popupAnchor: [-3, -76],
46
  });
47
48
  const areaStyle = (type) => {
49
    switch (type) {
50
      case "parkingZone":
51
        return {
52
          fillColor: "#96FF71",
53
          fillOpacity: 0.2,
54
        };
55
      case "noParkingZone":
56
        return {
57
          fillColor: "#FF6060",
58
          fillOpacity: 0.4,
59
          weight: 1,
60
        };
61
      case "bonusParkingZone":
62
        return {
63
          fillColor: "#C64EFF",
64
          fillOpacity: 0.4,
65
          weight: 1,
66
        };
67
      case "chargingZone":
68
        return {
69
          fillColor: "#638FFF",
70
          fillOpacity: 0.6,
71
          weight: 1,
72
        };
73
    }
74
  };
75
76
  function Search() {
77
    const map = useMap();
78
    if (features) {
79
      map.panTo(features, zoom);
80
      //map.setZoom(10);
81
    }
82
83
    return null;
84
  }
85
86
  function MarkersDisplay() {
87
    if (scooters) {
88
      return scooters.map((item, index) => {
89
        return (
90
          <Marker
91
            key={index}
92
            position={[item.coordinates.latitude, item.coordinates.longitude]}
93
            icon={scooterIcon}
94
            eventHandlers={{
95
              click: (e) => {
96
                setIsLive(false);
97
              },
98
            }}
99
          >
100
            <Popup>
101
              <h1 className="text-xl">{item.name}</h1>
102
              <div
103
                className="text-md text-white w-fit py-1 px-2 rounded-xl my-1"
104
                style={{ backgroundColor: scooterutils.sateColor(item.status) }}
105
              >
106
                {item.status}
107
              </div>
108
              <div className="px-1">
109
                <span className="text-md">
110
                  Owner: {item.owner}
111
                  <br />
112
                  Battery: {item.battery.toFixed(0)}%
113
                  <br />
114
                  Lat: {item.coordinates.latitude}
115
                  <br />
116
                  Lon: {item.coordinates.longitude}
117
                </span>
118
              </div>
119
            </Popup>
120
          </Marker>
121
        );
122
      });
123
    }
124
  }
125
126
  function AreasDisplay() {
127
    if (cities) {
128
      return cities.map((item) => {
129
        return item.zones.map((data, index) => {
130
          let geoObject = {
131
            type: "Feature",
132
            properties: { zonetype: data.zoneType },
133
            geometry: {
134
              type: "Polygon",
135
              coordinates: [data.coordinates],
136
            },
137
          };
138
          return (
139
            <GeoJSON
140
              key={index}
141
              data={geoObject}
142
              style={areaStyle(data.zoneType)}
143
            >
144
              {noPopup ? null : (
145
                <Popup>
146
                  <h1 className="text-xl">{item.name}</h1>
147
                  <h1 className="text-lf">
148
                    {utils.zoneNameTranslate(data.zoneType)}: {index}
149
                  </h1>
150
                </Popup>
151
              )}
152
            </GeoJSON>
153
          );
154
        });
155
      });
156
    }
157
  }
158
159
  function AddPoints() {
160
    useMapEvents({
161
      click(e) {
162
        setZoneMarkers([...zoneMarkers, [e.latlng.lng, e.latlng.lat]]);
163
        setReverse([...reverse, [e.latlng.lat, e.latlng.lng]]);
164
      },
165
    });
166
167
    return zoneMarkers.map((item, index) => {
168
      return <Marker key={index} position={[item[1], item[0]]} />;
169
    });
170
  }
171
172
  function AddSinglePoint() {
173
    useMapEvents({
174
      click(e) {
175
        setSingleMarker({ lon: e.latlng.lng, lat: e.latlng.lat });
176
        if (setLatLng) {
177
          setLatLng(e.latlng.lat, e.latlng.lng);
178
        }
179
      },
180
    });
181
182
    return <Marker position={[singleMarker.lat, singleMarker.lon]} />;
183
  }
184
185
  return (
186
    <MapContainer center={center} zoom={zoom} scrollWheelZoom={false}>
187
      <TileLayer
188
        url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
189
        attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
190
      />
191
      <Search />
192
      <MarkersDisplay />
193
      {add ? (
194
        <Polyline pathOptions={{ color: "blue" }} positions={reverse} />
195
      ) : null}
196
      <AreasDisplay />
197
      {add ? <AddPoints /> : null}
198
199
      {singleMode ? <AddSinglePoint /> : null}
200
    </MapContainer>
201
  );
202
};
203
204
export default Map;
205