File size: 5,056 Bytes
8bc50ed
 
 
 
 
 
 
 
a11f31d
 
 
8bc50ed
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
from flask import Flask, request, jsonify, render_template
from models import db, WifiSignal
from datetime import datetime, timedelta
import random
import folium
from folium.plugins import MarkerCluster
from flasgger import Swagger

# Chỉ định đường dẫn instance_path hợp lệ
app = Flask(__name__, instance_path='/tmp')

app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///database.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

# Khởi tạo Swagger
swagger = Swagger(app)

db.init_app(app)

@app.route('/api/generate-data', methods=['POST'])
def generate_data():
    """
    Generate demo data.
    ---
    tags:
      - Data Management
    responses:
      201:
        description: Demo data generated successfully
    """
    base_latitude = 35.6837
    base_longitude = 139.6805
    start_date = datetime(2024, 8, 1)
    end_date = datetime(2024, 8, 7)
    delta = end_date - start_date

    for _ in range(100):
        random_days = random.randint(0, delta.days)
        random_seconds = random.randint(0, 86400)
        random_time = start_date + timedelta(days=random_days, seconds=random_seconds)

        random_latitude = base_latitude + random.uniform(-0.01, 0.01)
        random_longitude = base_longitude + random.uniform(-0.01, 0.01)
        random_signal_strength = random.randint(10, 50)

        wifi_signal = WifiSignal(
            latitude=random_latitude,
            longitude=random_longitude,
            timestamp=random_time,
            signal_strength=random_signal_strength
        )

        db.session.add(wifi_signal)

    db.session.commit()
    return jsonify({"message": "Demo data generated successfully"}), 201

@app.route('/api/delete-data', methods=['DELETE'])
def delete_data():
    """
    Delete all data in the database.
    ---
    tags:
      - Data Management
    responses:
      200:
        description: All data deleted successfully
      500:
        description: An error occurred
    """
    try:
        num_rows_deleted = db.session.query(WifiSignal).delete()
        db.session.commit()
        return jsonify({"message": f"Deleted {num_rows_deleted} rows from the database."}), 200
    except Exception as e:
        db.session.rollback()
        return jsonify({"message": f"An error occurred: {str(e)}"}), 500

@app.route('/api/upload', methods=['POST'])
def upload_data():
    """
    Upload WiFi signal data.
    ---
    tags:
      - Data Management
    parameters:
      - name: body
        in: body
        required: true
        schema:
          type: object
          properties:
            latitude:
              type: number
              example: 35.6895
            longitude:
              type: number
              example: 139.6917
            timestamp:
              type: string
              example: "2024-08-29 14:30:00"
            signal_strength:
              type: integer
              example: 42
    responses:
      201:
        description: Data uploaded successfully
      400:
        description: Invalid input
    """
    data = request.json
    latitude = data.get('latitude')
    longitude = data.get('longitude')
    timestamp = datetime.strptime(data.get('timestamp'), '%Y-%m-%d %H:%M:%S')
    signal_strength = data.get('signal_strength')
    
    wifi_signal = WifiSignal(latitude=latitude, longitude=longitude, timestamp=timestamp, signal_strength=signal_strength)
    db.session.add(wifi_signal)
    db.session.commit()
    
    return jsonify({"message": "Data uploaded successfully"}), 201

@app.route('/', methods=['GET'])
def show_map():
    start_date = request.args.get('start_date')
    end_date = request.args.get('end_date')

    query = WifiSignal.query

    if start_date and end_date:
        start_datetime = datetime.strptime(start_date, '%Y-%m-%d')
        end_datetime = datetime.strptime(end_date, '%Y-%m-%d')
        query = query.filter(WifiSignal.timestamp >= start_datetime, WifiSignal.timestamp <= end_datetime)

    signals = query.all()
    signal_data = [(signal.latitude, signal.longitude, signal.signal_strength) for signal in signals]

    if signal_data:
        min_signal = min(s[2] for s in signal_data)
        max_signal = max(s[2] for s in signal_data)
    else:
        min_signal = max_signal = 1

    m = folium.Map(location=[35.6837, 139.6805], zoom_start=12)
    marker_cluster = MarkerCluster().add_to(m)

    for lat, lon, signal_strength in signal_data:
        if max_signal - min_signal != 0:
            radius = 5 + 10 * ((signal_strength - min_signal) / (max_signal - min_signal))
        else:
            radius = 15
        folium.CircleMarker(
            location=[lat, lon],
            radius=radius,
            popup=f'Signal Strength: {signal_strength}',
            color='blue',
            fill=True,
            fill_opacity=0.6
        ).add_to(marker_cluster)
    
    map_html = m._repr_html_()
    return render_template('map.html', map_html=map_html)

if __name__ == '__main__':
    with app.app_context():
        db.create_all()
    app.run(debug=True)