김승훈

final report

var SERVER_lOCAL = "f3eb38c42803.ngrok.io"
var SERVER_= "311cd4338cad.ngrok.io"
var SERVER_= "53d03390d6cb.ngrok.io"
var SERVER = SERVER_
export { SERVER }
\ No newline at end of file
......
......@@ -13,14 +13,15 @@ class MainPage extends Component {
super(props)
//AsyncStorage.getItem('isFirst',(err,result) => {
//
// JSON.parse(result)? this.props.navigation.navigate('App'):
//
// this.props.navigation.navigate('Guidance')
//
//})
AsyncStorage.getItem('isFirst',(err,result) => {
JSON.parse(result)? this.props.navigation.navigate('App'):
this.props.navigation.navigate('Guidance')
})
this.props.navigation.navigate('Guidance')
}
_onRefresh = () => {
this.setState({refreshing: true});
......
node_modules/
venv/
\ No newline at end of file
{
"12bb71342c6255bbf50437ec8f4441c083f47cdb74bd89160c15e4f43e52a1cb": true,
"40b842e832070c58deac6aa9e08fa459302ee3f9da492c7e77d93d2fbf4a56fd": true
}
node_modules/**/*
.expo/*
npm-debug.*
*.jks
*.p8
*.p12
*.key
*.mobileprovision
*.orig.*
web-build/
web-report/
# macOS
.DS_Store
import { Component } from 'react';
import { StyleSheet, Text, View, AppRegistry } from 'react-native';
import { createAppContainer } from 'react-navigation';
import {createStackNavigator } from 'react-navigation-stack'
import MainScreen from './components/Navigation/Navigation';
import React from 'react'
const AppStackNavigator = createStackNavigator({
Main:{
screen: MainScreen,
navigationOptions: {
headerShown:false
}
}
});
export default createAppContainer(AppStackNavigator);
\ No newline at end of file
{
"expo": {
"name": "HelloWorld",
"slug": "PME",
"platforms": [
"ios",
"android",
"web"
],
"version": "1.0.0",
"orientation": "portrait",
"icon": "./assets/icon.png",
"splash": {
"image": "./assets/splash.png",
"resizeMode": "contain",
"backgroundColor": "#ffffff"
},
"updates": {
"fallbackToCacheTimeout": 0
},
"assetBundlePatterns": [
"**/*"
],
"ios": {
"supportsTablet": true
},
"android" : {
"package" : "com.A.BLE",
"config": {
"googleMaps": {"apiKey":"AIzaSyCe_1-Mml2OyihnmS2oiPUj73X-Aj1j_2k"}
}
}
}
}
module.exports = function(api) {
api.cache(true);
return {
presets: ['babel-preset-expo'],
};
};
import React, { memo, useState, useEffect, useMemo, createRef } from "react";
import { Dimensions, LayoutAnimation, Platform } from "react-native";
import MapView, { Marker, Polyline } from "react-native-maps";
import SuperCluster from "supercluster";
import ClusterMarker from "./ClusteredMarker";
import {
isMarker,
markerToGeoJSONFeature,
calculateBBox,
returnMapZoom,
generateSpiral
} from "./helpers";
const ClusteredMapView = ({
radius,
maxZoom,
minZoom,
extent,
nodeSize,
children,
onClusterPress,
onRegionChangeComplete,
preserveClusterPressBehavior,
clusteringEnabled,
clusterColor,
clusterTextColor,
spiderLineColor,
layoutAnimationConf,
animationEnabled,
renderCluster,
...restProps
}) => {
const [markers, updateMarkers] = useState([]);
const [spiderMarkers, updateSpiderMarker] = useState([]);
const [otherChildren, updateChildren] = useState([]);
const [superCluster, setSuperCluster] = useState(null);
const [currentRegion, updateRegion] = useState(
restProps.region || restProps.initialRegion
);
const [isSpiderfier, updateSpiderfier] = useState(false);
const [spiderfierMarker, updateSpiderfierMarker] = useState(null);
const [clusterChildren, updateClusterChildren] = useState(null);
const mapRef = createRef();
const propsChildren = useMemo(() => React.Children.toArray(children), [
children
]);
useEffect(() => {
const rawData = [];
const otherChildren = [];
if (!clusteringEnabled) {
updateChildren(propsChildren);
return;
}
React.Children.forEach(children, (child, i) => {
if (isMarker(child)) {
rawData.push(markerToGeoJSONFeature(child, i));
} else {
otherChildren.push(child);
}
});
const superCluster = new SuperCluster({
radius,
maxZoom,
minZoom,
extent,
nodeSize
});
superCluster.load(rawData);
const bBox = calculateBBox(currentRegion);
const zoom = returnMapZoom(currentRegion, bBox, minZoom);
const markers = superCluster.getClusters(bBox, zoom);
updateMarkers(markers);
updateChildren(otherChildren);
setSuperCluster(superCluster);
}, [children, restProps.region, restProps.initialRegion]);
useEffect(() => {
if (isSpiderfier && markers.length > 0) {
let positions = generateSpiral(
markers[0].properties.point_count,
markers[0].geometry.coordinates,
clusterChildren
);
updateSpiderMarker(positions);
updateSpiderfierMarker({
latitude: markers[0].geometry.coordinates[1],
longitude: markers[0].geometry.coordinates[0]
});
} else {
updateSpiderMarker([]);
}
}, [isSpiderfier]);
const _onRegionChangeComplete = region => {
if (superCluster) {
const bBox = calculateBBox(region);
const zoom = returnMapZoom(region, bBox, minZoom);
const markers = superCluster.getClusters(bBox, zoom);
if (animationEnabled && Platform.OS === "ios") {
LayoutAnimation.configureNext(layoutAnimationConf);
}
if (zoom >= 17 && markers.length === 1 && clusterChildren) {
updateSpiderfier(true);
} else {
updateSpiderfier(false);
}
updateMarkers(markers);
onRegionChangeComplete(region, markers);
updateRegion(region);
}
};
const _onClusterPress = cluster => () => {
const children = superCluster.getLeaves(cluster.id);
updateClusterChildren(children);
if (preserveClusterPressBehavior) {
onClusterPress(cluster, children);
return;
}
const coordinates = children.map(({ geometry }) => ({
latitude: geometry.coordinates[1],
longitude: geometry.coordinates[0]
}));
mapRef.current.fitToCoordinates(coordinates, {
edgePadding: restProps.edgePadding
});
onClusterPress(cluster, children);
};
return (
<MapView
{...restProps}
ref={map => {
restProps.mapRef(map);
mapRef.current = map;
}}
onRegionChangeComplete={_onRegionChangeComplete}
>
{markers.map(marker =>
marker.properties.point_count === 0 ? (
propsChildren[marker.properties.index]
) : !isSpiderfier ? (
renderCluster ? (
renderCluster({
onPress: _onClusterPress(marker),
clusterColor,
clusterTextColor,
...marker
})
) : (
<ClusterMarker
key={`cluster-${marker.id}`}
{...marker}
onPress={_onClusterPress(marker)}
clusterColor={clusterColor}
clusterTextColor={clusterTextColor}
/>
)
) : null
)}
{otherChildren}
{spiderMarkers.map(marker => (
<Marker
key={marker.latitude}
coordinate={marker}
image={marker.image}
onPress={marker.onPress}
></Marker>
))}
{spiderMarkers.map((marker, index) => {
{
return (
spiderfierMarker && (
<Polyline
key={index}
coordinates={[spiderfierMarker, marker, spiderfierMarker]}
strokeColor={spiderLineColor}
strokeWidth={1}
/>
)
);
}
})}
</MapView>
);
};
ClusteredMapView.defaultProps = {
clusteringEnabled: true,
animationEnabled: true,
preserveClusterPressBehavior: false,
layoutAnimationConf: LayoutAnimation.Presets.spring,
// SuperCluster parameters
radius: Dimensions.get("window").width * 0.06,
maxZoom: 20,
minZoom: 1,
extent: 512,
nodeSize: 64,
// Map parameters
edgePadding: { top: 50, left: 50, right: 50, bottom: 50 },
// Cluster styles
clusterColor: "#00B386",
clusterTextColor: "#FFFFFF",
spiderLineColor: "#FF0000",
// Callbacks
onRegionChangeComplete: () => {},
onClusterPress: () => {},
mapRef: () => {}
};
export default memo(ClusteredMapView);
import React, { memo } from "react";
import { Text, View, StyleSheet, TouchableOpacity } from "react-native";
import { Marker } from "react-native-maps";
import { returnMarkerStyle } from "./helpers";
const ClusteredMarker = ({
geometry,
properties,
onPress,
clusterColor,
clusterTextColor
}) => {
const points = properties.point_count;
const { width, height, fontSize, size } = returnMarkerStyle(points);
return (
<Marker
coordinate={{
longitude: geometry.coordinates[0],
latitude: geometry.coordinates[1]
}}
style={{ zIndex: points + 1 }}
onPress={onPress}
>
<TouchableOpacity
activeOpacity={0.5}
style={[styles.container, { width, height }]}
>
<View
style={[
styles.wrapper,
{
backgroundColor: clusterColor,
width,
height,
borderRadius: width / 2
}
]}
/>
<View
style={[
styles.cluster,
{
backgroundColor: clusterColor,
width: size,
height: size,
borderRadius: size / 2
}
]}
>
<Text style={[styles.text, { color: clusterTextColor, fontSize }]}>
{points}
</Text>
</View>
</TouchableOpacity>
</Marker>
);
};
const styles = StyleSheet.create({
container: {
display: "flex",
justifyContent: "center",
alignItems: "center"
},
wrapper: {
position: "absolute",
opacity: 0.5,
zIndex: 0
},
cluster: {
display: "flex",
justifyContent: "center",
alignItems: "center",
zIndex: 1
},
text: {
fontWeight: "bold"
}
});
export default memo(ClusteredMarker);
import { Component } from 'react';
import { StyleSheet, Text, View, Image, TouchableOpacity, Alert } from 'react-native';
import { Icon } from 'native-base'; // 추가된 코드
import React from 'react'
import {Marker} from 'react-native-maps'
import Constants from 'expo-constants';
import * as Location from 'expo-location';
import MapView from "../ClusteredMapView";
export default class MainScreen extends Component {
// navigationOptions 코드 추가
static navigationOptions = {
headerLeft: <Icon name='ios-camera' style={{ paddingLeft:10 }}/>,
title: 'PME Service',
headerRight: <Icon name='ios-send' style={{ paddingRight:10 }}/>,
}
constructor(props) {
super(props)
this.state= {
location:null,
errorMsg:null
}
}
componentDidMount() {
(async () => {
let { status } = await Location.requestPermissionsAsync();
if (status !== 'granted') {
this.setState({
errorMsg:'Permission to access location was denied'
})
}
let location = await Location.getCurrentPositionAsync({});
console.log(location)
this.setState({
location
},() => {
console.log(this.state.location.coords.latitude)
})
})();
}
render() {
return (
//this.state.location?
<View style={{width:"100%",height:"100%"}}>
<TouchableOpacity onPress={() => Alert.alert('OK',"주변에 의심자가 있습니까?",[{text:"OK",onPress:() =>alert("확인")},{text:'cancel'}])} style={{position:"absolute",bottom:10,right:10, width:50,height:50,backgroundColor:"red",borderRadius:100}}>
<View style={{flex:1,justifyContent: 'center',alignItems: 'center'}}>
<Image style={{width:22,height:22}} source={require('../assets/security.png')}/>
</View>
</TouchableOpacity>
</View>
//:<Text>Loading..</Text>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
});
\ No newline at end of file
import React, { Component } from 'react';
import { StyleSheet, Text, View, Image,
TouchableOpacity, ScrollView, Dimensions,
SafeAreaView, } from 'react-native';
import { createAppContainer} from 'react-navigation';
import {createStackNavigator } from 'react-navigation-stack';
import ReportTab from '../TabNavigator/reportTab'
import MainTab from '../TabNavigator/MainTab'
import { Icon } from 'native-base'; // 추가된 코드
const Stack = createStackNavigator(
{
MainTab: {
screen: props => <MainTab {...props}/>,
navigationOptions: {
headerLeft: <Icon name='ios-camera' style={{ paddingLeft:10 }}/>,
title: 'PME Service',
headerRight: <Icon name='ios-send' style={{ paddingRight:10 }}/>,
headerTitleStyle: {flex: 1, textAlign: 'center'},
headerStyle: {
shadowOpacity: 0,
shadowOffset: {
y: 0,
x:0,
height:0
},
shadowRadius: 0, elevation:0
}
},
}
,reportTab: {
screen: props=> <ReportTab {...props}/>,
navigationOptions: {
headerShown:false
}
},
},{
}
);
export default createAppContainer(Stack);
/*
<Text
onPress={() => {
props.navigation.navigate('BlueScreen');
props.navigation.closeDrawer();
}}
>
BlueScreen
</Text>
<Text
onPress={() => {
props.navigation.navigate('DefaultScreen');
props.navigation.closeDrawer();
}}
>
DefaultScreen
</Text>
*/
\ No newline at end of file
import { Component } from 'react';
import { StyleSheet, Text, View, Image, TouchableOpacity, Alert, Platform } from 'react-native';
import { Icon } from 'native-base'; // 추가된 코드
import React from 'react'
import {Marker} from 'react-native-maps'
import Constants from 'expo-constants';
import * as Location from 'expo-location';
import MapView from "../ClusteredMapView";
import Share from 'react-native-share';
const url = 'https://awesome.contents.com/';
const title = 'Awesome Contents';
const message = 'Please check this out.';
const icon = 'data:<data_type>/<file_extension>;base64,<base64_data>';
const options = Platform.select({
ios: {
activityItemSources: [
{ // For sharing url with custom title.
placeholderItem: { type: 'url', content: url },
item: {
default: { type: 'url', content: url },
},
subject: {
default: title,
},
linkMetadata: { originalUrl: url, url, title },
},
{ // For sharing text.
placeholderItem: { type: 'text', content: message },
item: {
default: { type: 'text', content: message },
message: null, // Specify no text to share via Messages app.
},
linkMetadata: { // For showing app icon on share preview.
title: message
},
},
{ // For using custom icon instead of default text icon at share preview when sharing with message.
placeholderItem: {
type: 'url',
content: icon
},
item: {
default: {
type: 'text',
content: `${message} ${url}`
},
},
linkMetadata: {
title: message,
icon: icon
}
},
],
},
default: {
title,
subject: title,
message: `${message} ${url}`,
},
});
export default class MainScreen extends Component {
// navigationOptions 코드 추가
static navigationOptions = {
headerLeft: <Icon name='ios-camera' style={{ paddingLeft:10 }}/>,
title: 'PME Service',
headerRight: <Icon name='ios-send' style={{ paddingRight:10 }}/>,
}
constructor(props) {
super(props)
this.state= {
location:null,
errorMsg:null
}
}
componentDidMount() {
(async () => {
let { status } = await Location.requestPermissionsAsync();
if (status !== 'granted') {
this.setState({
errorMsg:'Permission to access location was denied'
})
}
let location = await Location.getCurrentPositionAsync({});
console.log(location)
this.setState({
location
},() => {
console.log(this.state.location.coords.latitude)
})
})();
}
render() {
return (
this.state.location?
<View style={{width:"100%",height:"100%"}}>
<MapView
style={{ flex: 1 }}
initialRegion={ { latitude: this.state.location.coords.latitude, longitude: this.state.location.coords.longitude
,latitudeDelta: 0.0922, longitudeDelta: 0.0421}}
zoomEnabled={true}
pitchEnabled={true}
showsUserLocation={true}
followsUserLocation={true}
showsCompass={true}
showsBuildings={true}
showsTraffic={true}
showsIndoors={true}
extent={512}>
<Marker coordinate={{ latitude: this.state.location.coords.latitude+0.1, longitude: this.state.location.coords.longitude }} >
<Image style={{width:54,height:54}} source={require('../../assets/marker.png')}/>
</Marker>
<Marker coordinate={{ latitude: this.state.location.coords.latitude+0.5, longitude: this.state.location.coords.longitude }}>
<Image style={{width:54,height:54}} source={require('../../assets/marker.png')}/>
</Marker>
<Marker icon="../../assets/marker.png" coordinate={{ latitude: this.state.location.coords.latitude+0.0001, longitude: this.state.location.coords.longitude }}>
<Image style={{width:54,height:54}} source={require('../../assets/marker.png')}/>
</Marker>
<Marker icon="../../assets/marker.png" coordinate={{ latitude: this.state.location.coords.latitude+0.0003, longitude: this.state.location.coords.longitude }}>
<Image style={{width:54,height:54}} source={require('../../assets/marker.png')}/>
</Marker>
<Marker icon="../../assets/marker.png" coordinate={{ latitude: this.state.location.coords.latitude+0.03, longitude: this.state.location.coords.longitude }}>
<Image style={{width:54,height:54}} source={require('../../assets/marker.png')}/>
</Marker>
<Marker icon="../../assets/marker.png" coordinate={{ latitude: this.state.location.coords.latitude+0.05, longitude: this.state.location.coords.longitude }}>
<Image style={{width:54,height:54}} source={require('../../assets/marker.png')}/>
</Marker>
<Marker icon="../../assets/marker.png" coordinate={{ latitude: this.state.location.coords.latitude+0.01, longitude: this.state.location.coords.longitude }}>
<Image style={{width:54,height:54}} source={require('../../assets/marker.png')}/>
</Marker>
<Marker icon="../../assets/marker.png" coordinate={{ latitude: this.state.location.coords.latitude+0.2, longitude: this.state.location.coords.longitude }}>
<Image style={{width:54,height:54}} source={require('../../assets/marker.png')}/>
</Marker>
<Marker icon="../../assets/marker.png" coordinate={{ latitude: this.state.location.coords.latitude+0.3, longitude: this.state.location.coords.longitude }}>
<Image style={{width:54,height:54}} source={require('../../assets/marker.png')}/>
</Marker>
<Marker icon="../../assets/marker.png" coordinate={{ latitude: this.state.location.coords.latitude+0.7, longitude: this.state.location.coords.longitude }}>
<Image style={{width:54,height:54}} source={require('../../assets/marker.png')}/>
</Marker>
</MapView>
<TouchableOpacity onPress={() => Alert.alert('OK',"주변에 의심자가 있습니까?",[{text:"OK",onPress:() =>Share.open(options)},{text:'cancel'}])} style={{position:"absolute",bottom:10,right:10, width:50,height:50,backgroundColor:"red",borderRadius:100}}>
<View style={{flex:1,justifyContent: 'center',alignItems: 'center'}}>
<Image style={{width:22,height:22}} source={require('../../assets/security.png')}/>
</View>
</TouchableOpacity>
</View>
:<Text>Loading..</Text>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
});
\ No newline at end of file
import React, { Component } from 'react';
import { View, Text, StyleSheet, Button } from 'react-native';
import * as DocumentPicker from 'expo-document-picker';
import Icon from 'native-base'
export default class AddTab extends Component {
static navigationOptions = {
headerLeft: <Icon name='ios-camera' style={{ paddingLeft:10 }}/>,
title: 'PME Service',
headerRight: <Icon name='ios-send' style={{ paddingRight:10 }}/>,
}
state = {
image: null,
};
_pickDocument = async () => {
let result = await DocumentPicker.getDocumentAsync({});
alert(result.uri);
console.log(result);
}
_pickImage = async () => {
let result = await ImagePicker.launchImageLibraryAsync({
allowsEditing: true,
aspect: [4, 3],
});
alert(result.uri);
console.log(result)
if (!result.cancelled) {
this.setState({ image: result.uri });
}
};
render() {
let { image } = this.state;
return (
<View style={style.container}>
<Button
title="녹음파일을 등록해주세요."
onPress={this._pickDocument}
/>
<Button
title="접수하기"
onPress={() => {alert("접수되었습니다.")}}
/>
</View>
);
}
}
const style = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
}
});
\ No newline at end of file
import GeoViewport from "@mapbox/geo-viewport";
import { Dimensions } from "react-native";
const { width, height } = Dimensions.get("window");
export const isMarker = child =>
child &&
child.props &&
child.props.coordinate &&
child.props.cluster !== false;
export const calculateBBox = region => {
let lngD;
if (region.longitudeDelta < 0) lngD = region.longitudeDelta + 360;
else lngD = region.longitudeDelta;
return [
region.longitude - lngD, // westLng - min lng
region.latitude - region.latitudeDelta, // southLat - min lat
region.longitude + lngD, // eastLng - max lng
region.latitude + region.latitudeDelta // northLat - max lat
];
};
export const returnMapZoom = (region, bBox, minZoom) => {
const viewport =
region.longitudeDelta >= 40
? { zoom: minZoom }
: GeoViewport.viewport(bBox, [width, height]);
return viewport.zoom;
};
export const markerToGeoJSONFeature = (marker, index) => {
return {
type: "Feature",
geometry: {
coordinates: [
marker.props.coordinate.longitude,
marker.props.coordinate.latitude
],
type: "Point"
},
properties: {
point_count: 0,
index,
..._removeChildrenFromProps(marker.props)
}
};
};
export const generateSpiral = (count, centerLocation, clusterChildren) => {
let res = [];
res.length = count;
let angle = 0;
for (let i = 0; i < count; i++) {
angle = 0.25 * (i * 0.5);
let latitude = centerLocation[1] + 0.0002 * angle * Math.cos(angle);
let longitude = centerLocation[0] + 0.0002 * angle * Math.sin(angle);
res[i] = {
longitude,
latitude,
image: clusterChildren[i] && clusterChildren[i].properties.image,
onPress: clusterChildren[i] && clusterChildren[i].properties.onPress
};
}
return res;
};
export const returnMarkerStyle = points => {
if (points >= 50) {
return {
width: 84,
height: 84,
size: 64,
fontSize: 20
};
}
if (points >= 25) {
return {
width: 78,
height: 78,
size: 58,
fontSize: 19
};
}
if (points >= 15) {
return {
width: 72,
height: 72,
size: 54,
fontSize: 18
};
}
if (points >= 10) {
return {
width: 66,
height: 66,
size: 50,
fontSize: 17
};
}
if (points >= 8) {
return {
width: 60,
height: 60,
size: 46,
fontSize: 17
};
}
if (points >= 4) {
return {
width: 84,
height: 84,
size: 64,
fontSize: 16
};
}
return {
width: 84,
height: 84,
size: 64,
fontSize: 15
};
};
const _removeChildrenFromProps = props => {
const newProps = {};
Object.keys(props).forEach(key => {
if (key !== "children") {
newProps[key] = props[key];
}
});
return newProps;
};
This diff could not be displayed because it is too large.
{
"main": "node_modules/expo/AppEntry.js",
"scripts": {
"start": "expo start",
"android": "expo start --android",
"ios": "expo start --ios",
"web": "expo start --web",
"eject": "expo eject"
},
"dependencies": {
"@expo/vector-icons": "^10.1.0",
"@react-native-community/masked-view": "^0.1.10",
"expo": "~37.0.3",
"expo-constants": "^9.0.0",
"expo-document-picker": "^8.1.0",
"expo-location": "^8.1.0",
"native-base": "^2.13.12",
"react": "~16.9.0",
"react-dom": "~16.9.0",
"react-native": "https://github.com/expo/react-native/archive/sdk-37.0.1.tar.gz",
"react-native-gesture-handler": "^1.6.1",
"react-native-map-clustering": "^3.1.2",
"react-native-maps": "^0.27.1",
"react-native-safe-area-context": "^0.7.3",
"react-native-screens": "^2.7.0",
"react-native-share": "^3.3.2",
"react-native-web": "~0.11.7",
"react-navigation": "^4.3.9",
"react-navigation-stack": "^2.5.0"
},
"devDependencies": {
"@babel/core": "^7.8.6",
"babel-preset-expo": "~8.1.0"
},
"private": true
}
This diff could not be displayed because it is too large.
{
"dependencies": {
"@expo/vector-icons": "^10.1.0",
"native-base": "^2.13.12",
"react-navigation": "^4.3.8"
}
}
This diff is collapsed. Click to expand it.
No preview for this file type