Login

Google Map Field and Widget

Author:
javinievas
Posted:
May 11, 2008
Language:
Python
Version:
.96
Tags:
newforms field widget gmap map google-map
Score:
1 (after 1 ratings)

There is a sample in the code.

You can use this snippet to allow your forms to easily edit object locations.

Take care about what you should add to your templates in order to make it work.

  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
# Sample model
#
#class Sitio(models.Model):
#    nombre = models.CharField(max_length=255)
#    location = models.CharField(max_length=255)
#    
#    class Admin:
#        list_display=('nombre', 'location',)
#
#

# Sample view
#class SitioForm(ModelForm):
#    location = LocationField()
#    class Meta:
#        model = Sitio
#
#def add_sitio(request):
#
#    form = SitioForm({'name':'Nombre','location':u"40.42, -3.7"}) # Default initial values
#    if request.POST:
#        form = SitioForm(request.POST)
#        if form.is_valid():
#            obj = form.save()            
#
#    return render_to_response("test/test.html", {'form':form})

# Sample template
#<html>
#    <head>
#    <script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=ABQIAAAAd7Rv9b8qi3Bs7gc5MlVsLBQCULP4XOMyhPd8d_NrQQEO8sT8XBT5eKFVa3VfRxSsgNQOU8T90yK6Vg" type="text/javascript"></script>  <!-- U Must include this line in order to load google maps api -->
#    </head>
#    <body onload="load_location()"> <!-- U also have to call a load_*field*() for each LocationField in your page, in the sample, the field is called "location", so load_location() have to be called -->
#        <form action="." method="post">
#            {{form}}
#            <input type="submit" />
#        </form>
#</body>
#</html>


from django import newforms as forms

DEFAULT_WIDTH = 500
DEFAULT_HEIGHT = 300

class LocationWidget(forms.widgets.Widget):
    def __init__(self, *args, **kw):
        self.map_width = kw.get("map_width", DEFAULT_WIDTH)
        self.map_height = kw.get("map_height", DEFAULT_HEIGHT)
        
        super(LocationWidget, self).__init__(*args, **kw)
        self.inner_widget = forms.widgets.HiddenInput()

    def render(self, name, value, *args, **kwargs):
        
        if isinstance(value, unicode):
            a, b = value.split(',')
        else:
            a, b = value
        lat, lng = float(a), float(b)
        
        js = '''
<script type="text/javascript">
//<![CDATA[

    var map_%(name)s;
    
    function savePosition_%(name)s(point)
    {
	    var latitude = document.getElementById("id_%(name)s");
	    //var longitude = document.getElementById("id_%(name)s_longitude");
	    latitude.value = point.lat().toFixed(6) + "," + point.lng().toFixed(6);
	    //longitude.value = point.lng().toFixed(6);
        map_%(name)s.panTo(point);
    }

    function load_%(name)s() {
        if (GBrowserIsCompatible()) {
            map_%(name)s = new GMap2(document.getElementById("map_%(name)s"));
            map_%(name)s.addControl(new GSmallMapControl());
            map_%(name)s.addControl(new GMapTypeControl());

            var point = new GLatLng(%(lat)f, %(lng)f);
            map_%(name)s.setCenter(point, 8);
            m = new GMarker(point, {draggable: true});

            GEvent.addListener(m, "dragend", function() {
                    point = m.getPoint();
                    savePosition_%(name)s(point);
            });

            map_%(name)s.addOverlay(m);

            /* save coordinates on clicks */
            GEvent.addListener(map_%(name)s, "click", function (overlay, point) {
                savePosition_%(name)s(point);
            
                map_%(name)s.clearOverlays();
                m = new GMarker(point, {draggable: true});

                GEvent.addListener(m, "dragend", function() {
                    point = m.getPoint();
                    savePosition_%(name)s(point);
                });

                map_%(name)s.addOverlay(m);
            });
        }
    }
//]]>
</script>
        ''' % dict(name=name, lat=lat, lng=lng)
        html = self.inner_widget.render("%s" % name, "%f,%f" % (lat,lng), dict(id='id_%s' % name))
        html += "<div id=\"map_%s\" class=\"gmap\" style=\"width: %dpx; height: %dpx\"></div>" % (name, self.map_width, self.map_height)
        
        return (js+html)


class LocationField(forms.Field):
    widget = LocationWidget

    def clean(self, value):
        if isinstance(value, unicode):
            a, b = value.split(',')
        else:
            a, b = value
            
        lat, lng = float(a), float(b)
        return "%f,%f" % (lat, lng)

More like this

  1. widget to capture a geographic Point by jerojasro 7 years, 5 months ago
  2. Django google maps v3 snipplet by summerisgone 5 years ago
  3. Get Latitude and Longitude from google maps by b23 7 years, 8 months ago
  4. ReST google-map directive. by mucius 2 years, 2 months ago
  5. GoogleAdmin: GMaps base layer in Geographic Admin (GeoDjango) by jbronn 6 years, 9 months ago

Comments

nimshkedy (on July 3, 2013):

Nice. This works. I wish there was a well-documented, complete package for this.

#

Please login first before commenting.