2 글 보임 - 1 에서 2 까지 (총 2 중에서)
-
글쓴이글
-
2023년 6월 4일 06:26 #85752
정윤식참가자현재 python과 node.js의 서버 server.js 를 사용하여 mongoDB에 데이터를 저장하려고 합니다.
<geo.py (public 디렉토리에 위치)>
import json import os from flask import Flask, render_template, request, jsonify from pymongo import MongoClient import numpy as np from sklearn.linear_model import LinearRegression
app = Flask(__name__, static_folder='public')
client = MongoClient('mongodb://localhost:5000/') db = client['mapdata'] # 데이터베이스 이름 설정 collection = db['calculate'] # 컬렉션 이름 설정
@app.route("/") def index(): return render_template("geo.ejs")
@app.route("/geojson") def get_geojson(): # file_path = os.path.join("public", "data.geojson") file_path = os.path.join(os.path.dirname(__file__), "public", "data.geojson") with open(file_path) as f: geojson_data = json.load(f) return jsonify(geojson_data)
@app.route("/elevation", methods=["POST"]) def calculate_elevation(): data = request.get_json() coordinates = data.get("coordinates") # TODO: 좌표를 기반으로 고도 계산하기 # elevations = [] elevations = [100, 200, 300]
file_path = os.path.join("public", "data.geojson") with open(file_path) as f: geojson_data = json.load(f)
features = geojson_data["features"] for coord in coordinates: lat = coord[0] lon = coord[1] elevation = get_elevation_from_geojson(features, lat, lon) elevations.append(elevation)
return jsonify(elevations)
def get_elevation_from_geojson(features, lat, lon): for feature in features: coordinates = feature["geometry"]["coordinates"][0] # 인덱스 수정 if is_close(coordinates[0], lon) and is_close(coordinates[1], lat): return feature["properties"]["elevation"]
return 0
def is_close(a, b, rel_tol=1e-09, abs_tol=0.0): return abs(a - b) <= max(rel_tol * max(abs(a), abs(b)), abs_tol)
@app.route("/predict", methods=["POST"]) def predict(): data = request.get_json() elevations = data.get("elevation")
# 경사도와 5분 동안의 심박수 증가량 데이터 X = np.array(elevations) # Elevation of trail 데이터 Y = 10.2025 * np.power(X, 0.4392) # 5분 동안의 심박수 증가량 데이터
# 모델 훈련 model = LinearRegression() X = X.reshape(-1, 1) # 입력 데이터를 2D 배열로 변환 model.fit(X, Y)
# 모델 예측 new_X = np.array(elevations) # 예측을 위한 새로운 Elevation of trail 데이터 new_X = new_X.reshape(-1, 1) # 입력 데이터를 2D 배열로 변환 predicted_Y = model.predict(new_X)
return jsonify(predicted_Y.tolist())
@app.route("/calculate_time", methods=["POST"]) def calculate_time(): data = request.get_json() from_latlng = data.get("from") to_latlng = data.get("to") increment_hr = data.get("Increment of HR") avg_hr = data.get("average HR") time_min = data.get("Taking Time(Minute)")
if from_latlng is None or to_latlng is None: return jsonify("Start and end locations are required"), 400
if avg_hr is None: return jsonify("Average HR is required"), 400
predicted_time = (avg_hr - float(from_latlng["lat"])) / increment_hr * time_min if predicted_time < 20: return jsonify(0)
# MongoDB에 데이터 저장 route_data = { "from": from_latlng, "to": to_latlng, "increment_hr": increment_hr, "average_hr": avg_hr, "taking_time_min": time_min }
collection.insert_one(route_data)
response_data = { 'result': '계산 결과', }
return jsonify(response_data)
if __name__ == "__main__": app.run(host='0.0.0.0', port=5000)
<server.js 코드>
const express = require('express') const app = express() var path = require('path'); const http = require('http').createServer(app); // const {Server} = require('socket.io'); // const io = new Server(http); const axios = require("axios"); const { spawn } = require('child_process'); const MongoClient = require('mongodb').MongoClient; const methodOverride = require('method-override') // const geoPyHost = 'localhost'; // const geoPyPort = 5000; const serverPort = 8000;
app.use(express.urlencoded({ extended: true })); app.use(methodOverride('_method')) app.set('view engine', 'ejs'); app.use('/public', express.static('public'));
const url = 'http://localhost:5000/calculate_time'; const data = { from: { lat: 37.123, lng: 127.456 }, to: { lat: 37.789, lng: 128.123 }, 'Increment of HR': 5, 'average HR': 120, 'Taking Time(Minute)': 30 };
axios.post(url, data) .then(response => { // 요청 성공 시 실행할 코드 console.log(response.data); }) .catch(error => { // 요청 실패 시 실행할 코드 console.error(error); });
var db; MongoClient.connect('mongodb+srv://@cluster0.ofcyns9.mongodb.net/mapdata?retryWrites=true&w=majority', function(에러, client) {
db = client.db('mapdata');
app.get('/', function (요청, 응답) { 응답.render('index.ejs'); });
app.get('/write', function(요청, 응답) { 응답.render('write.ejs'); });
// app.listen(5000, function () { // console.log('listening on 5000') // });
// })
app.get('/list', function(요청, 응답) { db.collection('post').find().toArray(function(에러, 결과) { console.log(결과); 응답.render('list.ejs', { posts : 결과 }); }); });
app.get('/detail/:id', function(요청, 응답) { db.collection('post').findOne({_id : parseInt(요청.params.id)}, function(에러, 결과) { console.log(결과); 응답.render('detail.ejs', { data : 결과 }); }); });
app.get('/edit/:id', function(요청, 응답) { db.collection('post').findOne({_id : parseInt(요청.params.id)}, function(에러, 결과) { 응답.render('edit.ejs', { post : 결과 }) });
});
app.put('/edit', function(요청, 응답) { db.collection('post').updateOne({ _id : parseInt(요청.body.id)},{ $set : { 제목 : 요청.body.title, 날짜 : 요청.body.password}}, function(에러, 결과) { console.log('수정완료') 응답.redirect('/list') }) });
const passport = require('passport'); const LocalStrategy = require('passport-local').Strategy; const session = require('express-session');
app.use(session({secret : '비밀코드', resave : true, saveUninitialized: false})); app.use(passport.initialize()); app.use(passport.session());
app.get('/login', function(요청, 응답) { 응답.render('login.ejs') });
app.post('/login', passport.authenticate('local', { failureRedirect : '/fail' }), function(요청, 응답) { 응답.redirect('/') });
app.get('/mypage', 로그인, function(요청, 응답) { console.log(요청.user); 응답.render('geo.ejs', {사용자 : 요청.user}) })
function 로그인(요청, 응답, next) { if (요청.user) { next() } else { 응답.send('You have to Log on.') } }
passport.use(new LocalStrategy({ usernameField: 'id', passwordField: 'pw', session: true, passReqToCallback: false, }, function (입력한아이디, 입력한비번, done) { //console.log(입력한아이디, 입력한비번); db.collection('login').findOne({ id: 입력한아이디 }, function (에러, 결과) { if (에러) return done(에러)
if (!결과) return done(null, false, { message: '존재하지않는 아이디요' }) if (입력한비번 == 결과.pw) { return done(null, 결과) } else { return done(null, false, { message: '비번틀렸어요' }) } }) }));
passport.serializeUser(function (user, done) { done(null, user.id) });
passport.deserializeUser(function (아이디, done) { db.collection('login').findOne({id : 아이디}, function(에러, 결과) { done(null, 결과) }) });
app.post('/register', function(요청,응답){ db.collection('login').insertOne( {id : 요청.body.id, pw : 요청.body.pw}, function(에러, 결과) { 응답.redirect('/') }) });
app.post('/add', function (요청, 응답) { 응답.send('전송완료'); db.collection('counter').findOne({name : '게시물갯수'}, function(에러, 결과) { console.log(결과.totalPost) var 총게시물갯수 = 결과.totalPost; var 저장할거 = {_id : 총게시물갯수 + 1, 작성자 : 요청.user._id, 제목 : 요청.body.title, 날짜 : 요청.body.password}
db.collection('post').insertOne(저장할거 , function(에러, 결과) { console.log('저장완료'); db.collection('counter').updateOne({name:'게시물갯수'}, { $inc : {totalPost:1} }, function(에러, 결과) { if(에러) { return console.log(에러) } }) });
}); });
app.delete('/delete', function(요청, 응답){ console.log(요청.body); 요청.body._id = parseInt(요청.body._id);
var 삭제할데이터 = { _id : 요청.body._id, 작성자 : 요청.user._id }
db.collection('post').deleteOne(삭제할데이터, function(에러, 결과) { console.log('삭제완료'); if (에러) {console.log(에러)} 응답.status(200).send({ message: '성공했습니다' }); }) });
app.post('/calculate_time', function (req, res) { // 예상 시간 계산 로직 const { from, to, 'Increment of HR': increment_hr, 'average HR': average_hr, 'Taking Time(Minute)': taking_time_min } = req.body;
// 요청을 geo.py에 전달하여 예상 시간 계산 // const pythonProcess = spawn('python', ['geo.py', JSON.stringify(from), JSON.stringify(to), increment_hr, average_hr, taking_time_min]); const pythonProcess = spawn('python', [path.join(__dirname, 'public/geo.py'), JSON.stringify(from), JSON.stringify(to), increment_hr, average_hr, taking_time_min]);
pythonProcess.stdout.on('data', (data) => { const predictedTime = data.toString().trim(); res.json(predictedTime);
// 예상 시간을 MongoDB에 저장 db.collection('calculate').insertOne({ from: from, to: to, increment_hr: increment_hr, average_hr: average_hr, taking_time_min: taking_time_min, predicted_time: predictedTime }, function (에러, 결과) { if (에러) { return console.log(에러); } console.log('저장 완료'); }); });
pythonProcess.stderr.on('data', (data) => { console.error(`stderr: ${data}`); res.status(500).json('An error occurred'); }); });
app.listen(serverPort, () => { console.log(`서버가 ${serverPort} 포트에서 실행 중입니다.`); }); });
이렇게 저는 웹에 지도를 띄어서 출발지와 도착지를 두 마커로 지정했을 때 vscode의 터미널 창에 server.js를 실행하여 mongodb의 mapdata에 calculate 라는 collection을 만들고,
server.js 실행에서 빠져나온 후 터미널 창에 ~~\public>geo.py 를 실행하여 계산된 예측시간을 화면에 띄우는게 목표입니다. 하지만 둘 다 실행은 잘 되지만 mongodb에 들어가면 mapdata 에 calculate 가 저장되지 않고 터미널에서
127.0.0.1 - - [04/Jun/2023 06:21:36] code 400, message Bad request version ('3.10.7.final.0\x00\x00\x00') 127.0.0.1 - - [04/Jun/2023 06:21:36] "\x0c\x01\x00\x00Cd\x00\x00\x00\x00\x00\x00Ô\x07\x00\x00\x00\x00\x00\x00admin.$cmd\x00\x00\x00\x00\x00ÿÿÿÿå\x00\x00\x00\x10ismaster\x00\x01\x00\x00\x00\x08helloOk\x00\x01\x03client\x00À\x00\x00\x00\x03driver\x00*\x00\x00\x00\x02name\x00\x08\x00\x00\x00PyMongo\x00\x02version\x00\x06\x00\x00\x004.3.3\x00\x00\x03os\x00`\x00\x00\x00\x02type\x00\x08\x00\x00\x00Windows\x00\x02name\x00\x0b\x00\x00\x00Windows 10\x00\x02architecture\x00\x06\x00\x00\x00AMD64\x00\x02version\x00\x0f\x00\x00\x0010.0.22621-SP0\x00\x00\x02platform\x00\x17\x00\x00\x00CPython 3.10.7.final.0\x00\x00\x00" HTTPStatus.BAD_REQUEST -
이런 에러가 뜹니다... 발표용으로 제작 중인데 원인을 찾아봐도 모르겠어요... 혹시 수정해야 할 부분이 있을까요?
-
글쓴이글
2 글 보임 - 1 에서 2 까지 (총 2 중에서)
- 답변은 로그인 후 가능합니다.