조민지

feat: 구글 지도 API 연동

Showing 35 changed files with 213 additions and 52 deletions
1 import React, {useEffect} from "react"; 1 import React, {useEffect} from "react";
2 import Dimensions from "react-dimensions"; 2 import Dimensions from "react-dimensions";
3 +import res from './res';
3 4
4 -let map, infoWindow; 5 +let map;
6 +let markers = [];
7 +let infoWindow;
5 8
6 -const GoogleMap = (props) => { 9 +const getGroupUrlStringByGroup = group => {
7 - useEffect(() => { 10 + if (group === "renting") {
8 - console.log('mount'); 11 + // 사용중
9 - const { google } = window; 12 + return "_inuse";
13 + } else if (group === "ready") {
14 + // 대기중
15 + return "";
16 + } else if (group === "target") {
17 + // 수거대상
18 + return "_pickup";
19 + } else if (group === "collect") {
20 + // 수거
21 + return "_deactive";
22 + }
23 +};
24 +
25 +const getBatteryUrlStringByBattery = battery => {
26 + if (battery >= 0 && battery < 25) {
27 + return "0-25";
28 + } else if (battery >= 25 && battery < 50) {
29 + return "25-50";
30 + } else if (battery >= 50 && battery < 75) {
31 + return "50-75";
32 + }
33 + return "75-100";
34 +};
35 +
36 +class GoogleMap extends React.Component {
37 + constructor(props) {
38 + super(props);
39 + this.state = {
40 + kickboards: []
41 + };
42 + }
43 +
44 + componentDidMount() {
45 + // fetch('http://1.201.143.67:5901/kickboard/all')
46 + // .then(r => r.json())
47 + // .then(d => {
48 + // if(!d.success || !d.data.length) return;
49 + //
50 + // console.log(d.data)
51 + // this.setState({
52 + // kickboards: d.data
53 + // })
54 + // })
55 + // .then(d => {
56 + // const { google } = window;
57 + //
58 + // infoWindow = new window.google.maps.InfoWindow({});
59 + //
60 + // map = new google.maps.Map(document.getElementById("map"), {
61 + // zoom: 11,
62 + // center: {lat: -34.397, lng: 150.644},
63 + // disableDefaultUI: true,
64 + // zoomControl: true
65 + // });
66 + //
67 + // google.maps.event.addListenerOnce(map, "idle", () => {
68 + // this.getCurrentLocation();
69 + // });
70 + // })
71 + // .catch(err => console.log(err));
72 +
73 + const response = JSON.parse(res);
74 + this.setState({
75 + kickboards: response.data
76 + });
10 77
78 + const { google } = window;
11 infoWindow = new window.google.maps.InfoWindow({}); 79 infoWindow = new window.google.maps.InfoWindow({});
12 80
13 map = new google.maps.Map(document.getElementById("map"), { 81 map = new google.maps.Map(document.getElementById("map"), {
...@@ -16,12 +84,100 @@ const GoogleMap = (props) => { ...@@ -16,12 +84,100 @@ const GoogleMap = (props) => {
16 disableDefaultUI: true, 84 disableDefaultUI: true,
17 zoomControl: true 85 zoomControl: true
18 }); 86 });
19 - }, []);
20 87
21 - return ( 88 + google.maps.event.addListenerOnce(map, "idle", () => {
22 - <div id="map" style={{height:props.containerWidth, backgroundColor:'pink'}}> 89 + this.getCurrentLocation();
23 - </div> 90 + });
24 - ) 91 + }
92 +
93 + getCurrentLocation() {
94 + if (navigator.geolocation) {
95 + map.setCenter(
96 + new window.google.maps.LatLng({
97 + lat: 37.2441088,
98 + lng: 127.05054720000001
99 + })
100 + );
101 + } else {
102 + map.setCenter(
103 + new window.google.maps.LatLng({
104 + lat: 37.2441088,
105 + lng: 127.05054720000001
106 + })
107 + );
108 + }
109 + }
110 +
111 + drawMarkers() {
112 + if (map == null) return;
113 + const selectedMarker = new window.google.maps.Marker({});
114 +
115 + markers = this.state.kickboards.map(item => {
116 + const marker = new window.google.maps.Marker({
117 + position: new window.google.maps.LatLng({
118 + lat: item.coordinates.lat,
119 + lng: item.coordinates.lon
120 + })
121 + });
122 +
123 + const markerContent = `
124 + <div>
125 + <div style="color:black"> 시리얼번호: ${item.serialNumber} </div>
126 + </div>
127 + `;
128 +
129 + marker.item = item;
130 +
131 + this.renderMarker(marker);
132 +
133 + window.google.maps.event.addListener(marker, "click", () => {
134 + infoWindow.close();
135 + infoWindow.setContent(markerContent);
136 + infoWindow.open(map, marker);
137 + });
138 +
139 + window.google.maps.event.addListener(marker, "mouseover", () => {
140 + this.highlightMarker(marker);
141 + });
142 +
143 + window.google.maps.event.addListener(marker, "mouseout", () => {
144 + this.renderMarker(marker);
145 + });
146 +
147 + marker.setMap(map);
148 + return marker;
149 + });
150 + }
151 +
152 + renderMarker(marker) {
153 + const { group, battery } = marker.item;
154 +
155 + const groupString = getGroupUrlStringByGroup(group);
156 + const batteryString = getBatteryUrlStringByBattery(battery);
157 +
158 + const iconUrl = require(`../../assets/marker/ic_map_pin_battery${batteryString}${groupString}.png`);
159 + marker.setIcon(iconUrl);
160 + }
161 +
162 +
163 + highlightMarker(marker) {
164 + const { group, battery } = marker.item;
165 +
166 + const groupString = getGroupUrlStringByGroup(group);
167 + const batteryString = getBatteryUrlStringByBattery(battery);
168 +
169 + const iconUrl = require(`../../assets/marker/ic_map_pin_battery${batteryString}${groupString}_selected.png`);
170 + marker.setIcon(iconUrl);
171 + }
172 +
173 + render() {
174 + this.drawMarkers();
175 +
176 + return (
177 + <div id="map" style={{height:this.props.containerWidth, backgroundColor:'pink'}}>
178 + </div>
179 + )
180 + }
25 }; 181 };
26 182
27 export default Dimensions()(GoogleMap) // Enhanced component 183 export default Dimensions()(GoogleMap) // Enhanced component
...\ No newline at end of file ...\ No newline at end of file
......
1 +const res = `
2 +{"success":true,"data":[{"serialNumber":"000000","battery":0,"dailyDrivenDistance":0,"dailyDrivenTime":0,"coordinates":{"lon":126.885654,"lat":37.480045},"modelName":"MA01","isGoodReception":false,"isGoodPosture":false,"connected":false,"createdAt":"2020-02-13T09:59:22.303Z","group":"target","state":"알 수 없는 오류"},{"serialNumber":"000001","battery":0,"dailyDrivenDistance":0,"dailyDrivenTime":0,"coordinates":{"lon":127.078668,"lat":37.244634},"modelName":"MA01","isGoodReception":false,"isGoodPosture":false,"connected":false,"createdAt":"2020-02-13T09:59:24.316Z","group":"target","state":"알 수 없는 오류"},{"serialNumber":"000002","battery":0,"dailyDrivenDistance":0,"dailyDrivenTime":52257,"coordinates":{"lon":126.886552,"lat":37.479997},"modelName":"MA01","isGoodReception":false,"isGoodPosture":true,"connected":true,"createdAt":"2020-04-16T08:40:51.817Z","group":"ready","state":"대기 중"},{"serialNumber":"000003","battery":78,"dailyDrivenDistance":0,"dailyDrivenTime":0,"coordinates":{"lon":127.05006,"lat":37.545254},"modelName":"MA01","isGoodReception":false,"isGoodPosture":false,"connected":false,"createdAt":"2020-02-04T01:57:45.032Z","group":"collect","state":"수거됨"},{"serialNumber":"000004","battery":0,"dailyDrivenDistance":0,"dailyDrivenTime":0,"coordinates":{"lon":127.078668,"lat":37.244634},"modelName":"MA01","isGoodReception":false,"isGoodPosture":false,"connected":false,"createdAt":"2020-02-13T09:59:26.569Z","group":"target","state":"알 수 없는 오류"},{"serialNumber":"000005","battery":0,"dailyDrivenDistance":0,"dailyDrivenTime":0,"coordinates":{"lon":127.050652,"lat":37.545297},"modelName":"MA01","isGoodReception":false,"isGoodPosture":false,"connected":false,"createdAt":"2020-02-13T15:02:15.601Z","group":"collect","state":"수거됨"},{"serialNumber":"000006","battery":94,"dailyDrivenDistance":0,"dailyDrivenTime":439119,"coordinates":{"lon":126.885743,"lat":37.479925},"modelName":"MA01","isGoodReception":false,"isGoodPosture":false,"connected":true,"createdAt":"2020-02-13T15:02:15.601Z","group":"ready","state":"서비스 종료"},{"serialNumber":"000007","battery":0,"dailyDrivenDistance":0,"dailyDrivenTime":0,"coordinates":{"lon":126.87614,"lat":37.482151},"modelName":"MA01","isGoodReception":false,"isGoodPosture":false,"connected":false,"createdAt":"2020-02-13T15:02:15.601Z","group":"target","state":"알 수 없는 오류"},{"serialNumber":"000008","battery":40,"dailyDrivenDistance":0,"dailyDrivenTime":29,"coordinates":{"lon":127.050652,"lat":37.545297},"modelName":"MA01","isGoodReception":false,"isGoodPosture":false,"connected":true,"createdAt":"2020-02-13T15:02:15.601Z","group":"collect","state":"수거됨"}]}`
3 +
4 +
5 +export default res;
...\ No newline at end of file ...\ No newline at end of file
...@@ -8,20 +8,20 @@ import Notifications from "views/Notifications.jsx"; ...@@ -8,20 +8,20 @@ import Notifications from "views/Notifications.jsx";
8 import Kickboard from "views/Kickboard" 8 import Kickboard from "views/Kickboard"
9 9
10 const dashboardRoutes = [ 10 const dashboardRoutes = [
11 - { 11 + // {
12 - path: "/dashboard", 12 + // path: "/dashboard",
13 - name: "Dashboard", 13 + // name: "Dashboard",
14 - icon: "pe-7s-graph", 14 + // icon: "pe-7s-graph",
15 - component: Dashboard, 15 + // component: Dashboard,
16 - layout: "/admin" 16 + // layout: "/admin"
17 - }, 17 + // },
18 - { 18 + // {
19 - path: "/user", 19 + // path: "/user",
20 - name: "User Profile", 20 + // name: "User Profile",
21 - icon: "pe-7s-user", 21 + // icon: "pe-7s-user",
22 - component: UserProfile, 22 + // component: UserProfile,
23 - layout: "/admin" 23 + // layout: "/admin"
24 - }, 24 + // },
25 { 25 {
26 path: "/table", 26 path: "/table",
27 name: "사용자 정보", 27 name: "사용자 정보",
...@@ -29,34 +29,34 @@ const dashboardRoutes = [ ...@@ -29,34 +29,34 @@ const dashboardRoutes = [
29 component: UserHistory, 29 component: UserHistory,
30 layout: "/admin" 30 layout: "/admin"
31 }, 31 },
32 - { 32 + // {
33 - path: "/typography", 33 + // path: "/typography",
34 - name: "Typography", 34 + // name: "Typography",
35 - icon: "pe-7s-news-paper", 35 + // icon: "pe-7s-news-paper",
36 - component: Typography, 36 + // component: Typography,
37 - layout: "/admin" 37 + // layout: "/admin"
38 - }, 38 + // },
39 - { 39 + // {
40 - path: "/icons", 40 + // path: "/icons",
41 - name: "Icons", 41 + // name: "Icons",
42 - icon: "pe-7s-science", 42 + // icon: "pe-7s-science",
43 - component: Icons, 43 + // component: Icons,
44 - layout: "/admin" 44 + // layout: "/admin"
45 - }, 45 + // },
46 - { 46 + // {
47 - path: "/maps", 47 + // path: "/maps",
48 - name: "Maps", 48 + // name: "Maps",
49 - icon: "pe-7s-map-marker", 49 + // icon: "pe-7s-map-marker",
50 - component: Maps, 50 + // component: Maps,
51 - layout: "/admin" 51 + // layout: "/admin"
52 - }, 52 + // },
53 - { 53 + // {
54 - path: "/notifications", 54 + // path: "/notifications",
55 - name: "Notifications", 55 + // name: "Notifications",
56 - icon: "pe-7s-bell", 56 + // icon: "pe-7s-bell",
57 - component: Notifications, 57 + // component: Notifications,
58 - layout: "/admin" 58 + // layout: "/admin"
59 - }, 59 + // },
60 { 60 {
61 path: "/kickboard", 61 path: "/kickboard",
62 name: "킥보드 정보", 62 name: "킥보드 정보",
......