From cbc87c7c82b6ca171ae99b3858302bf1a5edffb7 Mon Sep 17 00:00:00 2001 From: Lukas Winkler Date: Mon, 3 Oct 2016 16:16:09 +0200 Subject: [PATCH] Server --- abfragen.sql | 5 ++- nearest.py | 1 + server.py | 92 ++++++++++++++++++++++++++++++++++++++++++ www/map.html | 110 +++++++++++++++++++++++++++++++++++---------------- 4 files changed, 173 insertions(+), 35 deletions(-) create mode 100644 server.py diff --git a/abfragen.sql b/abfragen.sql index 3de5566..552859f 100644 --- a/abfragen.sql +++ b/abfragen.sql @@ -8,6 +8,8 @@ SELECT FROM connections LEFT JOIN stationen AS s ON start = s.ref LEFT JOIN stationen AS g ON goal = g.ref + +WHERE start != goal ORDER BY length ASC; # Suche nach Namen @@ -36,6 +38,7 @@ FROM (SELECT ref FROM connections LEFT JOIN stationen ON (start = ref OR goal = ref) + WHERE start != goal ORDER BY length ASC) AS x GROUP BY ref -ORDER BY length ASC \ No newline at end of file +ORDER BY length DESC \ No newline at end of file diff --git a/nearest.py b/nearest.py index 72d83b6..a1f9546 100755 --- a/nearest.py +++ b/nearest.py @@ -41,6 +41,7 @@ LIMIT {limit} feature["properties"]["nodes"] = [way[1], way[2]] feature["properties"]["id"] = way[0] feature["properties"]["wayLength"] = way[3] + feature["properties"]["nearest"] = True geojsonFeatures.append(feature) else: print(str(way[0]) + ": Dup") diff --git a/server.py b/server.py new file mode 100644 index 0000000..a159df5 --- /dev/null +++ b/server.py @@ -0,0 +1,92 @@ +#!/usr/bin/env python3 +import json +import subprocess + +import MySQLdb +from flask import Flask +from flask import abort +from flask import jsonify +from flask import make_response +from flask import redirect +from flask import request +from flask import send_file +from flask import send_from_directory +from flask import url_for + +from config import database + +db = MySQLdb.connect(database["host"], + database["user"], + database["passwd"], + database["db"]) +cur = db.cursor() + +app = Flask(__name__) +app.config.update( + JSONIFY_PRETTYPRINT_REGULAR=False +) + + +@app.route('/api/connection/', methods=["GET"]) +def hello_world(): + if not request.args \ + or 'from' not in request.args or 'to' not in request.args \ + or not request.args["from"].isdigit() or not request.args["to"].isdigit(): + abort(400) + cur.execute("SELECT id FROM connections WHERE start = %s AND goal = %s", [request.args["from"], request.args["to"]]) + result = cur.fetchone() + return redirect(url_for("get_connection", connection_id=int(result[0]))) + + +@app.route('/api/connection/', methods=['GET']) +def get_connection(connection_id): + try: + print("HIT") + with open("file/" + str(connection_id) + ".json") as f: + data = json.load(f) + return jsonify(data) + + except EnvironmentError: + print("MISS") + cur.execute("SELECT start, goal, length FROM connections WHERE id=%s", [connection_id]) + result = cur.fetchone() + geojson = [] + try: + geojsonstring = subprocess.check_output(["togeojson", "file/" + str(connection_id) + ".gpx"]).decode( + 'UTF-8') + geojson = json.loads(geojsonstring) + feature = geojson["features"][0] + del feature["properties"]["desc"], feature["properties"]["name"] # Überreste von GPX entfernen + feature["properties"]["wayLength"] = result[2] + feature["properties"]["nodes"] = [result[0], result[1]] + feature["properties"]["id"] = connection_id + geojson["features"][0] = feature + with open("file/" + str(connection_id) + ".json", 'w') as outfile: + json.dump(geojson, outfile, indent=4) + except subprocess.CalledProcessError: + abort(404) + return jsonify(geojson) + + +@app.route('/') +def send_main_html(): + return send_file('www/map.html') + + +@app.route('/') +def send_static(path): + return send_from_directory('www', path) + + +@app.errorhandler(404) +def not_found(error): + return make_response(jsonify({'error': str(error)}), 404) + + +@app.errorhandler(400) +def bad_request(error): + return make_response(jsonify({'error': str(error)}), 400) + + +if __name__ == "__main__": + app.run(debug=True) diff --git a/www/map.html b/www/map.html index 9c3787e..5c68ee0 100644 --- a/www/map.html +++ b/www/map.html @@ -15,7 +15,7 @@ height: 100%; } - #search { + .leaflet-control-custom { pointer-events: auto; } @@ -26,6 +26,13 @@ .leaflet-popup-content { font-size: medium; } + + .clearButton { + width: 10%; + background-color: white; + display: inline-block; + cursor: pointer; + } @@ -71,14 +78,6 @@ } }); - $.ajax({ - dataType: "json", - url: "nearest.json", - success: function (data) { - lines.addData(data); - lines.addTo(map); - } - }); var stations = {}; var stationLayer = L.geoJson(null, { @@ -86,12 +85,8 @@ return L.marker(latlng, {icon: new citybikeIcon()}); }, onEachFeature: function (feature, layer) { -// layer._leaflet_id = feature.properties.ref; -// console.log(feature.properties.ref); -// console.log(feature.properties); - stations[feature.properties.ref] = feature.properties.name; + stations[feature.properties.ref] = {name: feature.properties.name, leafletId: L.stamp(layer)}; layer.bindPopup(feature.properties.name); - layer._leaflet_id = 10000 + feature.properties.ref; layer.on({ //Icons beim hover verdunkeln mouseover: function (e) { layer.setIcon(new altCitybikeIcon()); @@ -105,16 +100,6 @@ } }); - $.ajax({ - dataType: "json", - url: "stationLayer.json", - success: function (data) { - stationLayer.addData(data); - stationLayer.addTo(map); - map.fitBounds(stationLayer.getBounds()); - } - }); - function onEachFeature(feature, layer) { layer.on({ mouseover: function (e) { @@ -126,32 +111,68 @@ if (!L.Browser.ie && !L.Browser.opera) { layer.bringToFront(); } - stationLayer.getLayer(10000 + layer.nodes[0]).setIcon(new altCitybikeIcon()); - stationLayer.getLayer(10000 + layer.nodes[1]).setIcon(new altCitybikeIcon()); + stationLayer.getLayer(stations[layer.nodes[0]]["leafletId"]).setIcon(new altCitybikeIcon()); + stationLayer.getLayer(stations[layer.nodes[1]]["leafletId"]).setIcon(new altCitybikeIcon()); }, mouseout: function (e) { lines.resetStyle(e.target); - stationLayer.getLayer(10000 + layer.nodes[0]).setIcon(new citybikeIcon()); - stationLayer.getLayer(10000 + layer.nodes[1]).setIcon(new citybikeIcon()); + if (!feature.properties.nearest) { + layer.setStyle({ + weight: 10, + color: '#E82C0C' + }); + } + stationLayer.getLayer(stations[layer.nodes[0]]["leafletId"]).setIcon(new citybikeIcon()); + stationLayer.getLayer(stations[layer.nodes[1]]["leafletId"]).setIcon(new citybikeIcon()); } }); } - + var linesArray = {}; var lines = L.geoJson(null, { onEachFeature: function (feature, layer) { - var popupText = stations[feature.properties.nodes[0]] + " ⟷ " + stations[feature.properties.nodes[1]] + "
" + + var popupText = stations[feature.properties.nodes[0]]["name"] + + " ⟷ " + stations[feature.properties.nodes[1]]["name"] + + "
" + feature.properties.wayLength / 1000 + " km"; layer.bindPopup(popupText); + linesArray[feature.properties.id] = {leafletId: L.stamp(layer)}; + + if (!feature.properties.nearest) { + layer.setStyle({ + weight: 10, + color: '#E82C0C' + }); + } onEachFeature(feature, layer); layer.nodes = feature.properties.nodes; -// layer._leaflet_id = feature.properties.id; }, style: { weight: 5 } }); + + $.ajax({ + dataType: "json", + url: "stationLayer.json", + success: function (data) { + stationLayer.addData(data); + stationLayer.addTo(map); + map.fitBounds(stationLayer.getBounds()); + $.ajax({ + dataType: "json", + url: "nearest.json", + success: function (data) { + lines.addData(data); + lines.addTo(map); + console.log(linesArray); + } + }); + } + }); + + lines.getAttribution = function () { return "Routing mit Routino"; }; @@ -177,12 +198,15 @@ onAdd: function (map) { var container = L.DomUtil.create('div', 'leaflet-bar leaflet-control leaflet-control-custom'); - container.style.backgroundColor = 'white'; container.style.width = '50vw'; var select1 = L.DomUtil.create("select", 'stationSelect', container); var select2 = L.DomUtil.create("select", 'stationSelect', container); - select1.style.width = "50%"; - select2.style.width = "50%"; + var clearButton = L.DomUtil.create("div", 'clearButton', container); + select1.style.width = "45%"; + select2.style.width = "45%"; + clearButton.style.width = "10%"; + clearButton.textContent = "Clear"; + select1.appendChild(new Option); select2.appendChild(new Option); return container; @@ -201,6 +225,24 @@ return false; } console.info(fromId + "->" + toId); + $.getJSON("http://127.0.0.1:5000/api/connection/", { + from: fromId, + to: toId + }).done(function (data) { + + lines.addData(data); + + }); + $(".clearButton").on("click", function () { + var allLines = lines.getLayers(); + for (i = 1; i < allLines.length; i++) { + var currentLine = allLines[i]; + if (!currentLine.feature.properties.nearest) { + lines.removeLayer(currentLine); + } + } + } + ) })