0001-map-field-5668.patch
wcs/fields.py | ||
---|---|---|
15 | 15 |
# along with this program; if not, see <http://www.gnu.org/licenses/>. |
16 | 16 | |
17 | 17 |
import time |
18 |
import random |
|
18 | 19 |
import re |
19 | 20 |
import xml.etree.ElementTree as ET |
20 | 21 | |
... | ... | |
1348 | 1349 |
register_field_class(TableRowsField) |
1349 | 1350 | |
1350 | 1351 | |
1352 |
class MapField(WidgetField): |
|
1353 |
key = 'map' |
|
1354 |
description = N_('Map') |
|
1355 | ||
1356 |
initial_zoom = None |
|
1357 |
min_zoom = None |
|
1358 |
max_zoom = None |
|
1359 |
default_position = None |
|
1360 |
init_with_geoloc = False |
|
1361 | ||
1362 |
widget_class = MapWidget |
|
1363 |
extra_attributes = ['initial_zoom', 'min_zoom', 'max_zoom', |
|
1364 |
'default_position', 'init_with_geoloc'] |
|
1365 | ||
1366 |
def fill_admin_form(self, form): |
|
1367 |
WidgetField.fill_admin_form(self, form) |
|
1368 |
# 0: whole world, 9: wide area, 11: area, 13: town, 16: small road |
|
1369 |
zoom_levels = [(None, '---'), |
|
1370 |
('0', _('Whole world')), |
|
1371 |
('9', _('Wide area')), |
|
1372 |
('11', _('Area')), |
|
1373 |
('13', _('Town')), |
|
1374 |
('16', _('Small road'))] |
|
1375 |
form.add(SingleSelectWidget, 'initial_zoom', title=_('Initial zoom level'), |
|
1376 |
value=self.initial_zoom or '13', options=zoom_levels) |
|
1377 |
form.add(SingleSelectWidget, 'min_zoom', title=_('Minimal zoom level'), |
|
1378 |
value=self.min_zoom, options=zoom_levels, required=False) |
|
1379 |
form.add(SingleSelectWidget, 'max_zoom', title=_('Maximal zoom level'), |
|
1380 |
value=self.max_zoom, options=zoom_levels, required=False) |
|
1381 |
form.add(MapWidget, 'default_position', title=_('Initial Position'), |
|
1382 |
value=self.default_position, default_zoom='9', required=False) |
|
1383 |
form.add(CheckboxWidget, 'init_with_geoloc', |
|
1384 |
title=_('Initialize position using device geolocation'), |
|
1385 |
value=self.init_with_geoloc, required=False) |
|
1386 | ||
1387 |
def get_admin_attributes(self): |
|
1388 |
return WidgetField.get_admin_attributes(self) + ['initial_zoom', |
|
1389 |
'min_zoom', 'max_zoom', 'default_position', |
|
1390 |
'init_with_geoloc'] |
|
1391 | ||
1392 |
def get_view_value(self, value): |
|
1393 |
widget = self.widget_class('x%s' % random.random(), value, readonly=True) |
|
1394 |
return widget.render_content() |
|
1395 | ||
1396 |
def get_rst_view_value(self, value, indent=''): |
|
1397 |
return indent + value |
|
1398 | ||
1399 |
register_field_class(MapField) |
|
1400 | ||
1401 | ||
1351 | 1402 |
class RankedItemsField(WidgetField): |
1352 | 1403 |
key = 'ranked-items' |
1353 | 1404 |
description = N_('Ranked Items') |
wcs/qommon/form.py | ||
---|---|---|
1747 | 1747 |
self.value = hashlib.sha1(pwd1).hexdigest() |
1748 | 1748 |
else: |
1749 | 1749 |
self.value = None |
1750 | ||
1751 | ||
1752 |
class MapWidget(CompositeWidget): |
|
1753 |
def __init__(self, name, value=None, **kwargs): |
|
1754 |
CompositeWidget.__init__(self, name, value, **kwargs) |
|
1755 |
self.add(HiddenWidget, 'latlng') |
|
1756 |
self.readonly = kwargs.pop('readonly', False) |
|
1757 |
self.kwargs = kwargs |
|
1758 | ||
1759 |
def render_content(self): |
|
1760 |
get_response().add_javascript(['qommon.map.js']) |
|
1761 |
r = TemplateIO(html=True) |
|
1762 |
for widget in self.get_widgets(): |
|
1763 |
r += widget.render() |
|
1764 |
attrs = { |
|
1765 |
'class': 'qommon-map', |
|
1766 |
'id': 'map-%s' % self.name, |
|
1767 |
} |
|
1768 |
if self.value: |
|
1769 |
attrs['data-init-lat'], attrs['data-init-lng'] = self.value.split(';') |
|
1770 |
if self.readonly: |
|
1771 |
attrs['data-readonly'] = 'true' |
|
1772 |
for attribute in ('initial_zoom', 'min_zoom', 'max_zoom'): |
|
1773 |
if attribute in self.kwargs: |
|
1774 |
attrs['data-%s' % attribute] = self.kwargs.get(attribute) |
|
1775 |
if self.kwargs.get('default_position'): |
|
1776 |
attrs['data-def-lat'], attrs['data-def-lng'] = self.kwargs.get('default_position').split(';') |
|
1777 |
if self.kwargs.get('init_with_geoloc'): |
|
1778 |
attrs['data-init-with-geologc'] = 1 |
|
1779 |
r += htmltext('<div %s></div>' % ' '.join(['%s="%s"' % x for x in attrs.items()])) |
|
1780 |
return r.getvalue() |
|
1781 | ||
1782 |
def _parse(self, request): |
|
1783 |
CompositeWidget._parse(self, request) |
|
1784 |
self.value = self.get('latlng') |
wcs/qommon/http_response.py | ||
---|---|---|
61 | 61 |
self.javascript_scripts = [] |
62 | 62 |
for script_name in script_names: |
63 | 63 |
if not script_name in self.javascript_scripts: |
64 |
if script_name == 'qommon.map.js': |
|
65 |
self.add_javascript(['jquery.js']) |
|
66 |
self.add_javascript(['../../leaflet/leaflet.js']) |
|
67 |
self.add_css_include('../../leaflet/leaflet.css') |
|
64 | 68 |
self.javascript_scripts.append(str(script_name)) |
65 | 69 |
if script_name == 'afterjob.js': |
66 | 70 |
self.add_javascript_code('var QOMMON_ROOT_URL = "%s";\n' % \ |
wcs/qommon/static/css/qommon.css | ||
---|---|---|
389 | 389 |
outline: 0; |
390 | 390 |
border: 1px solid #aaa; |
391 | 391 |
} |
392 | ||
393 |
div.qommon-map { |
|
394 |
height: 280px; |
|
395 |
} |
wcs/qommon/static/js/qommon.map.js | ||
---|---|---|
1 |
$(function() { |
|
2 |
$('.qommon-map').each(function() { |
|
3 |
var map_options = Object(); |
|
4 |
var initial_zoom = parseInt($(this).data('initial_zoom')); |
|
5 |
if (! isNaN(initial_zoom)) { |
|
6 |
map_options.zoom = initial_zoom; |
|
7 |
} else { |
|
8 |
map_options.zoom = 13; |
|
9 |
} |
|
10 |
var max_zoom = parseInt($(this).data('max_zoom')); |
|
11 |
if (! isNaN(max_zoom)) map_options.maxZoom = max_zoom; |
|
12 |
var min_zoom = parseInt($(this).data('min_zoom')); |
|
13 |
if (! isNaN(min_zoom)) map_options.minZoom = min_zoom; |
|
14 |
var map = L.map($(this).attr('id'), map_options); |
|
15 |
var hidden = $(this).prev(); |
|
16 |
map.marker = null; |
|
17 |
var latlng; |
|
18 |
if ($(this).data('init-lat')) { |
|
19 |
latlng = [$(this).data('init-lat'), $(this).data('init-lng')] |
|
20 |
map.marker = L.marker(latlng); |
|
21 |
map.marker.addTo(map); |
|
22 |
} else if ($(this).data('def-lat')) { |
|
23 |
latlng = [$(this).data('def-lat'), $(this).data('def-lng')] |
|
24 |
} else { |
|
25 |
latlng = [50.84, 4.36]; |
|
26 |
} |
|
27 |
map.setView(latlng, map_options.zoom); |
|
28 |
L.tileLayer( |
|
29 |
'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', |
|
30 |
{ |
|
31 |
attribution: 'Map data © <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>' |
|
32 |
}).addTo(map); |
|
33 |
if (! $(this).data('readonly')) { |
|
34 |
map.on('click', function(e) { |
|
35 |
if (map.marker === null) { |
|
36 |
map.marker = L.marker([0, 0]); |
|
37 |
map.marker.addTo(map); |
|
38 |
} |
|
39 |
map.marker.setLatLng(e.latlng); |
|
40 |
hidden.val(e.latlng.lat + ';' + e.latlng.lng); |
|
41 |
}); |
|
42 |
} |
|
43 |
if ($(this).data('init-with-geoloc')) { |
|
44 |
map.on('locationfound', function(e) { |
|
45 |
hidden.val(e.latlng.lat + ';' + e.latlng.lng); |
|
46 |
map.setView(e.latlng, map_options.zoom); |
|
47 |
}); |
|
48 |
map.locate({timeout: 1000, maximumAge: 60000}); |
|
49 |
} |
|
50 |
}); |
|
51 |
}); |
wcs/root.py | ||
---|---|---|
359 | 359 |
dirname = os.path.join(get_publisher().data_dir, 'qommon') |
360 | 360 |
return StaticDirectory(dirname, follow_symlinks = True) |
361 | 361 | |
362 |
# maps /leaflet/ to the directory provided by the libjs-openlayers package |
|
363 |
if component == 'leaflet': |
|
364 |
return StaticDirectory('/usr/share/javascript/leaflet') |
|
365 | ||
362 | 366 |
# is this a category ? |
363 | 367 |
try: |
364 | 368 |
category = Category.get_by_urlname(component) |
365 |
- |