Showing
19 changed files
with
651 additions
and
0 deletions
.gitignore
0 → 100644
소스코드/.gitignore
0 → 100644
소스코드/PME/.expo-shared/assets.json
0 → 100644
소스코드/PME/.gitignore
0 → 100644
소스코드/PME/App.js
0 → 100644
1 | +import { Component } from 'react'; | ||
2 | +import { StyleSheet, Text, View, AppRegistry } from 'react-native'; | ||
3 | +import { createAppContainer } from 'react-navigation'; | ||
4 | +import {createStackNavigator } from 'react-navigation-stack' | ||
5 | +import MainScreen from './components/Mainscreen'; | ||
6 | +import React from 'react' | ||
7 | + | ||
8 | +const AppStackNavigator = createStackNavigator({ | ||
9 | + Main:{ | ||
10 | + screen: MainScreen | ||
11 | + } | ||
12 | +}); | ||
13 | + | ||
14 | +export default createAppContainer(AppStackNavigator); | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
소스코드/PME/app.json
0 → 100644
1 | +{ | ||
2 | + "expo": { | ||
3 | + "name": "HelloWorld", | ||
4 | + "slug": "PME", | ||
5 | + "platforms": [ | ||
6 | + "ios", | ||
7 | + "android", | ||
8 | + "web" | ||
9 | + ], | ||
10 | + "version": "1.0.0", | ||
11 | + "orientation": "portrait", | ||
12 | + "icon": "./assets/icon.png", | ||
13 | + "splash": { | ||
14 | + "image": "./assets/splash.png", | ||
15 | + "resizeMode": "contain", | ||
16 | + "backgroundColor": "#ffffff" | ||
17 | + }, | ||
18 | + "updates": { | ||
19 | + "fallbackToCacheTimeout": 0 | ||
20 | + }, | ||
21 | + "assetBundlePatterns": [ | ||
22 | + "**/*" | ||
23 | + ], | ||
24 | + "ios": { | ||
25 | + "supportsTablet": true | ||
26 | + }, | ||
27 | + "android" : { | ||
28 | + "package" : "com.A.BLE", | ||
29 | + "config": { | ||
30 | + "googleMaps": {"apiKey":"AIzaSyCe_1-Mml2OyihnmS2oiPUj73X-Aj1j_2k"} | ||
31 | + } | ||
32 | + } | ||
33 | + } | ||
34 | +} |
소스코드/PME/assets/icon.png
0 → 100644

642 Bytes
소스코드/PME/assets/splash.png
0 → 100644

