2017-01-07 9 views
-1

FlaskとGoogle Maps Directions APIを使用してWebアプリケーションを作成しています。ここで出発地、経由地、目的地を入力してGoogleに渡してもらいますユーザーのルートを示すマップをレンダリングするAPI。ただし、これらのデータポイントが何であっても、APIは3つのデータポイントをすべて1つの場所として解釈し、それに従ってマップをレンダリングします。レンダリングされたマップは hereであり、このアドレスが間違っていることもわかります。Google Maps Directions API不適切なルートを計算する

次のように関連するソースファイルは、次のとおりです。(私は「/ finalize_new_trip」ルートでGoogleマップをレンダリングするために私のテンプレートを呼び出す) run.py:使用

from os.path import abspath, dirname, join 
from flask import flash, Flask, Markup, redirect, render_template, url_for, request 
from flask.ext.sqlalchemy import SQLAlchemy 

from flask_wtf import FlaskForm 
from wtforms import StringField 
from wtforms.validators import DataRequired 

import os 
import googlemaps 
from datetime import datetime 
import json 

_cwd = dirname(abspath(__file__)) 

SECRET_KEY = 'flask-session-insecure-secret-key' 
SQLALCHEMY_DATABASE_URI = 'sqlite:///' + join(_cwd, 'TripLogger.db') 
SQLALCHEMY_ECHO = True 
WTF_CSRF_SECRET_KEY = 'this-should-be-more-random' #TODO: RANDOMIZE THIS KEY 


app = Flask(__name__) 
app.config.from_object(__name__) 

db = SQLAlchemy(app) 

class Trip(db.Model): 
    __tablename__ = 'trips' 

    id = db.Column(db.Integer, primary_key=True) 
    trip_name = db.Column(db.String, unique=True) 
    origin = db.Column(db.String) 
    destination = db.Column(db.String) 
    waypoints = db.Column(db.String) #SEE IF ANOTHER DATA TYPE IS BETTER- IDEALLY WANT TO STORE LIST OF STRINGS 

    def __init__(self, trip_name, origin, destination, waypoints): 
     self.trip_name = trip_name 
     self.origin = origin 
     self.destination = destination 
     self.waypoints = waypoints 

    def __repr__(self): 
     return '<Trip %r(name = %r, origin = %r, destination = %r)>' % (self.id, self.trip_name, self.origin, self.destination) 

    def __str__(self): 
     return self.trip_name 

#CONSIDER CUSTOM VALIDATORS TO ENSURE THAT TRIP_NAME IS UNIQUE FOR A SPECIFIC USER/ACCOUNT 
class TripForm(FlaskForm): 
    trip_name = StringField('Trip Name', validators=[DataRequired()]) 
    origin = StringField('Origin', validators=[DataRequired()]) 
    destination = StringField('Destination', validators=[DataRequired()]) 
    waypoints = StringField('Waypoint') 

@app.route("/", methods = ["GET", "POST"]) 
def index(): 
    trip_form = TripForm(request.form) 
    if trip_form.validate_on_submit(): 
     flash("Submitted new trip form, now redirecting to /finalize_new_trip to render map...") 
     return redirect(url_for("complete_trip", trip_name = trip_form.trip_name.data, origin = trip_form.origin.data, destination = trip_form.destination.data, waypoints = trip_form.waypoints.data)) 
    return render_template("index.html", trip_form = trip_form) 

# Route to display trip on map (in future, to modify trip details, e.g. waypoints) 
@app.route("/finalize_new_trip", methods=["POST"]) 
def complete_trip(): 
    return render_template("finish_new_trip.html", trip_name = request.args.get("trip_name"), origin = request.args.get("origin"), destination = request.args.get("destination"), waypoints = request.args.get("waypoints")) 

# Store new trip data in database 
@app.route("/store_trip", methods=["POST"]) 
def store_trip(): 
    trip_data = request.form("trip_data") 
    return json.loads(trip_data)[0] 

