-2

I have a page which shows a map using Google Maps API (so it uses the Flask Google Maps extension). I load this page on my endpoint using the following call:

return render_template('example.html', mymap=mymap)

mymap is a Google Maps map object written in Python containing parameters for rendering the map (such as markers etc). I need to have this page check the database to see if any new entries have been added (since this is where it gets data for the mymap from). Something like

while True:
     # Wait some time
     # Check database and add to markers list any new entries
     # Render template with new markers
     render_template('example.html', mymap=mymap)

I have been told this isnt the best way to do it, and that render_template needs to be used with a return statement. What would be the best approach to this? At the moment, here is the html file where stuff from mymap goes (to render the page):

<script src="http://maps.googleapis.com/maps/api/js?sensor=false" type="text/javascript"></script>

<style type="text/css">
      #{{gmap.identifier}} { {{gmap.style}} }
</style>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.7/angular.min.js"></script>
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false&libraries=drawing"></script>
<script type="text/javascript">
    function initialize_googleMap() {
        var googleMap = new google.maps.Map(
        document.getElementById('{{gmap.identifier}}'), {
            center: new google.maps.LatLng({{gmap.center.0}}, {{gmap.center.1}}),
            zoom: {{gmap.zoom}},
            mapTypeId: google.maps.MapTypeId.{{gmap.maptype}}
        });

    var infoWindow = new google.maps.InfoWindow({
        content: "loading..."
    });


        {% for marker in gmap.markers %}

            var marker_{{loop.counter}} = new google.maps.Marker({
                position: new google.maps.LatLng({{marker.0}}, {{marker.1}}),
                map: googleMap,
                title: '{{marker.2}}',
                icon: '{{marker.3}}',
            });


            google.maps.event.addListener(marker_{{loop.counter}}, 'click', function() {
                infoWindow.setContent("{{marker.4|safe}}");
                infoWindow.open(googleMap, this);
            });
            google.maps.event.addListener(marker_{{loop.counter}}, 'rightclick', function() {

                $(this).w2overlay('Hello');
            });
        {% endfor %}

        {% for polyline in gmap.polylines %}
            var polylineCoordinates = [];

            {% for point in polyline.coordinates %}
                polylineCoordinates.push(new google.maps.LatLng({{point.0}}, {{point.1}}))
            {% endfor %}

            var polylinePath = new google.maps.Polyline({
                path: polylineCoordinates,
                geodesic: true,
                strokeColor: '{{polyline.stroke_color}}',
                strokeOpacity: '{{polyline.stroke_opacity}}',
                strokeWeight: '{{polyline.stroke_weight}}'
            });

            polylinePath.setMap(googleMap);
        {% endfor %}

        {% for polygon in gmap.polygons %}
            var polygonCoordinates = [];

            {% for point in polygon.coordinates %}
                polygonCoordinates.push(new google.maps.LatLng({{point.0}}, {{point.1}}))
            {% endfor %}

            var polygonPath = new google.maps.Polygon({
                path: polygonCoordinates,
                strokeColor: '{{polygon.stroke_color}}',
                strokeOpacity: '{{polygon.stroke_opacity}}',
                strokeWeight: '{{polygon.stroke_weight}}',
                fillColor: '{{polygon.fill_color}}',
                fillOpacity: '{{polygon.fill_opacity}}'
            });

            polygonPath.setMap(googleMap);
        {% endfor %}

        {% for circle in gmap.circles %}
            var circleCenter = new google.maps.LatLng({{circle.center.0}}, {{circle.center.1}});

            var gCircle = new google.maps.Circle({
                strokeColor: '{{circle.stroke_color}}',
                strokeOpacity: '{{circle.stroke_opacity}}',
                strokeWeight: '{{circle.stroke_weight}}',
                fillColor: '{{circle.fill_color}}',
                fillOpacity: '{{circle.fill_opacity}}',
                center: circleCenter,
                radius: {{circle.radius}}
            });

            gCircle.setMap(googleMap);
        {% endfor %}

        {% for rectangle in gmap.rectangles %}
            var gRectangle = new google.maps.Rectangle({
                strokeColor: '{{rectangle.stroke_color}}',
                strokeOpacity: '{{rectangle.stroke_opacity}}',
                strokeWeight: '{{rectangle.stroke_weight}}',
                fillColor: '{{rectangle.fill_color}}',
                fillOpacity: '{{rectangle.fill_opacity}}',
                bounds: new google.maps.LatLngBounds(
                    new google.maps.LatLng({{rectangle.bounds.0.0}}, {{rectangle.bounds.0.1}}),
                    new google.maps.LatLng({{rectangle.bounds.1.0}}, {{rectangle.bounds.1.1}}))
                });

            gRectangle.setMap(googleMap);
        {% endfor %}

        if('{{gmap.drawing}}' == "True") {
            var drawingManager = new google.maps.drawing.DrawingManager({
            drawingMode: google.maps.drawing.OverlayType.MARKER,
            drawingControl: true,
            drawingControlOptions: {
              position: google.maps.ControlPosition.TOP_CENTER,
              drawingModes: [
                google.maps.drawing.OverlayType.MARKER,
                google.maps.drawing.OverlayType.CIRCLE,
                google.maps.drawing.OverlayType.POLYGON,
                google.maps.drawing.OverlayType.POLYLINE,
                google.maps.drawing.OverlayType.RECTANGLE
              ]
            },
            circleOptions: {
              fillColor: '#ffff00',
              fillOpacity: 1,
              strokeWeight: 5,
              clickable: false,
              editable: true,
              zIndex: 1
            }
          });
          drawingManager.setMap(googleMap);
        }

        if (navigator.geolocation) {
            var container = document.createElement('div');
            var homeControl = new BuildHomeControl(container);

            container.index = 1;
            googleMap.controls[google.maps.ControlPosition.RIGHT_TOP].push(container);

            google.maps.event.addDomListener(container, 'click', function() {
                navigator.geolocation.getCurrentPosition(function(position) {
                    var coordinates = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
                    googleMap.setCenter(coordinates);
                });
            });
        }
    }

    function BuildHomeControl(container) {
          container.style.padding = '2px';

          var img = document.createElement('img');
          img.title = 'Click to set the map to Home';
          container.appendChild(img);
          img.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAB8klEQVR4Xu3XPWgTYRgA4Lug9QetFm1RqL8d0uIfSJwcOiiog4oi/oB0FAQRFxE6ODg6agehUMQiok62IO2iVmnXoIvNJEglSkstBYnWNOczHhnSpBfoYF54eLn7+N7vve+4uySMoihYyUjxfzfQaKDRwCpqjjAMm6U0W1gkT84j/bfmWibVsvBO6Qbn6YgNLfCJJwyo+avut8DiZ6VxbtPBHAUWKJLhAaMa7axrAwqekZ7RzmeucZAJPnKYXvIcZcicvVV1YLsqErvJEzFEa2zsOa9jx51kiRihaYn6Ve3ATbaRpcek6djYdXpiFzMpXeYHJziV6BbYxhbpAhH3LDBXtnuzzJSdy0l9BFxN1ACd7OALo1QbL/nDERexIUkDbQS0MKzYK1or7Fg7Yw6ekqKZTUkaKBGwnn2kWc1SEcVyKUkDU5T4xiEyfK/wRE3R7eAiRab5meRVPEmONPsVfxNUF6dZx3tzfi97B0wuSAOkuOv+rim759tDys9JtyjyuB5vwn6ydNNngbWxsRcgMNYmDbKHfhcwUZePkcIHpGF2McZ9xnlHyHFO0ksXI1xSez5pA/EmuqSHHCPgK1tJMU8bAY+4E1u8rp/jJukcV8iwkRIzvGVQvQ81/x5I8KNkM4vMqlNYVp3GHxNWNBoNNBr4B2Hh6BuKnV6nAAAAAElFTkSuQmCC';
    }

    google.maps.event.addDomListener(window, 'load', initialize_googleMap);
