def _get_voting_area_info(area_id): if re.match('\d\d([a-z][a-z])?([a-z][a-z])?$(?i)', area_id): area = get_object_or_404(Area, codes__type='ons', codes__code=area_id) else: area = get_object_or_404(Area, id=int(area_id)) if isinstance(area, HttpResponse): return area try: os_name = area.names.get(type='O').name except: os_name = None try: ons_code = area.codes.get(type='ons').code except: ons_code = None current = Generation.objects.current().id out = { 'area_id': area.id, 'name': area.name, 'os_name': os_name, 'country': area.country, 'parent_area_id': area.parent_area_id, 'type': area.type, 'ons_code': ons_code, 'generation_low': area.generation_low_id if area.generation_low_id else 0, 'generation_high': area.generation_high_id if area.generation_high_id else current, 'generation': current, } for item in ('type_name', 'attend_prep', 'general_prep', 'rep_name', 'rep_name_plural', 'rep_name_long', 'rep_name_long_plural', 'rep_suffix', 'rep_prefix'): out[item] = voting_area[item].get(area.type) return out
def area(request, area_id, legacy=False): if re.match('\d\d([A-Z]{2}|[A-Z]{4}|[A-Z]{2}\d\d\d|[A-Z]|[A-Z]\d\d)$', area_id): area = get_object_or_404(Area, codes__type='ons', codes__code=area_id) elif not re.match('\d+$', area_id): return output_json({ 'error': 'Bad area ID specified' }, code=400) else: area = get_object_or_404(Area, id=area_id) if isinstance(area, HttpResponse): return area return output_json( area.as_dict() )
def area_polygon(request, srid="", area_id="", format="kml"): if not srid and hasattr(countries, "area_code_lookup"): resp = countries.area_code_lookup(request, area_id, format) if resp: return resp if not re.match("\d+$", area_id): raise ViewException(format, "Bad area ID specified", 400) if not srid: srid = 4326 if format in ("kml", "json", "geojson") else settings.MAPIT_AREA_SRID srid = int(srid) area = get_object_or_404(Area, id=area_id) try: simplify_tolerance = float(request.GET.get("simplify_tolerance", 0)) except ValueError: raise ViewException(format, "Badly specified tolerance", 400) try: output, content_type = area.export(srid, format, simplify_tolerance=simplify_tolerance) if output is None: return output_json({"error": "No polygons found"}, code=404) except SimplifiedAway: return output_json({"error": "Simplifying removed all the polygons"}, code=404) return HttpResponse(output, content_type="%s; charset=utf-8" % content_type)
def _area_geometry(area_id): area = get_object_or_404(Area, id=area_id) all_areas = area.polygons.all().collect() if not all_areas: return output_json({"error": "No polygons found"}, code=404) out = {"parts": all_areas.num_geom} if settings.MAPIT_AREA_SRID != 4326: out["srid_en"] = settings.MAPIT_AREA_SRID out["area"] = all_areas.area out["min_e"], out["min_n"], out["max_e"], out["max_n"] = all_areas.extent out["centre_e"], out["centre_n"] = all_areas.centroid all_areas.transform(4326) out["min_lon"], out["min_lat"], out["max_lon"], out["max_lat"] = all_areas.extent out["centre_lon"], out["centre_lat"] = all_areas.centroid else: out["min_lon"], out["min_lat"], out["max_lon"], out["max_lat"] = all_areas.extent out["centre_lon"], out["centre_lat"] = all_areas.centroid if hasattr(countries, "area_geometry_srid"): srid = countries.area_geometry_srid all_areas.transform(srid) out["srid_en"] = srid out["area"] = all_areas.area out["min_e"], out["min_n"], out["max_e"], out["max_n"] = all_areas.extent out["centre_e"], out["centre_n"] = all_areas.centroid return out
def area_intersect(query_type, title, request, area_id, format): area = get_object_or_404(Area, format=format, id=area_id) if not area.polygons.count(): raise ViewException(format, "No polygons found", 404) generation = Generation.objects.current() types = filter(None, request.REQUEST.get("type", "").split(",")) set_timeout(format) try: # Cast to list so that it's evaluated here, and add_codes doesn't get # confused with a RawQuerySet areas = list(Area.objects.intersect(query_type, area, types, generation)) areas = add_codes(areas) except QueryCanceledError: raise ViewException( format, "That query was taking too long to compute - try restricting to a specific type, if you weren't already doing so.", 500, ) except DatabaseError, e: # Django 1.2+ catches QueryCanceledError and throws its own DatabaseError instead if "canceling statement due to statement timeout" not in e.args[0]: raise raise ViewException( format, "That query was taking too long to compute - try restricting to a specific type, if you weren't already doing so.", 500, )
def area_code_lookup(request, area_code, format): from mapit.models import Area, CodeType area_code_type = None if re.match('\d\d([A-Z]{2}|[A-Z]{4}|[A-Z]{2}\d\d\d|[A-Z]|[A-Z]\d\d)$', area_code): area_code_type = CodeType.objects.get(code='ons') elif re.match('[EW]0[12]\d{6}$', area_code): # LSOA/MSOA have ONS code type area_code_type = CodeType.objects.get(code='ons') elif re.match('[ENSW]\d{8}$', area_code): area_code_type = CodeType.objects.get(code='gss') if not area_code_type: return None args = {'format': format, 'codes__type': area_code_type, 'codes__code': area_code} if re.match('[EW]01', area_code): args['type__code'] = 'OLF' elif re.match('[EW]02', area_code): args['type__code'] = 'OMF' area = get_object_or_404(Area, **args) area_kwargs = {'area_id': area.id} if format: area_kwargs['format'] = format # We're called either by area or area_polygon try: redirect_path = reverse('area', kwargs=area_kwargs) except NoReverseMatch: redirect_path = reverse('area_polygon', kwargs=area_kwargs) # If there was a query string, make sure it's passed on in the # redirect: if request.META['QUERY_STRING']: redirect_path += "?" + request.META['QUERY_STRING'] return HttpResponseRedirect(redirect_path)
def area_children(request, area_id, format='json'): q = query_args(request, format) area = get_object_or_404(Area, format=format, id=area_id) children = area.children.filter(q).distinct() if format in ('kml', 'geojson'): return _areas_polygon(request, format, children) return output_areas(request, _('Children of %s') % area.name, format, children)
def area_code_lookup(request, area_code, format): from mapit.models import Area, CodeType area_code_type = None if re.match(r'\d\d([A-Z]{2}|[A-Z]{4}|[A-Z]{2}\d\d\d|[A-Z]|[A-Z]\d\d)$', area_code): area_code_type = CodeType.objects.get(code='ons') elif re.match(r'[EW]0[12]\d{6}$', area_code): # LSOA/MSOA have ONS code type area_code_type = CodeType.objects.get(code='ons') elif re.match(r'[ENSW]\d{8}$', area_code): area_code_type = CodeType.objects.get(code='gss') if not area_code_type: return None args = {'format': format, 'codes__type': area_code_type, 'codes__code': area_code} if re.match('[EW]01', area_code): args['type__code'] = 'OLF' elif re.match('[EW]02', area_code): args['type__code'] = 'OMF' area = get_object_or_404(Area, **args) area_kwargs = {'area_id': area.id} if format: area_kwargs['format'] = format # We're called either by area or area_polygon try: redirect_path = reverse('area', kwargs=area_kwargs) except NoReverseMatch: redirect_path = reverse('area_polygon', kwargs=area_kwargs) # If there was a query string, make sure it's passed on in the # redirect: if request.META['QUERY_STRING']: redirect_path += "?" + request.META['QUERY_STRING'] return HttpResponseRedirect(redirect_path)
def area_code_lookup(request, area_id, format): from mapit.models import Area, CodeType area_code = None if re.match('\d\d([A-Z]{2}|[A-Z]{4}|[A-Z]{2}\d\d\d|[A-Z]|[A-Z]\d\d)$', area_id): area_code = CodeType.objects.get(code='ons') elif re.match('[EW]0[12]\d{6}$', area_id): # LSOA/MSOA have ONS code type area_code = CodeType.objects.get(code='ons') elif re.match('[ENSW]\d{8}$', area_id): area_code = CodeType.objects.get(code='gss') if not area_code: return None args = { 'format': format, 'codes__type': area_code, 'codes__code': area_id } if re.match('[EW]01', area_id): args['type__code'] = 'OLF' elif re.match('[EW]02', area_id): args['type__code'] = 'OMF' area = get_object_or_404(Area, **args) path = '/area/%d%s' % (area.id, '.%s' % format if format else '') # If there was a query string, make sure it's passed on in the # redirect: if request.META['QUERY_STRING']: path += "?" + request.META['QUERY_STRING'] return HttpResponseRedirect(path)
def area_intersect(query_type, title, request, area_id, format): area = get_object_or_404(Area, format=format, id=area_id) if not area.polygons.count(): raise ViewException(format, 'No polygons found', 404) generation = Generation.objects.current() types = filter(None, request.REQUEST.get('type', '').split(',')) set_timeout(format) try: # Cast to list so that it's evaluated here, and add_codes doesn't get # confused with a RawQuerySet areas = list( Area.objects.intersect(query_type, area, types, generation)) areas = add_codes(areas) except QueryCanceledError: raise ViewException( format, 'That query was taking too long to compute - try restricting to a specific type, if you weren\'t already doing so.', 500) except DatabaseError, e: # Django 1.2+ catches QueryCanceledError and throws its own DatabaseError instead if 'canceling statement due to statement timeout' not in e.args[0]: raise raise ViewException( format, 'That query was taking too long to compute - try restricting to a specific type, if you weren\'t already doing so.', 500)
def area_polygon(request, srid='', area_id='', format='kml'): if not srid and hasattr(countries, 'area_code_lookup'): resp = countries.area_code_lookup(request, area_id, format) if resp: return resp if not re.match('\d+$', area_id): raise ViewException(format, 'Bad area ID specified', 400) if not srid: srid = 4326 if format in ('kml', 'json', 'geojson') else settings.MAPIT_AREA_SRID srid = int(srid) area = get_object_or_404(Area, id=area_id) try: simplify_tolerance = float(request.GET.get('simplify_tolerance', 0)) except ValueError: raise ViewException(format, 'Badly specified tolerance', 400) try: output, content_type = area.export(srid, format, simplify_tolerance=simplify_tolerance) if output is None: return output_json({'error': 'No polygons found'}, code=404) except TransformError as e: return output_json({'error': e.args[0]}, code=400) response = HttpResponse(content_type='%s; charset=utf-8' % content_type) response['Access-Control-Allow-Origin'] = '*' response['Cache-Control'] = 'max-age=2419200' # 4 weeks response.write(output) return response
def area(request, area_id, format='json'): if re.match('\d\d([A-Z]{2}|[A-Z]{4}|[A-Z]{2}\d\d\d|[A-Z]|[A-Z]\d\d)$', area_id): area = get_object_or_404(Area, format=format, codes__type='ons', codes__code=area_id) elif re.match('[ENSW]\d{8}$', area_id): area = get_object_or_404(Area, format=format, codes__type='gss', codes__code=area_id) elif not re.match('\d+$', area_id): return output_error(format, 'Bad area ID specified', 400) else: area = get_object_or_404(Area, format=format, id=area_id) if isinstance(area, HttpResponse): return area if format == 'html': return render(request, 'area.html', { 'area': area, 'show_geometry': (area.type not in ('EUR', 'SPE', 'WAE')) }) return output_json( area.as_dict() )
def _area_geometry(area_id): area = get_object_or_404(Area, id=area_id) all_areas = area.polygons.all().collect() if not all_areas: return output_json({'error': 'No polygons found'}, code=404) out = { 'parts': all_areas.num_geom, } if settings.MAPIT_AREA_SRID != 4326: out['srid_en'] = settings.MAPIT_AREA_SRID out['area'] = all_areas.area out['min_e'], out['min_n'], out['max_e'], out['max_n'] = all_areas.extent out['centre_e'], out['centre_n'] = all_areas.centroid all_areas.transform(4326) out['min_lon'], out['min_lat'], out['max_lon'], out['max_lat'] = all_areas.extent out['centre_lon'], out['centre_lat'] = all_areas.centroid else: out['min_lon'], out['min_lat'], out['max_lon'], out['max_lat'] = all_areas.extent out['centre_lon'], out['centre_lat'] = all_areas.centroid if hasattr(countries, 'area_geometry_srid'): srid = countries.area_geometry_srid all_areas.transform(srid) out['srid_en'] = srid out['area'] = all_areas.area out['min_e'], out['min_n'], out['max_e'], out['max_n'] = all_areas.extent out['centre_e'], out['centre_n'] = all_areas.centroid return out
def area_intersect(query_type, title, request, area_id, format): area = get_object_or_404(Area, format=format, id=area_id) if isinstance(area, HttpResponse): return area if not area.polygons.count(): return output_error(format, 'No polygons found', 404) generation = Generation.objects.current() args = { 'generation_low__lte': generation, 'generation_high__gte': generation, } type = request.REQUEST.get('type', '') if ',' in type: args['type__code__in'] = type.split(',') elif type: args['type__code'] = type elif area.type.code in ('EUR'): args['type__code'] = area.type.code set_timeout(format) try: areas = list(Area.objects.intersect(query_type, area).filter(**args).distinct()) areas = add_codes(areas) except QueryCanceledError: return output_error(format, 'That query was taking too long to compute - try restricting to a specific type, if you weren\'t already doing so.', 500) except DatabaseError, e: # Django 1.2+ catches QueryCanceledError and throws its own DatabaseError instead if 'canceling statement due to statement timeout' not in e.args[0]: raise return output_error(format, 'That query was taking too long to compute - try restricting to a specific type, if you weren\'t already doing so.', 500)
def area_intersect(query_type, title, request, area_id, format): area = get_object_or_404(Area, format=format, id=area_id) if not area.polygons.count(): raise ViewException(format, _('No polygons found'), 404) generation = Generation.objects.current() types = [_f for _f in request.GET.get('type', '').split(',') if _f] set_timeout(format) try: # Cast to list so that it's evaluated here, and output_areas doesn't get # confused with a RawQuerySet areas = list( Area.objects.intersect(query_type, area, types, generation)) except DatabaseError as e: if 'canceling statement due to statement timeout' not in e.args[0]: raise raise ViewException( format, _('That query was taking too long to compute - ' 'try restricting to a specific type, if you weren\'t already doing so.' ), 500) except InternalError: raise ViewException( format, _('There was an internal error performing that query.'), 500) title = title % ('<a href="%sarea/%d.html">%s</a>' % (reverse('mapit_index'), area.id, area.name)) return output_areas(request, title, format, areas, norobots=True)
def area_polygon(request, srid='', area_id='', format='kml'): if not srid and hasattr(countries, 'area_code_lookup'): resp = countries.area_code_lookup(request, area_id, format) if resp: return resp if not re.match('\d+$', area_id): raise ViewException(format, 'Bad area ID specified', 400) if not srid: srid = 4326 if format in ('kml', 'json', 'geojson') else settings.MAPIT_AREA_SRID srid = int(srid) area = get_object_or_404(Area, id=area_id) try: simplify_tolerance = float(request.GET.get('simplify_tolerance', 0)) except ValueError: raise ViewException(format, 'Badly specified tolerance', 400) try: output, content_type = area.export(srid, format, simplify_tolerance=simplify_tolerance) if output is None: return output_json({'error': 'No polygons found'}, code=404) except SimplifiedAway: return output_json({'error': 'Simplifying removed all the polygons'}, code=404) return HttpResponse(output, content_type='%s; charset=utf-8' % content_type)
def area_polygon(request, srid='', area_id='', format='kml'): if not srid: srid = 4326 if format in ('kml', 'json', 'geojson') else int(mysociety.config.get('AREA_SRID')) srid = int(srid) area = get_object_or_404(Area, id=area_id) if isinstance(area, HttpResponse): return area all_areas = area.polygons.all() if len(all_areas) > 1: all_areas = all_areas.collect() elif len(all_areas) == 1: all_areas = all_areas[0].polygon else: return output_json({ 'error': 'No polygons found' }, code=404) if srid != int(mysociety.config.get('AREA_SRID')): all_areas.transform(srid) if format=='kml': out = '''<?xml version="1.0" encoding="UTF-8"?> <kml xmlns="http://www.opengis.net/kml/2.2"> <Placemark> <name>%s</name> %s </Placemark> </kml>''' % (area.name, all_areas.kml) content_type = 'application/vnd.google-earth.kml+xml' elif format in ('json', 'geojson'): out = all_areas.json content_type = 'application/json' elif format=='wkt': out = all_areas.wkt content_type = 'text/plain' return HttpResponse(out, content_type='%s; charset=utf-8' % content_type)
def _area_geometry(area_id): area = get_object_or_404(Area, id=area_id) if isinstance(area, HttpResponse): return area all_areas = area.polygons.all().collect() if not all_areas: return output_json({ 'error': 'No polygons found' }, code=404) out = { 'parts': all_areas.num_geom, } if int(mysociety.config.get('AREA_SRID')) != 4326: out['srid_en'] = mysociety.config.get('AREA_SRID') out['area'] = all_areas.area out['min_e'], out['min_n'], out['max_e'], out['max_n'] = all_areas.extent out['centre_e'], out['centre_n'] = all_areas.centroid all_areas.transform(4326) out['min_lon'], out['min_lat'], out['max_lon'], out['max_lat'] = all_areas.extent out['centre_lon'], out['centre_lat'] = all_areas.centroid elif mysociety.config.get('COUNTRY') == 'NO': out['min_lon'], out['min_lat'], out['max_lon'], out['max_lat'] = all_areas.extent out['centre_lon'], out['centre_lat'] = all_areas.centroid all_areas.transform(32633) out['srid_en'] = 32633 out['area'] = all_areas.area out['min_e'], out['min_n'], out['max_e'], out['max_n'] = all_areas.extent out['centre_e'], out['centre_n'] = all_areas.centroid return out
def area_intersect(query_type, title, request, area_id, format): area = get_object_or_404(Area, format=format, id=area_id) if not area.polygons.count(): raise ViewException(format, 'No polygons found', 404) generation = Generation.objects.current() types = [_f for _f in request.REQUEST.get('type', '').split(',') if _f] set_timeout(format) try: # Cast to list so that it's evaluated here, and output_areas doesn't get # confused with a RawQuerySet areas = list(Area.objects.intersect(query_type, area, types, generation)) except QueryCanceledError: raise ViewException( format, 'That query was taking too long to compute - ' 'try restricting to a specific type, if you weren\'t already doing so.', 500) except DatabaseError as e: # Django 1.2+ catches QueryCanceledError and throws its own DatabaseError instead if 'canceling statement due to statement timeout' not in e.args[0]: raise raise ViewException( format, 'That query was taking too long to compute - ' 'try restricting to a specific type, if you weren\'t already doing so.', 500) except InternalError: raise ViewException(format, 'There was an internal error performing that query.', 500) title = title % ('<a href="%sarea/%d.html">%s</a>' % (reverse('mapit_index'), area.id, area.name)) return output_areas(request, title, format, areas, norobots=True)
def _area_geometry(area_id): area = get_object_or_404(Area, id=area_id) if isinstance(area, HttpResponse): return area all_areas = area.polygons.all().collect() if not all_areas: return output_json({ 'error': 'No polygons found' }, code=404) out = { 'parts': all_areas.num_geom, } if settings.MAPIT_AREA_SRID != 4326: out['srid_en'] = settings.MAPIT_AREA_SRID out['area'] = all_areas.area out['min_e'], out['min_n'], out['max_e'], out['max_n'] = all_areas.extent out['centre_e'], out['centre_n'] = all_areas.centroid all_areas.transform(4326) out['min_lon'], out['min_lat'], out['max_lon'], out['max_lat'] = all_areas.extent out['centre_lon'], out['centre_lat'] = all_areas.centroid else: out['min_lon'], out['min_lat'], out['max_lon'], out['max_lat'] = all_areas.extent out['centre_lon'], out['centre_lat'] = all_areas.centroid if hasattr(countries, 'area_geometry_srid'): srid = countries.area_geometry_srid all_areas.transform(srid) out['srid_en'] = srid out['area'] = all_areas.area out['min_e'], out['min_n'], out['max_e'], out['max_n'] = all_areas.extent out['centre_e'], out['centre_n'] = all_areas.centroid return out
def postcode(request, postcode, format=None): if hasattr(countries, 'canonical_postcode'): canon_postcode = countries.canonical_postcode(postcode) postcode = canon_postcode # if (postcode != canon_postcode and format is None) or format == 'json': # return redirect('mapit.views.postcodes.postcode', postcode=canon_postcode) if format is None: format = 'json' if not is_valid_postcode(postcode): raise ViewException(format, "Postcode '%s' is not valid." % postcode, 400) postcode = get_object_or_404(Postcode, format=format, postcode=postcode) try: generation = int(request.GET['generation']) except: generation = Generation.objects.current() if not hasattr(countries, 'is_special_postcode') or not countries.is_special_postcode( postcode.postcode): areas = list(add_codes(Area.objects.by_postcode(postcode, generation))) else: areas = [] # Shortcuts shortcuts = {} for area in areas: if area.type.code in ('COP', 'LBW', 'LGE', 'MTW', 'UTE', 'UTW'): shortcuts['ward'] = area.id shortcuts['council'] = area.parent_area_id elif area.type.code == 'CED': shortcuts.setdefault('ward', {})['county'] = area.id shortcuts.setdefault('council', {})['county'] = area.parent_area_id elif area.type.code == 'DIW': shortcuts.setdefault('ward', {})['district'] = area.id shortcuts.setdefault('council', {})['district'] = area.parent_area_id elif area.type.code in ('WMC', ): # XXX Also maybe 'EUR', 'NIE', 'SPC', 'SPE', 'WAC', 'WAE', 'OLF', 'OLG', 'OMF', 'OMG'): shortcuts[area.type.code] = area.id # Add manual enclosing areas. extra = [] for area in areas: if area.type.code in enclosing_areas.keys(): extra.extend(enclosing_areas[area.type.code]) areas = itertools.chain(areas, Area.objects.filter(id__in=extra)) if format == 'html': return render( request, 'mapit/postcode.html', { 'postcode': postcode.as_dict(), 'areas': areas, 'json_view': 'mapit-postcode', }) out = postcode.as_dict() out['areas'] = dict((area.id, area.as_dict()) for area in areas) if shortcuts: out['shortcuts'] = shortcuts return output_json(out)
def area_children(request, area_id, format=''): q = query_args(request, format) area = get_object_or_404(Area, format=format, id=area_id) children = area.children.filter(q).distinct() if format in ('kml', 'geojson'): return _areas_polygon(request, format, children) return output_areas(request, _('Children of %s') % area.name, format, children)
def area_polygon(request, srid='', area_id='', format='kml'): if not srid and hasattr(countries, 'area_code_lookup'): resp = countries.area_code_lookup(area_id, format) if resp: return resp if not re.match('\d+$', area_id): return output_error(format, 'Bad area ID specified', 400) if not srid: srid = 4326 if format in ('kml', 'json', 'geojson') else settings.MAPIT_AREA_SRID srid = int(srid) area = get_object_or_404(Area, id=area_id) if isinstance(area, HttpResponse): return area all_areas = area.polygons.all() if len(all_areas) > 1: all_areas = all_areas.collect() elif len(all_areas) == 1: all_areas = all_areas[0].polygon else: return output_json({ 'error': 'No polygons found' }, code=404) if srid != settings.MAPIT_AREA_SRID: all_areas.transform(srid) try: simplify_tolerance = float(request.GET.get('simplify_tolerance', 0)) except: return output_error(format, 'Badly specified tolerance', 400) if simplify_tolerance: all_areas = all_areas.simplify(simplify_tolerance) if format=='kml': out = '''<?xml version="1.0" encoding="UTF-8"?> <kml xmlns="http://www.opengis.net/kml/2.2"> <Style id="transBluePoly"> <LineStyle> <color>70ff0000</color> <width>2</width> </LineStyle> <PolyStyle> <color>3dff5500</color> </PolyStyle> </Style> <Placemark> <styleUrl>#transBluePoly</styleUrl> <name>%s</name> %s </Placemark> </kml>''' % (escape(area.name), all_areas.kml) content_type = 'application/vnd.google-earth.kml+xml' elif format in ('json', 'geojson'): out = all_areas.json content_type = 'application/json' elif format=='wkt': out = all_areas.wkt content_type = 'text/plain' return HttpResponse(out, content_type='%s; charset=utf-8' % content_type)
def area_polygon(request, srid='', area_id='', format='kml'): if not srid and hasattr(countries, 'area_code_lookup'): resp = countries.area_code_lookup(area_id, format) if resp: return resp if not re.match('\d+$', area_id): raise ViewException(format, 'Bad area ID specified', 400) if not srid: srid = 4326 if format in ('kml', 'json', 'geojson') else settings.MAPIT_AREA_SRID srid = int(srid) area = get_object_or_404(Area, id=area_id) all_areas = area.polygons.all() if len(all_areas) > 1: all_areas = all_areas.collect() elif len(all_areas) == 1: all_areas = all_areas[0].polygon else: return output_json({ 'error': 'No polygons found' }, code=404) if srid != settings.MAPIT_AREA_SRID: all_areas.transform(srid) try: simplify_tolerance = float(request.GET.get('simplify_tolerance', 0)) except: raise ViewException(format, 'Badly specified tolerance', 400) if simplify_tolerance: all_areas = all_areas.simplify(simplify_tolerance) if format=='kml': out = '''<?xml version="1.0" encoding="UTF-8"?> <kml xmlns="http://www.opengis.net/kml/2.2"> <Style id="transBluePoly"> <LineStyle> <color>70ff0000</color> <width>2</width> </LineStyle> <PolyStyle> <color>3dff5500</color> </PolyStyle> </Style> <Placemark> <styleUrl>#transBluePoly</styleUrl> <name>%s</name> %s </Placemark> </kml>''' % (escape(area.name), all_areas.kml) content_type = 'application/vnd.google-earth.kml+xml' elif format in ('json', 'geojson'): out = all_areas.json content_type = 'application/json' elif format=='wkt': out = all_areas.wkt content_type = 'text/plain' return HttpResponse(out, content_type='%s; charset=utf-8' % content_type)
def area_children(request, area_id, legacy=False, format='json'): area = get_object_or_404(Area, id=area_id) if isinstance(area, HttpResponse): return area generation = Generation.objects.current() children = add_codes(area.children.filter( generation_low__lte=generation, generation_high__gte=generation )) if legacy: return output_json( [ child.id for child in children ] ) if format == 'html': return output_html( children ) return output_json( dict( (child.id, child.as_dict() ) for child in children ) )
def postcode(request, postcode, format=None): if hasattr(countries, 'canonical_postcode'): canon_postcode = countries.canonical_postcode(postcode) postcode = canon_postcode # if (postcode != canon_postcode and format is None) or format == 'json': # return redirect('mapit.views.postcodes.postcode', postcode=canon_postcode) if format is None: format = 'json' if not is_valid_postcode(postcode): raise ViewException(format, "Postcode '%s' is not valid." % postcode, 400) postcode = get_object_or_404(Postcode, format=format, postcode=postcode) try: generation = int(request.GET['generation']) except: generation = Generation.objects.current() if not hasattr(countries, 'is_special_postcode') or not countries.is_special_postcode(postcode.postcode): areas = list(add_codes(Area.objects.by_postcode(postcode, generation))) else: areas = [] # Shortcuts shortcuts = {} for area in areas: if area.type.code in ('COP', 'LBW', 'LGE', 'MTW', 'UTE', 'UTW'): shortcuts['ward'] = area.id shortcuts['council'] = area.parent_area_id elif area.type.code == 'CED': shortcuts.setdefault('ward', {})['county'] = area.id shortcuts.setdefault('council', {})['county'] = area.parent_area_id elif area.type.code == 'DIW': shortcuts.setdefault('ward', {})['district'] = area.id shortcuts.setdefault('council', {})['district'] = area.parent_area_id elif area.type.code in ('WMC',): # XXX Also maybe 'EUR', 'NIE', 'SPC', 'SPE', 'WAC', 'WAE', 'OLF', 'OLG', 'OMF', 'OMG'): shortcuts[area.type.code] = area.id # Add manual enclosing areas. extra = [] for area in areas: if area.type.code in enclosing_areas.keys(): extra.extend(enclosing_areas[area.type.code]) areas = itertools.chain(areas, Area.objects.filter(id__in=extra)) if format == 'html': return render(request, 'mapit/postcode.html', { 'postcode': postcode.as_dict(), 'areas': areas, 'json_view': 'mapit-postcode', }) out = postcode.as_dict() out['areas'] = dict((area.id, area.as_dict()) for area in areas) if shortcuts: out['shortcuts'] = shortcuts return output_json(out)
def area_code_lookup(area_id, format): from mapit.models import Area, CodeType area_code = None if re.match('\d\d([A-Z]{2}|[A-Z]{4}|[A-Z]{2}\d\d\d|[A-Z]|[A-Z]\d\d)$', area_id): area_code = CodeType.objects.get(code='ons') if re.match('[ENSW]\d{8}$', area_id): area_code = CodeType.objects.get(code='gss') if not area_code: return None area = get_object_or_404(Area, format=format, codes__type=area_code, codes__code=area_id) return HttpResponseRedirect('/area/%d%s' % (area.id, '.%s' % format if format else ''))
def example_postcode_for_area(request, area_id, legacy=False): area = get_object_or_404(Area, id=area_id) if isinstance(area, HttpResponse): return area try: pc = Postcode.objects.filter(areas=area).order_by('?')[0] except: try: pc = Postcode.objects.filter(location__contained=area.polygons.all().collect()).order_by('?')[0] except: pc = None if pc: pc = pc.get_postcode_display() return output_json(pc)
def area_touches(request, area_id, format='json'): area = get_object_or_404(Area, id=area_id) if isinstance(area, HttpResponse): return area all_areas = area.polygons.all() if len(all_areas) > 1: all_areas = all_areas.collect() elif len(all_areas) == 1: all_areas = all_areas[0].polygon else: return output_json({ 'error': 'No polygons found' }, code=404) areas = Area.objects.filter(polygons__polygon__touches=all_areas, type=area.type) if format == 'html': return output_html( areas ) return output_json( dict( (a.id, a.as_dict() ) for a in areas ) )
def area_intersect(query_type, title, request, area_id, format): area = get_object_or_404(Area, format=format, id=area_id) if isinstance(area, HttpResponse): return area all_areas = area.polygons.all() if len(all_areas) > 1: all_areas = all_areas.collect() elif len(all_areas) == 1: all_areas = all_areas[0].polygon else: return output_error(format, 'No polygons found', 404) generation = Generation.objects.current() args = { 'generation_low__lte': generation, 'generation_high__gte': generation, } type = request.REQUEST.get('type', '') if ',' in type: args['type__in'] = type.split(',') elif type: args['type'] = type elif area.type in ('EUR'): args['type'] = area.type if isinstance(query_type, list): or_queries = [ Q(**{'polygons__polygon__%s' % t: all_areas}) for t in query_type ] areas = Area.objects.exclude(id=area.id).filter(**args) areas = areas.filter(reduce(operator.or_, or_queries)) elif len(all_areas) == 1: areas = Area.objects.intersect(query_type, area) areas = areas.exclude(id=area.id).filter(**args) else: areas = Area.objects.exclude(id=area.id).filter(**args) areas = areas.filter(**{'polygons__polygon__%s' % query_type : all_areas }) areas = areas.distinct() set_timeout(format) try: if format == 'html': return output_html(request, title % ('<a href="/area/%d.html">%s</a>' % (area.id, area.name)), areas, norobots=True ) return output_json( dict( (a.id, a.as_dict() ) for a in areas ) ) except QueryCanceledError: return output_error(format, 'That query was taking too long to compute - try restricting to a specific type, if you weren\'t already doing so.', 500)
def example_postcode_for_area(request, area_id, format='json'): area = get_object_or_404(Area, format=format, id=area_id) try: pc = Postcode.objects.filter(areas=area).order_by()[0] except: set_timeout(format) try: pc = Postcode.objects.filter_by_area(area).order_by()[0] except QueryCanceledError: raise ViewException(format, 'That query was taking too long to compute.', 500) except DatabaseError, e: if 'canceling statement due to statement timeout' not in e.args[0]: raise raise ViewException(format, 'That query was taking too long to compute.', 500) except: pc = None
def area_code_lookup(request, area_id, format): from mapit.models import Area, CodeType area_code = None if re.match('\d\d([A-Z]{2}|[A-Z]{4}|[A-Z]{2}\d\d\d|[A-Z]|[A-Z]\d\d)$', area_id): area_code = CodeType.objects.get(code='ons') if re.match('[ENSW]\d{8}$', area_id): area_code = CodeType.objects.get(code='gss') if not area_code: return None area = get_object_or_404(Area, format=format, codes__type=area_code, codes__code=area_id) path = '/area/%d%s' % (area.id, '.%s' % format if format else '') # If there was a query string, make sure it's passed on in the # redirect: if request.META['QUERY_STRING']: path += "?" + request.META['QUERY_STRING'] return HttpResponseRedirect(path)
def area(request, area_id, format='json'): if hasattr(countries, 'area_code_lookup'): resp = countries.area_code_lookup(area_id, format) if resp: return resp if not re.match('\d+$', area_id): return output_error(format, 'Bad area ID specified', 400) area = get_object_or_404(Area, format=format, id=area_id) if isinstance(area, HttpResponse): return area if format == 'html': return render(request, 'mapit/area.html', { 'area': area, 'show_geometry': (area.type.code not in ('EUR', 'SPE', 'WAE')) }) return output_json( area.as_dict() )
def example_postcode_for_area(request, area_id, legacy=False, format='json'): area = get_object_or_404(Area, format=format, id=area_id) if isinstance(area, HttpResponse): return area try: pc = Postcode.objects.filter(areas=area).order_by()[0] except: set_timeout(format) try: pc = Postcode.objects.filter_by_area(area).order_by()[0] except QueryCanceledError: return output_error(format, 'That query was taking too long to compute.', 500) except: pc = None if pc: pc = pc.get_postcode_display() if format == 'html': return render_to_response('example-postcode.html', { 'area': area, 'postcode': pc }) return output_json(pc)
def area_intersect(query_type, title, request, area_id, format): area = get_object_or_404(Area, format=format, id=area_id) if isinstance(area, HttpResponse): return area if not area.polygons.count(): return output_error(format, 'No polygons found', 404) generation = Generation.objects.current() args = { 'generation_low__lte': generation, 'generation_high__gte': generation, } type = request.REQUEST.get('type', '') if ',' in type: args['type__code__in'] = type.split(',') elif type: args['type__code'] = type elif area.type.code in ('EUR'): args['type__code'] = area.type.code set_timeout(format) areas = Area.objects.intersect( query_type, area).exclude(id=area.id).filter(**args).distinct() try: if format == 'html': return output_html(request, title % ('<a href="/area/%d.html">%s</a>' % (area.id, area.name)), areas, norobots=True) return output_json(dict((a.id, a.as_dict()) for a in areas)) except QueryCanceledError: return output_error( format, 'That query was taking too long to compute - try restricting to a specific type, if you weren\'t already doing so.', 500) except DatabaseError, e: # Django 1.2+ catches QueryCanceledError and throws its own DatabaseError instead if 'canceling statement due to statement timeout' not in e.args[0]: raise return output_error( format, 'That query was taking too long to compute - try restricting to a specific type, if you weren\'t already doing so.', 500)
def area(request, area_id, format='json'): if hasattr(countries, 'area_code_lookup'): resp = countries.area_code_lookup(area_id, format) if resp: return resp if not re.match('\d+$', area_id): return output_error(format, 'Bad area ID specified', 400) area = get_object_or_404(Area, format=format, id=area_id) if isinstance(area, HttpResponse): return area if format == 'html': return render( request, 'mapit/area.html', { 'area': area, 'show_geometry': (area.type.code not in ('EUR', 'SPE', 'WAE')) }) return output_json(area.as_dict())
def area_polygon(request, srid='', area_id='', format='kml'): if not srid and hasattr(countries, 'area_code_lookup'): resp = countries.area_code_lookup(request, area_id, format) if resp: return resp args = query_args_polygon(request, format, srid, [area_id]) area = get_object_or_404(Area, id=area_id) try: output, content_type = area.export(args['srid'], format, simplify_tolerance=args['simplify_tolerance']) if output is None: return output_json({'error': _('No polygons found')}, code=404) except TransformError as e: return output_json({'error': e.args[0]}, code=400) return output_polygon(content_type, output)
def example_postcode_for_area(request, area_id, format='json'): area = get_object_or_404(Area, format=format, id=area_id) try: pc = Postcode.objects.filter(areas=area).order_by()[0] except: set_timeout(format) try: pc = Postcode.objects.filter_by_area(area).order_by()[0] except DatabaseError as e: if 'canceling statement due to statement timeout' not in e.args[0]: raise raise ViewException(format, 'That query was taking too long to compute.', 500) except: pc = None if pc: pc = pc.get_postcode_display() if format == 'html': return render(request, 'mapit/example-postcode.html', {'area': area, 'postcode': pc}) return output_json(pc)
def _area_geometry(area_id): area = get_object_or_404(Area, id=area_id) if isinstance(area, HttpResponse): return area all_areas = area.polygons.all().collect() if not all_areas: return output_json({ 'error': 'No polygons found' }, code=404) out = { 'area': all_areas.area, 'parts': all_areas.num_geom, 'centre_e': all_areas.centroid[0], 'centre_n': all_areas.centroid[1], } out['min_e'], out['min_n'], out['max_e'], out['max_n'] = all_areas.extent all_areas.transform(4326) out['min_lon'], out['min_lat'], out['max_lon'], out['max_lat'] = all_areas.extent #all_areas.centroid.transform(4326) out['centre_lon'] = all_areas.centroid[0] out['centre_lat'] = all_areas.centroid[1] return out
def area(request, area_id, format=''): if hasattr(countries, 'area_code_lookup'): resp = countries.area_code_lookup(request, area_id, format) if resp: return resp if not re.match(r'\d+$', area_id): raise ViewException(format, _('Bad area ID specified'), 400) area = get_object_or_404(Area, format=format, id=area_id) codes = [] for code_type, code in sorted(area.all_codes.items()): code_link = None if code_type in ('osm', 'osm_rel'): code_link = 'http://www.openstreetmap.org/browse/relation/' + code elif code_type == 'osm_way': code_link = 'http://www.openstreetmap.org/browse/way/' + code codes.append((code_type, code, code_link)) # Sort any alternative names by the description of the name (the # English name of the language for global MapIt) and exclude the # default OSM name, since if that exists, it'll already be # displayed as the page title. names = Name.objects.filter(area=area).select_related() alternative_names = sorted((n.type.description, n.name) for n in names if n.type.code != "default") geotype = {} if hasattr(countries, 'restrict_geo_html'): geotype = countries.restrict_geo_html(area) if format == 'html': return render( request, 'mapit/area.html', { 'area': area, 'codes': codes, 'alternative_names': alternative_names, 'geotype': geotype, }) return output_json(area.as_dict(names))
def area_children(request, area_id, format='json'): area = get_object_or_404(Area, format=format, id=area_id) generation = request.REQUEST.get('generation', Generation.objects.current()) if not generation: generation = Generation.objects.current() args = { 'generation_low__lte': generation, 'generation_high__gte': generation, } type = request.REQUEST.get('type', '') if ',' in type: args['type__code__in'] = type.split(',') elif type: args['type__code'] = type children = add_codes(area.children.filter(**args)) if format == 'html': return output_html(request, 'Children of %s' % area.name, children) return output_json( dict( (child.id, child.as_dict() ) for child in children ) )
def check_postcode(format, postcode): postcode = re.sub('[^A-Z0-9]', '', postcode.upper()) if not is_valid_postcode(postcode): return bad_request(format, "Postcode '%s' is not valid." % postcode) postcode = get_object_or_404(Postcode, format=format, postcode=postcode) return postcode
def area_children(request, area_id, format='json'): args = query_args(request, format) area = get_object_or_404(Area, format=format, id=area_id) children = area.children.filter(**args) return output_areas(request, 'Children of %s' % area.name, format, children)