def query_to_list(query, include_field_names=True): 
    """Turns a SQLAlchemy query into a list of data values.""" 
    column_names = [] 
    for i, obj in enumerate(query.all()): 
     if i == 0: 
      column_names = [c.name for c in obj.__table__.columns] 
      if include_field_names: 
       yield column_names 
     yield obj_to_list(obj, column_names) 


def obj_to_list(sa_obj, field_order): 
    """Takes a SQLAlchemy object - returns a list of all its data""" 
    return [getattr(sa_obj, field_name, None) for field_name in field_order] 

if __name__ == "__main__": 
    app.debug = True 
    db.create_all() 
    app.run() 

finish_new_trip.html(テンプレートを地図をレンダリングするGoogleマップAPI):私はローカルに自分のアプリケーションをテストする場合

<!DOCTYPE html> 
<html> 
    <head> 
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no"> 
    <meta charset="utf-8"> 
    <script async defer 
    src="https://maps.googleapis.com/maps/api/js?v=3.exp&key=<MY_API_KEY>&callback=getOriginCoordinates" type="text/javascript"> 
    </script> 
    <title>Finish New Trip</title> 
    </head> 
    <body> 
    <div id="trip_name"> 
     <h1> {{ trip_name }} </h1> 
    </div> 
    <div id="map"></div> 
    <div id="right-panel"> 
    <div> 
     <form> 
     <input type="submit" id="finish-new-trip-button" value="Add My Trip!"> 
     </form> 
    </div> 
    <div id="directions-panel"></div> 
    </div> 

    <script> 
     //Wrapper function to AJAX POST request that passes data back to server. 
     /*function passTripData() { 
     document.getElementById("finish-new-trip-button").onclick = function() { 
      // Retrieve data from displayed map (after user makes changes) after testing 
      $.post("{{ url_for('store_trip') }}", { 
      trip_data: { 
       "trip_name": "{{ trip_name }}", 
       "origin": "{{ origin }}", 
       "destination": "{{ destination }}", 
       "waypoints": [ 
       "{{ waypoints }}" 
       ] 
      } 
      }); 
     } 
     }*/ 

     //Use Geocoding API to get coordinates for origin, destination, and waypoints. 
     function getOriginCoordinates() { 
     //passTripData(); // function that sets onClick event for "Submit" button 
     var geocoder = new google.maps.Geocoder(); 
     geocoder.geocode({ 'address': "{{ origin }}"}, function(results, status) { 
      if (status == 'OK') { 
      originCoordinates = results[0].geometry.location; 
      console.log("Origin coords: " + "lat = " + originCoordinates.lat() + ", lng = " + originCoordinates.lng()); 
      getDestCoordinates(originCoordinates); 
      } else { 
      alert('Geocode of origin was not successful for the following reason: ' + status); 
      } 
     }); 
     } 
     function getDestCoordinates(originCoords) { 
     var geocoder = new google.maps.Geocoder(); 
     geocoder.geocode({ 'address': "{{ destination }}"}, function(results, status) { 
      if (status == 'OK') { 
      destCoordinates = results[0].geometry.location; 
      console.log("Dest coords: " + "lat = " + destCoordinates.lat() + ", lng = " + destCoordinates.lng()); 
      getWaypointCoordinates(originCoords, destCoordinates); 
      } else { 
      alert('Geocode of destination was not successful for the following reason: ' + status); 
      } 
     }); 
     } 
     function getWaypointCoordinates(originCoords, destCoords) { 
     var geocoder = new google.maps.Geocoder(); 
     geocoder.geocode({ 'address': "{{ waypoints }}"}, function(results, status) { 
      if (status == 'OK') { 
      waypointCoordinates = results[0].geometry.location; 
      console.log("Waypoint coords: " + "lat = " + waypointCoordinates.lat() + ", lng = " + waypointCoordinates.lng()); 
      initMap(originCoords, destCoords, waypointCoordinates); 
      } else { 
      alert('Geocode of waypoints was not successful for the following reason: ' + status); 
      } 
     }); 
     } 

     function initMap(originCoords, destCoords, waypointCoords) { 
     var directionsService = new google.maps.DirectionsService; 
     var directionsDisplay = new google.maps.DirectionsRenderer; 

     //Center map between origin and destination. 
     //TEST LATLNG OBJECTS FIRST 
     console.log("Origin: lat=" + originCoords.lat() + ", lng=" + originCoords.lng()); 
     console.log("Destination: lat=" + destCoords.lat() + ", lng=" + destCoords.lng()); 

     var mapLatitudeCenter = (originCoords.lat() + destCoords.lat())/2; 
     var mapLongitudeCenter = (originCoords.lng() + destCoords.lng())/2; 

     var map = new google.maps.Map(document.getElementById('map'), { 
      zoom: 6, 
      center: {lat: mapLatitudeCenter, lng: mapLongitudeCenter} 
     }); 
     directionsDisplay.setMap(map); 

     calculateAndDisplayRoute(directionsService, directionsDisplay, originCoords, destCoords, waypointCoords); 
     } 

     function calculateAndDisplayRoute(directionsService, directionsDisplay, originCoords, destCoords, waypointCoords) { 
     var waypts = []; 
     waypts.push({ 
      location: waypointCoords, 
      stopover: true 
     }); 

     directionsService.route({ 
      origin: originCoords, 
      destination: destCoords, 
      waypoints: waypts, 
      optimizeWaypoints: true, 
      travelMode: 'DRIVING' 
     }, function(response, status) { 
      if (status === 'OK') { 
      directionsDisplay.setDirections(response); 
      var route = response.routes[0]; 
      var summaryPanel = document.getElementById('directions-panel'); 
      summaryPanel.innerHTML = ''; 
      // For each route, display summary information. 
      for (var i = 0; i < route.legs.length; i++) { 
       var routeSegment = i + 1; 
       summaryPanel.innerHTML += '<b>Route Segment: ' + routeSegment + 
        '</b><br>'; 
       summaryPanel.innerHTML += route.legs[i].start_address + ' to '; 
       summaryPanel.innerHTML += route.legs[i].end_address + '<br>'; 
       summaryPanel.innerHTML += route.legs[i].distance.text + '<br><br>'; 
      } 
      } else { 
      window.alert('Directions request failed due to ' + status); 
      } 
     }); 
     } 
    </script> 
    </body> 