</script>
user1397215
  • 321
  • 1
  • 6
  • 18
  • You could write an additional view function that returns just the map portion of your site and call it from the front end with js/jquery. The call to render template will require the entire page to be refreshed. – Maarten Aug 20 '15 at 10:38
  • @Maarten, how would I do that? – user1397215 Aug 20 '15 at 22:31
  • 2
    force the page to reload every so many minutes (in the html) ? or use ajax see http://stackoverflow.com/questions/8470431/what-is-the-best-way-to-implement-a-forced-page-refresh-using-flask?rq=1 – lxx Aug 23 '15 at 06:15

1 Answers1

2

One possible solution is to generate your map content in a separate Flask view, and display this in your page within an iframe. You can have the iframe content refresh itself periodically.

Here's a simple example illustrating this solution.

app.py

# coding: utf-8

from flask import Flask, render_template
from flask.ext.googlemaps import GoogleMaps
from flask.ext.googlemaps import Map
import random

app = Flask(__name__, template_folder=".")
GoogleMaps(app)

@app.route("/")
def index():
    return render_template('index.html')

@app.route("/map")
def map():

    lat = -31.9572891
    long = 115.8559911

    points = [
        {"lat": -31.958988, "long": 115.858176},
        {"lat": -31.954946, "long": 115.866976},
        {"lat": -31.952037, "long": 115.851682},
        {"lat": -31.951573, "long": 115.858570}
    ]

    [a,b] = random.sample(range(0,3),2)

    mymap = Map(
        identifier="mymap",
        lat=lat,
        lng=long,
        markers={'http://maps.google.com/mapfiles/ms/icons/green-dot.png':[(points[a]['lat'], points[a]['long'])],
                 'http://maps.google.com/mapfiles/ms/icons/blue-dot.png':[(points[b]['lat'], points[b]['long'])]}
    )
    return render_template('map.html', mymap=mymap)

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

index.html

<!DOCTYPE html>
    <html>
    <head>
            <meta charset="utf-8">
            <meta http-equiv="X-UA-Compatible" content="IE=edge">
            <title>Flask Google Maps Example</title>
    </head>
    <body>
        <h1>Flask Google Maps</h1>

        <iframe src="{{ url_for('map') }}" frameborder="0" width="600" height="600"></iframe>

    </body>
</html>

map.html

<!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta http-equiv="refresh" content="5">
        <title>Flask Google Maps Example</title>
        {{mymap.js}}
    </head>
    <body>
        {{mymap.html}}
    </body>
</html>
Matt Healy
  • 18,033
  • 4
  • 56
  • 56