diff options
author | Étienne Loks <etienne.loks@iggdrasil.net> | 2019-02-05 17:05:34 +0100 |
---|---|---|
committer | Étienne Loks <etienne.loks@iggdrasil.net> | 2019-04-24 19:38:56 +0200 |
commit | c68a0bb8412f261b535d8cebb4b533cdc7b148e7 (patch) | |
tree | f9536b686833b6f406761359895fc641262c8003 /ishtar_common | |
parent | 9b6182875de760e3c4e5a6843ee56d25e869c4b8 (diff) | |
download | Ishtar-c68a0bb8412f261b535d8cebb4b533cdc7b148e7.tar.bz2 Ishtar-c68a0bb8412f261b535d8cebb4b533cdc7b148e7.zip |
Map: optimize query tretment too manage large results
Diffstat (limited to 'ishtar_common')
-rw-r--r-- | ishtar_common/static/js/ishtar-map.js | 8 | ||||
-rw-r--r-- | ishtar_common/views_item.py | 78 |
2 files changed, 45 insertions, 41 deletions
diff --git a/ishtar_common/static/js/ishtar-map.js b/ishtar_common/static/js/ishtar-map.js index 1488d8fcd..4045d952f 100644 --- a/ishtar_common/static/js/ishtar-map.js +++ b/ishtar_common/static/js/ishtar-map.js @@ -152,14 +152,15 @@ var click_on_feature = function(feature){ if (typeof feature == 'undefined'){ current_feature = null; + $(popup_item).hide(); return; } if (current_feature == feature){ + $(popup_item).hide(); return } current_feature = feature; if (!feature) return; - $(popup_item).hide(); var timeout = 200; setTimeout(function(){ @@ -271,7 +272,8 @@ var _display_items = function(features, offset_x, offset_y){ } var feat = features[idx_feat]; var properties = feat.getProperties(); - popup_content += "<li>" + properties['link'] + " " + properties['name'] + "</li>" + var link = link_template.replace("<pk>", properties["id"]); + popup_content += "<li>" + link + " " + properties['name'] + "</li>" } popup_content += "</ul>"; $(popup_item).html(popup_content); @@ -330,6 +332,7 @@ var proj_options = { } var geojson_format = new ol.format.GeoJSON(proj_options); var wkt_format = new ol.format.WKT(proj_options); +var link_template; var initialize_base_map = function(layers){ center = wkt_format.readGeometry(map_default_center).getCoordinates(); @@ -360,6 +363,7 @@ var redraw_map = function(layers){ var display_map = function(current_map_id, points, layers){ + link_template = points['link_template']; map_id = current_map_id; if (map){ redraw_map(layers); diff --git a/ishtar_common/views_item.py b/ishtar_common/views_item.py index 4a6337fe7..4e8a742e2 100644 --- a/ishtar_common/views_item.py +++ b/ishtar_common/views_item.py @@ -17,7 +17,7 @@ from django.contrib.staticfiles.templatetags.staticfiles import static from django.core.cache import cache from django.core.exceptions import ObjectDoesNotExist from django.core.urlresolvers import reverse, NoReverseMatch -from django.db.models import Q, ImageField +from django.db.models import Q, ImageField, Func, ExpressionWrapper, FloatField from django.db.models.fields import FieldDoesNotExist from django.http import HttpResponse from django.shortcuts import render @@ -991,7 +991,7 @@ def _format_val(val): return unicode(val) -def _format_geojson(rows): +def _format_geojson(rows, link_template): data = { 'type': 'FeatureCollection', 'crs': { @@ -1000,38 +1000,31 @@ def _format_geojson(rows): 'name': 'EPSG:4326' } }, + 'link_template': link_template, 'features': [], 'no-geo': [] } if not rows: return data - geo_attr, name_attr = None, None - full, idx = len(rows), 0 - while not geo_attr and idx < full: - row = rows[idx] - for attr in row: - if attr.endswith('point_2d'): - geo_attr = attr - if attr in ['name', 'cached_label']: - name_attr = attr - idx += 1 - if not geo_attr or not name_attr: - return data for row in rows: - feat = {'name': row[name_attr], 'id': row['id'], 'link': row['link']} - if not row.get(geo_attr, None): + feat = {'id': row[0], 'name': row[1]} + if not row[2]: data['no-geo'].append(feat) continue - feature = {'type': 'Feature'} - feature['properties'] = feat - point = GEOSGeometry(row[geo_attr]) - feature['geometry'] = json.loads(point.json) + feature = { + 'type': 'Feature', + 'properties': feat, + 'geometry': { + u'type': u'Point', + u'coordinates': [row[2], row[3]] + } + } data['features'].append(feature) return data def _get_data_from_query(items, query_table_cols, request, extra_request_keys, - do_not_deduplicate=False): + point_field=None): for query_keys in query_table_cols: if not isinstance(query_keys, (tuple, list)): query_keys = [query_keys] @@ -1049,17 +1042,17 @@ def _get_data_from_query(items, query_table_cols, request, extra_request_keys, query_key.replace(".", "__") # class style to query values = ['id'] + query_table_cols - - c_ids, data_list = [], [] - for item in items.values(*values): - # manual deduplicate when distinct is not enough - if not do_not_deduplicate and item['id'] in c_ids: - continue - c_ids.append(item['id']) - data = [item['id']] - for key in query_table_cols: - data.append(item[key]) - data_list.append(data) + if point_field: + items = items.annotate( + point_x=ExpressionWrapper( + Func(point_field, function='ST_X'), output_field=FloatField()) + ) + items = items.annotate( + point_y=ExpressionWrapper( + Func(point_field, function='ST_Y'), output_field=FloatField()) + ) + values += ['point_x', 'point_y'] + data_list = items.values_list(*values) return data_list @@ -1632,9 +1625,10 @@ def get_item(model, func_name, default_name, extra_request_keys=None, items = [item.get_previous(old) for item in items] if data_type == 'json-map': + point_field = query_table_cols.pop() datas = _get_data_from_query( items, query_table_cols, request, my_extra_request_keys, - do_not_deduplicate) + point_field=point_field) else: datas = _get_data_from_query_old( items, query_table_cols, request, my_extra_request_keys, @@ -1661,6 +1655,13 @@ def get_item(model, func_name, default_name, extra_request_keys=None, link_ext_template = '<a href="{}" target="_blank">{}</a>' if data_type.startswith("json"): rows = [] + if data_type == 'json-map': + + lnk = link_template % reverse('show-' + default_name, + args=[999999, '']) + lnk = lnk.replace('999999', "<pk>") + data = json.dumps(_format_geojson(datas, lnk)) + return HttpResponse(data, content_type='application/json') for data in datas: try: lnk_template = link_template @@ -1671,8 +1672,10 @@ def get_item(model, func_name, default_name, extra_request_keys=None, '**WARN "show-' + default_name + '" args (' + unicode(data[0]) + ") url not available") lnk = '' - res = {'id': data[0]} - res['link'] = lnk + res = { + 'id': data[0], + 'link': lnk + } for idx, value in enumerate(data[1:]): if value: table_col = table_cols[idx] @@ -1697,9 +1700,7 @@ def get_item(model, func_name, default_name, extra_request_keys=None, elif 'name' in res: res['value'] = res.pop('name') rows.append(res) - if data_type == 'json-map': - data = json.dumps(_format_geojson(rows)) - elif full == 'shortcut': + if full == 'shortcut': data = json.dumps(rows) else: data = json.dumps({ @@ -1714,7 +1715,6 @@ def get_item(model, func_name, default_name, extra_request_keys=None, return HttpResponse(data, content_type='application/json') elif data_type == "csv": response = HttpResponse(content_type='text/csv') - n = datetime.datetime.now() filename = u'%s_%s.csv' % (default_name, n.strftime('%Y%m%d-%H%M%S')) response['Content-Disposition'] = 'attachment; filename=%s' \ |