</html> 

、コンソールは、各データポイントの緯度/経度座標(原点、宛先、及びウェイポイント)を表示し、それらはすべてに対応このイタリアの住所は間違っています。私は以前にも "404"というエラーメッセージを受け取りましたが、今はそれを受け取っていません。

APIキーを再生成しようとしましたが、この新しいキーを使用しましたが、これで問題は解決されませんでした。この問題を解決するにはどうすればよいですか?

答えて

0

私は

@app.route("/finalize_new_trip", methods=["GET"]) 
def complete_trip(): 
    return render_template("finish_new_trip.html", trip_name ='new trip', origin='new york, ny', destination='los angeles, california', waypoints='topeka, kansas') 

complete_trip():を変更し、ページを要求すると、結果は(トピーカを通過NYからLAへの旅)に最適です。あなたはどこにでもコメントされたコードをたくさん持っています。私はあなたが期待しているデータを取得していないと感じています(たとえば、このデータを投稿するために使用されたHTML形式は見えません)。

+0

提案していただきありがとうございます。私はあなたの方法をチェックし、手動でこれらのアドレスを入力しても私のために働いた。このエンドポイントのGETリクエストを変更し、ルートURLを更新してパラメータを次のように変更することで解決しました。 '@app.route("/finalize_new_trip//// "、methods = [" GET "]))と私のAPIリクエストは現在動作しています。 –

+0

参考のため、私のフォームHTMLテンプレートは次のとおりです。{%extend "layout.html"%} {%import "helpers/forms.html"フォーム}% {%block title%} TripLoggerへようこそ! {%endblock%} {%ブロックのコンテンツ%} {{super()}}

新しい旅行を計画していますか?

以下の基本情報を入力してください。

<フォームアクション= "{{なurl_for( 'インデックス')}}" METHOD = "POST"> \t
\t \t \t \t {{forms.render(trip_form)}} 新しい旅行を作成します\t \t

\t
{%の末端ブロック含有量%} ' –

関連する問題