Axione-IPE-Viewer/webapp/main.py
Félix Baylac-Jacqué 38c67ee588 Webapp: add real elig data query
When a acceptable zoom level is reached, the frontend is going to
query the DB for the eligibility data associated to the region the
user is viewing.

When requesting too much data, the frontend gets pretty slow. In order
to prevent that, we require a minimal zoom level before triggering the
actual request.
2022-02-22 14:24:41 +01:00

77 lines
2.5 KiB
Python

from flask import Flask, request, render_template
from typing import TypedDict
import configparser
import sqlite3
import os
class Config(TypedDict):
dbPath: str
def parseConfig() -> Config:
cfg_path = os.environ.get("CONFIG", "/etc/ipe-ftth-elig/conf.ini")
cfg = configparser.ConfigParser()
with open(cfg_path, "r") as f:
cfg.read_file(f)
return {'dbPath':cfg.get("DB","path")}
app = Flask(__name__)
cfg:Config = parseConfig()
@app.route("/", methods=["GET"])
def getMap():
return render_template("map.html")
@app.route("/eligdata", methods=["GET"])
def getEligData():
args = request.args
valid_args = True
processed_args = {}
for k in ['swx', 'swy', 'nex', 'ney']:
valid_args = valid_args and k in args
if valid_args:
try:
processed_args[k] = float(args[k])
except ValueError:
valid_args = False
if valid_args:
cur = cursorWithSpatialite()
# Let's first see how big is the area we're about to query.
# If it's too big, abort the request to prevent a server DOS.
cur.execute('''
SELECT Area(BuildMBR(:swx,:swy,:nex,:ney,4326))
''',processed_args)
req_area = cur.fetchone()[0]
if req_area <= 0.08:
cur.execute('''
SELECT
X(ImmeubleGeoPoint),
Y(ImmeubleGeoPoint),
IdentifiantImmeuble,
EtatImmeuble,
NumeroVoieImmeuble,
TypeVoieImmeuble,
NomVoieImmeuble
FROM ipe
WHERE ROWID IN (
SELECT ROWID FROM SpatialIndex
WHERE f_table_name = 'ipe' AND
search_frame = BuildMBR(:swx, :swy, :nex, :ney, 4326))
''',processed_args)
buildings = [ {
'x':b[0], 'y':b[1], 'idImm':b[2],
'etatImm':b[3], 'numVoieImm': b[4],
'typeVoieImm': b[5], 'nomVoieImm': b[6]
} for b in cur.fetchall()]
return { "buildings": buildings}
else:
return "The requested area is too wide, please reduce it", 400
else:
return "Invalid bounding box coordinates", 400
def cursorWithSpatialite():
db = sqlite3.connect(cfg['dbPath'])
cur = db.cursor()
db.enable_load_extension(True)
cur.execute('SELECT load_extension("mod_spatialite")')
return cur