map

Differences between revisions 1 and 23 (spanning 22 versions)
Revision 1 as of 2011-01-17 13:59:40
Size: 5156
Editor: ip5456cf16
Comment:
Revision 23 as of 2011-01-21 13:07:26
Size: 12862
Editor: ip5456cf16
Comment:
Deletions are marked like this. Additions are marked like this.
Line 3: Line 3:
Blueprint: [[https://blueprints.launchpad.net/ubuntu-django-foundations/+spec/maps-jquery-plugin]]

Download: [[attachment:jquery-ubuntu-maps-0.2.1.js]]

Required js libraries:
 * jQuery
 * jquery-tmpl (only if templates are used)
 * Google maps
 * markerclusterer
{{{
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
    <script type="text/javascript" src="https://github.com/jquery/jquery-tmpl/raw/master/jquery.tmpl.min.js"></script>
    <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false&language=en&region=US"></script>
    <script type="text/javascript" src="http://google-maps-utility-library-v3.googlecode.com/svn/tags/markerclusterer/1.0/src/markerclusterer_packed.js"></script>
}}}

||<<TableOfContents()>>||
Line 4: Line 22:
 * $('map-element').selectLocation({params})
 * $('map-element').showLocations({params})
{{{
$('map-element').selectLocation({ params })
$('map-element').showLocations({ params })
}}}
Line 11: Line 31:
There are 3 methods to add/move a marker on the map

There are 3 methods to add/move a marker on the map:
Line 17: Line 37:
=== Possible parameters ===

----
=== html_lng ===
''The HTML <input> element that represents the longitude of the marker e.g.''

'''Examples'''
 * $('#id_lng')
 * $('#id_longitude')

'''Default'''

null (maybe change this to '#id_lng')

'''Specification'''
 * If the inputs already contains data, put the marker on the map at init
 * In the data in the inputs is changed, move the marker and center the map at the marker
 * If the marker is moved, change the values in these input elements accourdingly
 * If the inputs are made empty, remove the marker

----
=== html_lat ===
''Same as html_lng but this one is for the latitude''
----
=== html_lat and html_lng ===
''The HTML <input> element that represents the latitude and longitude of the marker e.g.''

'''Default'''

{{{
null
}}}
''maybe change this to `#id_lng` ''

'''Example'''

HTML
{{{
<input type="text" id="id_lat" name="lat" value="0.353452" />
<input type="text" id="id_lng" name="lng" value="0.435323" />
}}}
Javascript
{{{
$('map-element').selectLocation({ html_lat: $('#id_lat'),
                                  html_lng: $('#id_lng') });
}}}

'''Specification'''
 * When the input already contains data on init, place the marker on the map
 * When the data in the inputs is changed, move the marker to that position and center the map at the marker
 * When the marker is moved, change the values in the input elements to the coordinates of the marker
 * When the inputs are emptied, remove the marker from the map
Line 45: Line 71:
'''Example'''

/media/icons/marker.png

'''Specification'''
 * If no marker is specified, use the Google default

----
==== html_addr ====
''The HTML <input> elements where the adress is specified (can be multiple)
See google.maps.Geocoder() for more information''

Example:
 * $('#id_country, #id_city, #id_address')
'''Default'''
{{{
/media.icons/marker.png
}}}

'''Example'''
{{{
$('map-element').selectLocation({ marker_icon: '/media/icons/my_marker.png' });
}}}

'''Specification'''
 * If no marker is specified, use the default marker (supplied by this module)
 * If the default marker is not found, use the google default

----
=== html_addr ===
''The HTML <input> elements where the adress is specified''

See [[http://code.google.com/intl/nl/apis/maps/documentation/javascript/services.html#Geocoding| the google api]] for more information

'''Default'''
{{{
null
}}}

'''Example'''

HTML
{{{
<input type="text" id="id_country" name="country" />
<input type="text" id="id_city" name="city" />
<input type="text" id="id_address" name="address" />
}}}
Javascript
{{{
$('map-element').selectLocation({ html_addr: $('#id_country, #id_city, #id_address') });
}}}
Line 70: Line 119:
The url of the icon that is displayed as marker.

'''Example'''

/media/icons/marker.png

'''Specification'''
 * If no marker is specified, use the Google default

----
=== data_url ===
''The url where the locations can be loaded from in JSON form''

'''Example'''

/map/locations/all/

'''Specification'''
The URL should return at minimal:
[{fields: {lng:<float>, lat:<float>}},
 {fields: {lng:<float>, lat:<float>}},
''The url of the icon that is displayed as marker.''

'''Default'''
{{{
null
}}}


'''Example'''
{{{
$('map-element').showLocations({ marker_icon: '
/media/icons/my_marker.png' });
}}}


'''Specification'''
 * If no marker is specified, use the default marker (supplied by this module)
 * If the default marker is not found, use the g
oogle default

----
=== markers_url ===
''A list of markers, from url OR a predefined list''

'''Default'''
{{{
null
}}}


'''Example'''
{{{
$('map-element').showLocations({ markers_url: '
/map/locations/all/' });
}}}


'''Specification'''
The URL should return:
{{{
[{lng:<float>, lat:<float>},
 {lng:<float>, lat:<float>}
Line 92: Line 155:
}}}
or (specially for django)
{{{
[{pk: <int>, fields: {lng:<float>, lat:<float>}},
 {pk: <int>, fields: {lng:<float>, lat:<float>}},
 ...]
}}}
Line 109: Line 179:
=== geo_location ===
Uses the HTML5 geolocation to determine the location of the user.
=== markers_list ===
''A list of markers in json format''

'''Default'''
{{{
null
}}}

'''Example'''
{{{
$('map-element').showLocations({ markers_list: [ {lat: 0.345, lng: 0.3456},
                                                 {lat: 44.345, lng: 34.3456} ] });
}}}

=== position_name ===
''If your json file does not contain 'lat' and 'lng' but uses other names for these fields, you can specify yhe names here''

'''Default'''
{{{
{ lat: 'lat', lng: 'lng' }
}}}

'''Example'''
{{{
$('map-element').showLocations({ position_name: { lat: 'latitude', lng: 'longitude' } });
}}}

The JSON data provided by markers_url or markers_list should then looks like
{{{
[ { latitude: 0.345, longitude: 0.3456},
  { latitude: 44.345, longitude: 34.3456} ]
}}}

=== marker_content_url ===
''The content that need to be displayed when clicked on a marker, loaded with an url''

'''Default'''
{{{
null
}}}

'''Example'''
{{{
$('map-element').showLocations({ marker_content_url: '/marker/user/${user}/${username}/' });
}}}

The part ${user} and ${username} are replaced by the values of the marker
{{{
{ lat: 45.3245, lng: 23.4563, user: 1, username: 'myname' }
}}}
is translated to te url '/marker/user/1/myname/'

'''Specification'''
 * each ${...} is replaced in the url by the value of the marker
 * while the request is loading, the loading infowindow is displayed (icon: '''ajax_load_icon''')
 * if the url does not exists, the text from '''ajax_load_error''' is displayed
 * When the request is successfull loaded, the contents are shown in the infowindow

=== marker_content_tmpl ===
''If all the values you want to display are in the marker itself, this function can be used to translate the marker data into a nice template''

'''Default'''
{{{
null
}}}

'''Example'''
{{{
$('map-element').showLocations({ marker_content_tmpl: '/path/to/template.tmpl' });
}}}

The template file should look something like this:
{{{
<script id="markerTemplate" type="text/x-jquery-tmpl">
    <div>
        <p>UserId: ${ marker.user }</p>
        <p>Username: ${ marker.username }</p>
        <p>other param: ${ marker.other }</p>
    </div>
</script>
}}}

The JSON data provided by markers_url or markers_list should then looks like
{{{
[ { latitude: 0.345, longitude: 0.3456, user: 1, username: 'myname', other: 'blablabla' },
  { latitude: 44.345, longitude: 34.3456, user: 2, username: 'anothername', other: 'not important' } ]
}}}

----
=== user_location_zoom ===
''Uses the HTML5 geolocation to determine the location of the user. If the value is '''null''' this behaviour is disabled''

See the [[https://developer.mozilla.org/En/Using_geolocation|Mozilla developer page]] for more information

'''Default'''
{{{
7
}}}
Line 113: Line 279:
{use=True, zoom=7}

'''Default'''
{use=True, zoom=7}
{{{
$('map-element').showLocations({ user_location_zoom: 9 });
$('map-element').showLocations({ user_location_zoom: null } });
}}}
Line 119: Line 285:
 * If use=True, use the HTML5 to determine the location of the user, then set the map's center to that location  * If the value is not 'null' use the HTML5 to determine the location of the user, then set the map's center to that location
Line 122: Line 288:
----
=== marker_content_url ===
''The url of content that is showed when clicked on the marker. $id will be replaced by the id of the marker.''

'''Example'''

/markers/users/$id/

'''Specification'''
 * If the url is not specified, dont allow clicking on markers
 * if the url is specified, replace the %id in url by the marker id, and load the HTML
 * While the html is loaded, show a infowindows with a loading text (Retrieving data from server)
 * Possible make this more regex in the future to replace each /$xxx/ by some variable of the marker

----
=== locations ===
''A list of predefined locations (if the data_url is not used)''

'''Example'''

[{lng: 1.5555, lat: 1.2345},
 {lng: 3.4563, lat: 23.2345},
 ...]

'''Specification'''
 * If the locations is defined, direcly show the locations on the map


== Full Example 1 ==

=== single_marker_zoom ===
''The zoomlevel for the map when there is only one marker on it. Use '''null''' to disable this future''
'''Default'''
{{{
7
}}}

'''Example'''
{{{
$('map-element').showLocations({ single_marker_zoom: 9 });
$('map-element').showLocations({ single_marker_zoom: null });
}}}

'''Specification'''
 * If true and there is only one marker, zoom in and center that marker.
 * If false, leave the zoom to the default settings


=== ajax_load_error ===
''The error that is shown when the remote page could not be loaded''

'''Default'''
{{{
'<p>The page could not be loaded</p>',
}}}

'''Example'''
{{{
$('map-element').showLocations({ ajax_load_error: '<p>Contact the site admin, the page could not be loaded</p>' });
}}}

=== ajax_load_icon ===
''The url of the icon that is shown when an ajax call is executed''

'''Default'''
{{{
'/ubuntu-website/media/images/ajax-loader.gif'
}}}

'''Example'''
{{{
$('map-element').showLocations({ ajax_load_icon: '/path/to/icon.gif' });
}}}

=== cluster_tmpl ===
''The link to the template that is shown when someone clicks on a cluster''

'''Default'''
{{{
null
}}}

'''Example'''
{{{
$('map-element').showLocations({ cluster_tmpl: '/path/to/template.tmpl' });
}}}

The template should look like this. '''marker_list''' is the list of markers. From here the attributes of the marker can be used.
{{{
<script id="clusterTemplate" type="text/x-jquery-tmpl">
    <div>
        <ul>
            {{each marker_list.slice(0, 10)}}
            <li>${ user } - ${ is_support }</li>
            {{/each}}
        </ul>
        {{if marker_list.length > 10}}
        <p>and ${ marker_list.length - 10 } more</p>
        {{/if}}
    </div>
</script>
}}}

=== filter ===
''A filter object for displaying the right markers, which filter on the attributes of the marker''

'''Default'''
{{{
null
}}}

'''Example'''
{{{
$('map-element').showLocations({ filter: [ { element: $('#filter-programmers'), attrs: { program: true },
                                           { element: $('#filter-support'), attrs: { support: true },
                                           { element: $('#filter-none), attrs: {} ] });
}}}
This example has 2 filters (programmers and support), the last one shows all the markers (no filtering)

The element should be a jQuery DOM element (button to click on, for triggering the filter)
{{{
<a href="javascript:void(0);" id="filter-programmers">Programmers</a>
<a href="javascript:void(0);" id="filter-support">Support</a>
<div id="filter-none">Show all</div>
}}}

The markers should have the attibutes '''program''' and '''support'''

'''Specification'''
 * When clicked on a 'filter-button' the markers that dont apply to the filter wil be hidden
 * When no attrs are supplied, all the markers will be visible


== Full Example 1 (showLocations) ==
=== models.py ===
{{{
class Marker(models.Model):
    user = models.ForeignKey(User)
    lat = models.FloatField()
    lng = models.FloatField()
}}}

=== views.py ===
{{{
from django.core import serializers
from django.contrib.auth.models import User
from django.shortcuts import get_object_or_404
from models import Marker

def show_all_markers(request):
    data = serializers.serialize('json', Marker.object.all(), ensure_ascii=False)
    return HttpResponse(data, mimetype="application/json")

def marker_html(request, userId):
    user = get_object_or_404(User, pk=userId)
    return render_to_response('templatename.html', {'user':user})
}}}

=== urls.py ===
{{{
    url('^map/markers/all', 'app.views.show_all_markers', name='map-markers-all'),
    url('^map/marker/user/(?P<user>\d+)/', 'app.views.marker_html', name='marker_html'),
}}}
Line 153: Line 425:
<html>
<body>
Line 155: Line 429:
}}} </body>
</html>
}}}
Line 160: Line 437:
Line 163: Line 441:
    $('#mymap').showLocations({ locations: [{55.5522, 45.3222},
                                            {23.2345, -65.8742},
                                            {-25.5322, 0.5235}],
                                geo_location: {use: True, geo_location_zoom: 8},
                                marker_icon: '/media/icons/marker.png'});
    $('#mymap').showLocations({ markers_url: '{% url map-markers-all %}',
                                marker_content_url: '/map/marker/user/${user}/',
                                marker_icon: '{{ MEDIA_URL }}icons/marker.png' });

Google Maps implementation for Ubuntu-django-foundations

Blueprint: https://blueprints.launchpad.net/ubuntu-django-foundations/+spec/maps-jquery-plugin

Download: jquery-ubuntu-maps-0.2.1.js

Required js libraries:

  • jQuery
  • jquery-tmpl (only if templates are used)
  • Google maps
  • markerclusterer

    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
    <script type="text/javascript" src="https://github.com/jquery/jquery-tmpl/raw/master/jquery.tmpl.min.js"></script>
    <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false&language=en&region=US"></script>
    <script type="text/javascript" src="http://google-maps-utility-library-v3.googlecode.com/svn/tags/markerclusterer/1.0/src/markerclusterer_packed.js"></script>

The plugin consists of 2 commands e.g.

$('map-element').selectLocation({ params })
$('map-element').showLocations({ params })

Both commands with their parameters and uses will be exmplained below

selectLocation

Allows the user to add a marker to the map.

There are 3 methods to add/move a marker on the map:

  1. By clinking an empty space on the map
  2. By changing the <input> elements that represents the latitude and longitude

  3. By changing the <input> elements that is a representation of the address


html_lat and html_lng

The HTML <input> element that represents the latitude and longitude of the marker e.g.

Default

null

maybe change this to #id_lng

Example

HTML

<input type="text" id="id_lat" name="lat" value="0.353452" />
<input type="text" id="id_lng" name="lng" value="0.435323" />

Javascript

$('map-element').selectLocation({ html_lat: $('#id_lat'),
                                  html_lng: $('#id_lng') });

Specification

  • When the input already contains data on init, place the marker on the map
  • When the data in the inputs is changed, move the marker to that position and center the map at the marker
  • When the marker is moved, change the values in the input elements to the coordinates of the marker
  • When the inputs are emptied, remove the marker from the map


marker_icon

The url of the icon that is displayed as marker.

Default

/media.icons/marker.png

Example

$('map-element').selectLocation({ marker_icon: '/media/icons/my_marker.png' });

Specification

  • If no marker is specified, use the default marker (supplied by this module)
  • If the default marker is not found, use the google default


html_addr

The HTML <input> elements where the adress is specified

See the google api for more information

Default

null

Example

HTML

<input type="text" id="id_country" name="country" />
<input type="text" id="id_city" name="city" />
<input type="text" id="id_address" name="address" />

Javascript

$('map-element').selectLocation({ html_addr: $('#id_country, #id_city, #id_address') });

Specification

  • If one of the input elements is changed, lookup the address in the google database, and move the marker to that location, and center the map at the marker
  • If multiple locations are returned, use the first one
  • If the marker is moved, do nothing

showLocations

Shows multiple markers on the map. The markers cannot be changed position. When clicked on the marker, it can (if specified) show some HTML content with information about that marker. If there are many markers and zoomed out, the markers are clustered to save some CPU power. When zoomed in, the cluster is separated into single markers. Clicking on a cluster shows the markers in it (max 10).


marker_icon

The url of the icon that is displayed as marker.

Default

null

Example

$('map-element').showLocations({ marker_icon: '/media/icons/my_marker.png' });

Specification

  • If no marker is specified, use the default marker (supplied by this module)
  • If the default marker is not found, use the google default


markers_url

A list of markers, from url OR a predefined list

Default

null

Example

$('map-element').showLocations({ markers_url: '/map/locations/all/'  });

Specification The URL should return:

[{lng:<float>, lat:<float>},
 {lng:<float>, lat:<float>}
 ...]

or (specially for django)

[{pk: <int>, fields: {lng:<float>, lat:<float>}},
 {pk: <int>, fields: {lng:<float>, lat:<float>}},
 ...]

Additional information can be added to fields.

The JSON can be easily created by the django function:

Example models.py class MyModel(models.Model): <tab>lat = models.FloatField() <tab>lng = models.FloatField()

views.py from django.core import serializers data = serializers.serialize('json', MyModel.objects.all(), ensure_ascii=False) return HttpResponse(data, mimetype="application/json")


markers_list

A list of markers in json format

Default

null

Example

$('map-element').showLocations({ markers_list: [ {lat: 0.345, lng: 0.3456}, 
                                                 {lat: 44.345, lng: 34.3456} ] });

position_name

If your json file does not contain 'lat' and 'lng' but uses other names for these fields, you can specify yhe names here

Default

{ lat: 'lat', lng: 'lng' }

Example

$('map-element').showLocations({ position_name: { lat: 'latitude', lng: 'longitude' } });

The JSON data provided by markers_url or markers_list should then looks like

[ { latitude: 0.345, longitude: 0.3456}, 
  { latitude: 44.345, longitude: 34.3456} ]

marker_content_url

The content that need to be displayed when clicked on a marker, loaded with an url

Default

null

Example

$('map-element').showLocations({ marker_content_url: '/marker/user/${user}/${username}/' });

The part ${user} and ${username} are replaced by the values of the marker

{ lat: 45.3245, lng: 23.4563, user: 1, username: 'myname' }

is translated to te url '/marker/user/1/myname/'

Specification

  • each ${...} is replaced in the url by the value of the marker
  • while the request is loading, the loading infowindow is displayed (icon: ajax_load_icon)

  • if the url does not exists, the text from ajax_load_error is displayed

  • When the request is successfull loaded, the contents are shown in the infowindow

marker_content_tmpl

If all the values you want to display are in the marker itself, this function can be used to translate the marker data into a nice template

Default

null

Example

$('map-element').showLocations({ marker_content_tmpl: '/path/to/template.tmpl' });

The template file should look something like this:

<script id="markerTemplate" type="text/x-jquery-tmpl"> 
    <div>
        <p>UserId: ${ marker.user }</p>
        <p>Username: ${ marker.username }</p>
        <p>other param: ${ marker.other }</p>
    </div>
</script>

The JSON data provided by markers_url or markers_list should then looks like

[ { latitude: 0.345, longitude: 0.3456, user: 1, username: 'myname', other: 'blablabla' }, 
  { latitude: 44.345, longitude: 34.3456, user: 2, username: 'anothername', other: 'not important' } ]


user_location_zoom

Uses the HTML5 geolocation to determine the location of the user. If the value is null this behaviour is disabled

See the Mozilla developer page for more information

Default

7

Examples

$('map-element').showLocations({ user_location_zoom: 9 });
$('map-element').showLocations({ user_location_zoom: null } });

Specifications

  • If the value is not 'null' use the HTML5 to determine the location of the user, then set the map's center to that location
  • Adapt the zoomlevel to the specified zoomlevel

single_marker_zoom

The zoomlevel for the map when there is only one marker on it. Use null to disable this future Default

7

Example

$('map-element').showLocations({ single_marker_zoom: 9 });
$('map-element').showLocations({ single_marker_zoom: null });

Specification

  • If true and there is only one marker, zoom in and center that marker.
  • If false, leave the zoom to the default settings

ajax_load_error

The error that is shown when the remote page could not be loaded

Default

'<p>The page could not be loaded</p>',

Example

$('map-element').showLocations({ ajax_load_error: '<p>Contact the site admin, the page could not be loaded</p>' });

ajax_load_icon

The url of the icon that is shown when an ajax call is executed

Default

'/ubuntu-website/media/images/ajax-loader.gif'

Example

$('map-element').showLocations({ ajax_load_icon: '/path/to/icon.gif' });

cluster_tmpl

The link to the template that is shown when someone clicks on a cluster

Default

null

Example

$('map-element').showLocations({ cluster_tmpl: '/path/to/template.tmpl' });

The template should look like this. marker_list is the list of markers. From here the attributes of the marker can be used.

<script id="clusterTemplate" type="text/x-jquery-tmpl"> 
    <div>
        <ul>
            {{each marker_list.slice(0, 10)}}
            <li>${ user } - ${ is_support }</li>
            {{/each}}
        </ul>
        {{if marker_list.length > 10}}
        <p>and ${ marker_list.length - 10 } more</p>
        {{/if}}
    </div>
</script>

filter

A filter object for displaying the right markers, which filter on the attributes of the marker

Default

null

Example

$('map-element').showLocations({ filter: [ { element: $('#filter-programmers'), attrs: { program: true },
                                           { element: $('#filter-support'), attrs: { support: true },
                                           { element: $('#filter-none), attrs: {} ] });

This example has 2 filters (programmers and support), the last one shows all the markers (no filtering)

The element should be a jQuery DOM element (button to click on, for triggering the filter)

<a href="javascript:void(0);" id="filter-programmers">Programmers</a>
<a href="javascript:void(0);" id="filter-support">Support</a>
<div id="filter-none">Show all</div>

The markers should have the attibutes program and support

Specification

  • When clicked on a 'filter-button' the markers that dont apply to the filter wil be hidden
  • When no attrs are supplied, all the markers will be visible

Full Example 1 (showLocations)

models.py

class Marker(models.Model):
    user = models.ForeignKey(User)
    lat = models.FloatField()
    lng = models.FloatField()

views.py

from django.core import serializers
from django.contrib.auth.models import User
from django.shortcuts import get_object_or_404
from models import Marker

def show_all_markers(request):
    data = serializers.serialize('json', Marker.object.all(), ensure_ascii=False)
    return HttpResponse(data, mimetype="application/json")

def marker_html(request, userId):
    user = get_object_or_404(User, pk=userId)
    return render_to_response('templatename.html', {'user':user})

urls.py

    url('^map/markers/all', 'app.views.show_all_markers', name='map-markers-all'),
    url('^map/marker/user/(?P<user>\d+)/', 'app.views.marker_html', name='marker_html'),

HTML

<html>
<body>
    <section id="mymap">
    </section>
</body>
</html>

CSS

#mymap { height: 400px; width: 500px; }

Javascript

$(function(){
    $('#mymap').showLocations({ markers_url: '{% url map-markers-all %}',
                                marker_content_url: '/map/marker/user/${user}/',
                                marker_icon: '{{ MEDIA_URL }}icons/marker.png' });
});

TODO

  • Allow Cluster options
  • Multiple different clusters
  • Reloading markers
  • Filter markers on attribute

ubuntu-django-foundations/map (last edited 2011-04-11 11:40:40 by 41)