9.09 KB
소스코드/PME/babel.config.js
0 → 100644
소스코드/PME/components/ClusteredMapView.js
0 → 100644
1 | +import React, { memo, useState, useEffect, useMemo, createRef } from "react"; | ||
2 | +import { Dimensions, LayoutAnimation, Platform } from "react-native"; | ||
3 | +import MapView, { Marker, Polyline } from "react-native-maps"; | ||
4 | +import SuperCluster from "supercluster"; | ||
5 | +import ClusterMarker from "./ClusteredMarker"; | ||
6 | +import { | ||
7 | + isMarker, | ||
8 | + markerToGeoJSONFeature, | ||
9 | + calculateBBox, | ||
10 | + returnMapZoom, | ||
11 | + generateSpiral | ||
12 | +} from "./helpers"; | ||
13 | + | ||
14 | +const ClusteredMapView = ({ | ||
15 | + radius, | ||
16 | + maxZoom, | ||
17 | + minZoom, | ||
18 | + extent, | ||
19 | + nodeSize, | ||
20 | + children, | ||
21 | + onClusterPress, | ||
22 | + onRegionChangeComplete, | ||
23 | + preserveClusterPressBehavior, | ||
24 | + clusteringEnabled, | ||
25 | + clusterColor, | ||
26 | + clusterTextColor, | ||
27 | + spiderLineColor, | ||
28 | + layoutAnimationConf, | ||
29 | + animationEnabled, | ||
30 | + renderCluster, | ||
31 | + ...restProps | ||
32 | +}) => { | ||
33 | + const [markers, updateMarkers] = useState([]); | ||
34 | + const [spiderMarkers, updateSpiderMarker] = useState([]); | ||
35 | + const [otherChildren, updateChildren] = useState([]); | ||
36 | + const [superCluster, setSuperCluster] = useState(null); | ||
37 | + const [currentRegion, updateRegion] = useState( | ||
38 | + restProps.region || restProps.initialRegion | ||
39 | + ); | ||
40 | + | ||
41 | + const [isSpiderfier, updateSpiderfier] = useState(false); | ||
42 | + const [spiderfierMarker, updateSpiderfierMarker] = useState(null); | ||
43 | + const [clusterChildren, updateClusterChildren] = useState(null); | ||
44 | + const mapRef = createRef(); | ||
45 | + | ||
46 | + const propsChildren = useMemo(() => React.Children.toArray(children), [ | ||
47 | + children | ||
48 | + ]); | ||
49 | + | ||
50 | + useEffect(() => { | ||
51 | + const rawData = []; | ||
52 | + const otherChildren = []; | ||
53 | + | ||
54 | + if (!clusteringEnabled) { | ||
55 | + updateChildren(propsChildren); | ||
56 | + return; | ||
57 | + } | ||
58 | + | ||
59 | + React.Children.forEach(children, (child, i) => { | ||
60 | + if (isMarker(child)) { | ||
61 | + rawData.push(markerToGeoJSONFeature(child, i)); | ||
62 | + } else { | ||
63 | + otherChildren.push(child); | ||
64 | + } | ||
65 | + }); | ||
66 | + | ||
67 | + const superCluster = new SuperCluster({ | ||
68 | + radius, | ||
69 | + maxZoom, | ||
70 | + minZoom, | ||
71 | + extent, | ||
72 | + nodeSize | ||
73 | + }); | ||
74 | + | ||
75 | + superCluster.load(rawData); | ||
76 | + | ||
77 | + const bBox = calculateBBox(currentRegion); | ||
78 | + const zoom = returnMapZoom(currentRegion, bBox, minZoom); | ||
79 | + const markers = superCluster.getClusters(bBox, zoom); | ||
80 | + | ||
81 | + updateMarkers(markers); | ||
82 | + updateChildren(otherChildren); | ||
83 | + setSuperCluster(superCluster); | ||
84 | + }, [children, restProps.region, restProps.initialRegion]); | ||
85 | + | ||
86 | + useEffect(() => { | ||
87 | + if (isSpiderfier && markers.length > 0) { | ||
88 | + let positions = generateSpiral( | ||
89 | + markers[0].properties.point_count, | ||
90 | + markers[0].geometry.coordinates, | ||
91 | + clusterChildren | ||
92 | + ); | ||
93 | + updateSpiderMarker(positions); | ||
94 | + updateSpiderfierMarker({ | ||
95 | + latitude: markers[0].geometry.coordinates[1], | ||
96 | + longitude: markers[0].geometry.coordinates[0] | ||
97 | + }); | ||
98 | + } else { | ||
99 | + updateSpiderMarker([]); | ||
100 | + } | ||
101 | + }, [isSpiderfier]); | ||
102 | + | ||
103 | + const _onRegionChangeComplete = region => { | ||
104 | + if (superCluster) { | ||
105 | + const bBox = calculateBBox(region); | ||
106 | + const zoom = returnMapZoom(region, bBox, minZoom); | ||
107 | + const markers = superCluster.getClusters(bBox, zoom); | ||
108 | + | ||
109 | + if (animationEnabled && Platform.OS === "ios") { | ||
110 | + LayoutAnimation.configureNext(layoutAnimationConf); | ||
111 | + } | ||
112 | + | ||
113 | + if (zoom >= 17 && markers.length === 1 && clusterChildren) { | ||
114 | + updateSpiderfier(true); | ||
115 | + } else { | ||
116 | + updateSpiderfier(false); | ||
117 | + } | ||
118 | + | ||
119 | + updateMarkers(markers); | ||
120 | + onRegionChangeComplete(region, markers); | ||
121 | + updateRegion(region); | ||
122 | + } | ||
123 | + }; | ||
124 | + | ||
125 | + const _onClusterPress = cluster => () => { | ||
126 | + const children = superCluster.getLeaves(cluster.id); | ||
127 | + updateClusterChildren(children); | ||
128 | + | ||
129 | + if (preserveClusterPressBehavior) { | ||
130 | + onClusterPress(cluster, children); | ||
131 | + return; | ||
132 | + } | ||
133 | + | ||
134 | + const coordinates = children.map(({ geometry }) => ({ | ||
135 | + latitude: geometry.coordinates[1], | ||
136 | + longitude: geometry.coordinates[0] | ||
137 | + })); | ||
138 | + | ||
139 | + mapRef.current.fitToCoordinates(coordinates, { | ||
140 | + edgePadding: restProps.edgePadding | ||
141 | + }); | ||
142 | + | ||
143 | + onClusterPress(cluster, children); | ||
144 | + }; | ||
145 | + | ||
146 | + return ( | ||
147 | + <MapView | ||
148 | + {...restProps} | ||
149 | + ref={map => { | ||
150 | + restProps.mapRef(map); | ||
151 | + mapRef.current = map; | ||
152 | + }} | ||
153 | + onRegionChangeComplete={_onRegionChangeComplete} | ||
154 | + > | ||
155 | + {markers.map(marker => | ||
156 | + marker.properties.point_count === 0 ? ( | ||
157 | + propsChildren[marker.properties.index] | ||
158 | + ) : !isSpiderfier ? ( | ||
159 | + renderCluster ? ( | ||
160 | + renderCluster({ | ||
161 | + onPress: _onClusterPress(marker), | ||
162 | + clusterColor, | ||
163 | + clusterTextColor, | ||
164 | + ...marker | ||
165 | + }) | ||
166 | + ) : ( | ||
167 | + <ClusterMarker | ||
168 | + key={`cluster-${marker.id}`} | ||
169 | + {...marker} | ||
170 | + onPress={_onClusterPress(marker)} | ||
171 | + clusterColor={clusterColor} | ||
172 | + clusterTextColor={clusterTextColor} | ||
173 | + /> | ||
174 | + ) | ||
175 | + ) : null | ||
176 | + )} | ||
177 | + {otherChildren} | ||
178 | + {spiderMarkers.map(marker => ( | ||
179 | + <Marker | ||
180 | + key={marker.latitude} | ||
181 | + coordinate={marker} | ||
182 | + image={marker.image} | ||
183 | + onPress={marker.onPress} | ||
184 | + ></Marker> | ||
185 | + ))} | ||
186 | + {spiderMarkers.map((marker, index) => { | ||
187 | + { | ||
188 | + return ( | ||
189 | + spiderfierMarker && ( | ||
190 | + <Polyline | ||
191 | + key={index} | ||
192 | + coordinates={[spiderfierMarker, marker, spiderfierMarker]} | ||
193 | + strokeColor={spiderLineColor} | ||
194 | + strokeWidth={1} | ||
195 | + /> | ||
196 | + ) | ||
197 | + ); | ||
198 | + } | ||
199 | + })} | ||
200 | + </MapView> | ||
201 | + ); | ||
202 | +}; | ||
203 | + | ||
204 | +ClusteredMapView.defaultProps = { | ||
205 | + clusteringEnabled: true, | ||
206 | + animationEnabled: true, | ||
207 | + preserveClusterPressBehavior: false, | ||
208 | + layoutAnimationConf: LayoutAnimation.Presets.spring, | ||
209 | + // SuperCluster parameters | ||
210 | + radius: Dimensions.get("window").width * 0.06, | ||
211 | + maxZoom: 20, | ||
212 | + minZoom: 1, | ||
213 | + extent: 512, | ||
214 | + nodeSize: 64, | ||
215 | + // Map parameters | ||
216 | + edgePadding: { top: 50, left: 50, right: 50, bottom: 50 }, | ||
217 | + // Cluster styles | ||
218 | + clusterColor: "#00B386", | ||
219 | + clusterTextColor: "#FFFFFF", | ||
220 | + spiderLineColor: "#FF0000", | ||
221 | + // Callbacks | ||
222 | + onRegionChangeComplete: () => {}, | ||
223 | + onClusterPress: () => {}, | ||
224 | + mapRef: () => {} | ||
225 | +}; | ||
226 | + | ||
227 | +export default memo(ClusteredMapView); |
소스코드/PME/components/ClusteredMarker.js
0 → 100644
1 | +import React, { memo } from "react"; | ||
2 | +import { Text, View, StyleSheet, TouchableOpacity } from "react-native"; | ||
3 | +import { Marker } from "react-native-maps"; | ||
4 | +import { returnMarkerStyle } from "./helpers"; | ||
5 | + | ||
6 | +const ClusteredMarker = ({ | ||
7 | + geometry, | ||
8 | + properties, | ||
9 | + onPress, | ||
10 | + clusterColor, | ||
11 | + clusterTextColor | ||
12 | +}) => { | ||
13 | + const points = properties.point_count; | ||
14 | + const { width, height, fontSize, size } = returnMarkerStyle(points); | ||
15 | + | ||
16 | + return ( | ||
17 | + <Marker | ||
18 | + coordinate={{ | ||
19 | + longitude: geometry.coordinates[0], | ||
20 | + latitude: geometry.coordinates[1] | ||
21 | + }} | ||
22 | + style={{ zIndex: points + 1 }} | ||
23 | + onPress={onPress} | ||
24 | + > | ||
25 | + <TouchableOpacity | ||
26 | + activeOpacity={0.5} | ||
27 | + style={[styles.container, { width, height }]} | ||
28 | + > | ||
29 | + <View | ||
30 | + style={[ | ||
31 | + styles.wrapper, | ||
32 | + { | ||
33 | + backgroundColor: clusterColor, | ||
34 | + width, | ||
35 | + height, | ||
36 | + borderRadius: width / 2 | ||
37 | + } | ||
38 | + ]} | ||
39 | + /> | ||
40 | + <View | ||
41 | + style={[ | ||
42 | + styles.cluster, | ||
43 | + { | ||
44 | + backgroundColor: clusterColor, | ||
45 | + width: size, | ||
46 | + height: size, | ||
47 | + borderRadius: size / 2 | ||
48 | + } | ||
49 | + ]} | ||
50 | + > | ||
51 | + <Text style={[styles.text, { color: clusterTextColor, fontSize }]}> | ||
52 | + {points} | ||
53 | + </Text> | ||
54 | + </View> | ||
55 | + </TouchableOpacity> | ||
56 | + </Marker> | ||
57 | + ); | ||
58 | +}; | ||
59 | + | ||
60 | +const styles = StyleSheet.create({ | ||
61 | + container: { | ||
62 | + display: "flex", | ||
63 | + justifyContent: "center", | ||
64 | + alignItems: "center" | ||
65 | + }, | ||
66 | + wrapper: { | ||
67 | + position: "absolute", | ||
68 | + opacity: 0.5, | ||
69 | + zIndex: 0 | ||
70 | + }, | ||
71 | + cluster: { | ||
72 | + display: "flex", | ||
73 | + justifyContent: "center", | ||
74 | + alignItems: "center", | ||
75 | + zIndex: 1 | ||
76 | + }, | ||
77 | + text: { | ||
78 | + fontWeight: "bold" | ||
79 | + } | ||
80 | +}); | ||
81 | + | ||
82 | +export default memo(ClusteredMarker); |
소스코드/PME/components/Mainscreen.js
0 → 100644
1 | +import { Component } from 'react'; | ||
2 | +import { StyleSheet, Text, View } from 'react-native'; | ||
3 | +import { Icon } from 'native-base'; // 추가된 코드 | ||
4 | +import React from 'react' | ||
5 | +import {Marker} from 'react-native-maps' | ||
6 | +import Constants from 'expo-constants'; | ||
7 | +import * as Location from 'expo-location'; | ||
8 | +import MapView from "./ClusteredMapView"; | ||
9 | + | ||
10 | + | ||
11 | +export default class MainScreen extends Component { | ||
12 | + | ||
13 | + // navigationOptions 코드 추가 | ||
14 | + static navigationOptions = { | ||
15 | + headerLeft: <Icon name='ios-camera' style={{ paddingLeft:10 }}/>, | ||
16 | + title: 'PME Service', | ||
17 | + headerRight: <Icon name='ios-send' style={{ paddingRight:10 }}/>, | ||
18 | + } | ||
19 | + constructor(props) { | ||
20 | + super(props) | ||
21 | + this.state= { | ||
22 | + location:null, | ||
23 | + errorMsg:null | ||
24 | + } | ||
25 | + } | ||
26 | + componentDidMount() { | ||
27 | + (async () => { | ||
28 | + let { status } = await Location.requestPermissionsAsync(); | ||
29 | + if (status !== 'granted') { | ||
30 | + this.setState({ | ||
31 | + errorMsg:'Permission to access location was denied' | ||
32 | + }) | ||
33 | + } | ||
34 | + | ||
35 | + let location = await Location.getCurrentPositionAsync({}); | ||
36 | + console.log(location) | ||
37 | + this.setState({ | ||
38 | + location | ||
39 | + },() => { | ||
40 | + console.log(this.state.location.coords.latitude) | ||
41 | + }) | ||
42 | + })(); | ||
43 | + } | ||
44 | + render() { | ||
45 | + return ( | ||
46 | + this.state.location? | ||
47 | + <MapView | ||
48 | + style={{ flex: 1 }} | ||
49 | + initialRegion={ { latitude: this.state.location.coords.latitude, longitude: this.state.location.coords.longitude | ||
50 | + ,latitudeDelta: 0.0922, longitudeDelta: 0.0421}} | ||
51 | + zoomEnabled={true} | ||
52 | + pitchEnabled={true} | ||
53 | + showsUserLocation={true} | ||
54 | + followsUserLocation={true} | ||
55 | + showsCompass={true} | ||
56 | + showsBuildings={true} | ||
57 | + showsTraffic={true} | ||
58 | + showsIndoors={true} | ||
59 | + extent={512}> | ||
60 | + <Marker coordinate={{ latitude: this.state.location.coords.latitude+0.1, longitude: this.state.location.coords.longitude }} /> | ||
61 | + <Marker coordinate={{ latitude: this.state.location.coords.latitude+0.5, longitude: this.state.location.coords.longitude }} /> | ||
62 | + <Marker coordinate={{ latitude: this.state.location.coords.latitude+0.0001, longitude: this.state.location.coords.longitude }} /> | ||
63 | + <Marker coordinate={{ latitude: this.state.location.coords.latitude+0.0003, longitude: this.state.location.coords.longitude }} /> | ||
64 | + <Marker coordinate={{ latitude: this.state.location.coords.latitude+0.03, longitude: this.state.location.coords.longitude }} /> | ||
65 | + <Marker coordinate={{ latitude: this.state.location.coords.latitude+0.05, longitude: this.state.location.coords.longitude }} /> | ||
66 | + <Marker coordinate={{ latitude: this.state.location.coords.latitude+0.01, longitude: this.state.location.coords.longitude }} /> | ||
67 | + <Marker coordinate={{ latitude: this.state.location.coords.latitude+0.2, longitude: this.state.location.coords.longitude }} /> | ||
68 | + <Marker coordinate={{ latitude: this.state.location.coords.latitude+0.3, longitude: this.state.location.coords.longitude }} /> | ||
69 | + <Marker coordinate={{ latitude: this.state.location.coords.latitude+0.7, longitude: this.state.location.coords.longitude }} /> | ||
70 | + | ||
71 | + </MapView>:<Text>Loading..</Text> | ||
72 | + ); | ||
73 | + } | ||
74 | +} | ||
75 | + | ||
76 | +const styles = StyleSheet.create({ | ||
77 | + container: { | ||
78 | + flex: 1, | ||
79 | + alignItems: 'center', | ||
80 | + justifyContent: 'center', | ||
81 | + }, | ||
82 | +}); | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
소스코드/PME/components/helpers.js
0 → 100644
1 | +import GeoViewport from "@mapbox/geo-viewport"; | ||
2 | +import { Dimensions } from "react-native"; | ||
3 | + | ||
4 | +const { width, height } = Dimensions.get("window"); | ||
5 | + | ||
6 | +export const isMarker = child => | ||
7 | + child && | ||
8 | + child.props && | ||
9 | + child.props.coordinate && | ||
10 | + child.props.cluster !== false; | ||
11 | + | ||
12 | +export const calculateBBox = region => { | ||
13 | + let lngD; | ||
14 | + if (region.longitudeDelta < 0) lngD = region.longitudeDelta + 360; | ||
15 | + else lngD = region.longitudeDelta; | ||
16 | + | ||
17 | + return [ | ||
18 | + region.longitude - lngD, // westLng - min lng | ||
19 | + region.latitude - region.latitudeDelta, // southLat - min lat | ||
20 | + region.longitude + lngD, // eastLng - max lng | ||
21 | + region.latitude + region.latitudeDelta // northLat - max lat | ||
22 | + ]; | ||
23 | +}; | ||
24 | + | ||
25 | +export const returnMapZoom = (region, bBox, minZoom) => { | ||
26 | + const viewport = | ||
27 | + region.longitudeDelta >= 40 | ||
28 | + ? { zoom: minZoom } | ||
29 | + : GeoViewport.viewport(bBox, [width, height]); | ||
30 | + | ||
31 | + return viewport.zoom; | ||
32 | +}; | ||
33 | + | ||
34 | +export const markerToGeoJSONFeature = (marker, index) => { | ||
35 | + return { | ||
36 | + type: "Feature", | ||
37 | + geometry: { | ||
38 | + coordinates: [ | ||
39 | + marker.props.coordinate.longitude, | ||
40 | + marker.props.coordinate.latitude | ||
41 | + ], | ||
42 | + type: "Point" | ||
43 | + }, | ||
44 | + properties: { | ||
45 | + point_count: 0, | ||
46 | + index, | ||
47 | + ..._removeChildrenFromProps(marker.props) | ||
48 | + } | ||
49 | + }; | ||
50 | +}; | ||
51 | + | ||
52 | +export const generateSpiral = (count, centerLocation, clusterChildren) => { | ||
53 | + let res = []; | ||
54 | + res.length = count; | ||
55 | + let angle = 0; | ||
56 | + | ||
57 | + for (let i = 0; i < count; i++) { | ||
58 | + angle = 0.25 * (i * 0.5); | ||
59 | + let latitude = centerLocation[1] + 0.0002 * angle * Math.cos(angle); | ||
60 | + let longitude = centerLocation[0] + 0.0002 * angle * Math.sin(angle); | ||
61 | + res[i] = { | ||
62 | + longitude, | ||
63 | + latitude, | ||
64 | + image: clusterChildren[i] && clusterChildren[i].properties.image, | ||
65 | + onPress: clusterChildren[i] && clusterChildren[i].properties.onPress | ||
66 | + }; | ||
67 | + } | ||
68 | + | ||
69 | + return res; | ||
70 | +}; | ||
71 | + | ||
72 | +export const returnMarkerStyle = points => { | ||
73 | + if (points >= 50) { | ||
74 | + return { | ||
75 | + width: 84, | ||
76 | + height: 84, | ||
77 | + size: 64, | ||
78 | + fontSize: 20 | ||
79 | + }; | ||
80 | + } | ||
81 | + | ||
82 | + if (points >= 25) { | ||
83 | + return { | ||
84 | + width: 78, | ||
85 | + height: 78, | ||
86 | + size: 58, | ||
87 | + fontSize: 19 | ||
88 | + }; | ||
89 | + } | ||
90 | + | ||
91 | + if (points >= 15) { | ||
92 | + return { | ||
93 | + width: 72, | ||
94 | + height: 72, | ||
95 | + size: 54, | ||
96 | + fontSize: 18 | ||
97 | + }; | ||
98 | + } | ||
99 | + | ||
100 | + if (points >= 10) { | ||
101 | + return { | ||
102 | + width: 66, | ||
103 | + height: 66, | ||
104 | + size: 50, | ||
105 | + fontSize: 17 | ||
106 | + }; | ||
107 | + } | ||
108 | + | ||
109 | + if (points >= 8) { | ||
110 | + return { | ||
111 | + width: 60, | ||
112 | + height: 60, | ||
113 | + size: 46, | ||
114 | + fontSize: 17 | ||
115 | + }; | ||
116 | + } | ||
117 | + | ||
118 | + if (points >= 4) { | ||
119 | + return { | ||
120 | + width: 54, | ||
121 | + height: 54, | ||
122 | + size: 40, | ||
123 | + fontSize: 16 | ||
124 | + }; | ||
125 | + } | ||
126 | + | ||
127 | + return { | ||
128 | + width: 48, | ||
129 | + height: 48, | ||
130 | + size: 36, | ||
131 | + fontSize: 15 | ||
132 | + }; | ||
133 | +}; | ||
134 | + | ||
135 | +const _removeChildrenFromProps = props => { | ||
136 | + const newProps = {}; | ||
137 | + Object.keys(props).forEach(key => { | ||
138 | + if (key !== "children") { | ||
139 | + newProps[key] = props[key]; | ||
140 | + } | ||
141 | + }); | ||
142 | + return newProps; | ||
143 | +}; |
소스코드/PME/package-lock.json
0 → 100644
This diff could not be displayed because it is too large.
소스코드/PME/package.json
0 → 100644
1 | +{ | ||
2 | + "main": "node_modules/expo/AppEntry.js", | ||
3 | + "scripts": { | ||
4 | + "start": "expo start", | ||
5 | + "android": "expo start --android", | ||
6 | + "ios": "expo start --ios", | ||
7 | + "web": "expo start --web", | ||
8 | + "eject": "expo eject" | ||
9 | + }, | ||
10 | + "dependencies": { | ||
11 | + "@expo/vector-icons": "^10.1.0", | ||
12 | + "@react-native-community/masked-view": "^0.1.10", | ||
13 | + "expo": "~37.0.3", | ||
14 | + "expo-constants": "^9.0.0", | ||
15 | + "expo-location": "^8.1.0", | ||
16 | + "native-base": "^2.13.12", | ||
17 | + "react": "~16.9.0", | ||
18 | + "react-dom": "~16.9.0", | ||
19 | + "react-native": "https://github.com/expo/react-native/archive/sdk-37.0.1.tar.gz", | ||
20 | + "react-native-gesture-handler": "^1.6.1", | ||
21 | + "react-native-map-clustering": "^3.1.2", | ||
22 | + "react-native-maps": "^0.27.1", | ||
23 | + "react-native-safe-area-context": "^0.7.3", | ||
24 | + "react-native-screens": "^2.7.0", | ||
25 | + "react-native-web": "~0.11.7", | ||
26 | + "react-navigation": "^4.3.8", | ||
27 | + "react-navigation-stack": "^2.3.13" | ||
28 | + }, | ||
29 | + "devDependencies": { | ||
30 | + "@babel/core": "^7.8.6", | ||
31 | + "babel-preset-expo": "~8.1.0" | ||
32 | + }, | ||
33 | + "private": true | ||
34 | +} |
소스코드/PME/yarn.lock
0 → 100644
This diff could not be displayed because it is too large.
소스코드/package.json
0 → 100644
소스코드/yarn.lock
0 → 100644
This diff is collapsed. Click to expand it.
주제보고서/중간보고서.hwp
0 → 100644
No preview for this file type
-
Please register or login to post a comment