Example #1
0
def query_args(request, format, type=None):
    try:
        generation = int(request.GET.get('generation', 0))
    except ValueError:
        raise ViewException(format, 'Bad generation specified', 400)
    if not generation:
        generation = Generation.objects.current().id

    try:
        min_generation = int(request.GET.get('min_generation', 0))
    except ValueError:
        raise ViewException(format, 'Bad min_generation specified', 400)
    if not min_generation:
        min_generation = generation

    if type is None:
        type = request.GET.get('type', '')

    args = {}
    if min_generation > -1:
        args = {
            'generation_low__lte': generation,
            'generation_high__gte': min_generation,
        }
    if ',' in type:
        args['type__code__in'] = type.split(',')
    elif type:
        args['type__code'] = type

    return args
Example #2
0
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)
Example #3
0
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)
Example #4
0
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
Example #5
0
def nearest(request, srid, x, y, format='json'):
    location = Point(float(x), float(y), srid=int(srid))
    set_timeout(format)
    try:
        postcode = Postcode.objects.filter(
            location__distance_gte=(location, D(
                mi=0))).distance(location).order_by('distance')[0]
    except DatabaseError as e:
        if 'Cannot find SRID' in e.args[0]:
            raise ViewException(format, e.args[0], 400)
        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:
        raise ViewException(format,
                            'No postcode found near %s,%s (%s)' % (x, y, srid),
                            404)

    if format == 'html':
        return render(request, 'mapit/postcode.html', {
            'postcode': postcode.as_dict(),
            'json_view': 'mapit-postcode',
        })

    pc = postcode.as_dict()
    pc['distance'] = round(postcode.distance.m)
    return output_json({
        'postcode': pc,
    })
Example #6
0
def partial_postcode(request, postcode, format='json'):
    postcode = re.sub(r'\s+', '', postcode.upper())
    if is_valid_postcode(postcode):
        postcode = re.sub(r'\d[A-Z]{2}$', '', postcode)
    if not is_valid_partial_postcode(postcode):
        raise ViewException(format,
                            "Partial postcode '%s' is not valid." % postcode,
                            400)

    location = Postcode.objects.filter(postcode__startswith=postcode).extra(
        where=['length(postcode) = %d' % (len(postcode) + 3)]).aggregate(
            Collect('location'))['location__collect']
    if not location:
        raise ViewException(format, 'Postcode not found', 404)

    postcode = Postcode(postcode=postcode, location=location.centroid)

    if format == 'html':
        return render(
            request, 'mapit/postcode.html', {
                'postcode': postcode.as_dict(),
                'json_view': 'mapit-postcode-partial',
            })

    return output_json(postcode.as_dict())
Example #7
0
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)
Example #8
0
def nearest(request, srid, x, y, format='json'):
    location = Point(float(x), float(y), srid=int(srid))
    set_timeout(format)
    try:
        postcode = Postcode.objects.filter(location__distance_gte=( location, D(mi=0) )).distance(location).order_by('distance')[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)
Example #9
0
def area_from_code(request, code_type, code_value, format='json'):
    args = query_args(request, format)
    args['codes__type__code'] = code_type
    args['codes__code'] = code_value
    try:
        area = Area.objects.get(**args)
    except Area.DoesNotExist:
        message = 'No areas were found that matched code %s = %s.' % (code_type, code_value)
        raise ViewException(format, message, 404)
    except Area.MultipleObjectsReturned:
        message = 'There were multiple areas that matched code %s = %s.' % (code_type, code_value)
        raise ViewException(format, message, 500)
    return HttpResponseRedirect("/area/%d%s" % (area.id, '.%s' % format if format else ''))
Example #10
0
def area_from_code(request, code_type, code_value, format='json'):
    q = query_args(request, format)
    q &= Q(codes__type__code=code_type, codes__code=code_value)
    try:
        area = Area.objects.get(q)
    except Area.DoesNotExist:
        message = _('No areas were found that matched code {0} = {1}.').format(code_type, code_value)
        raise ViewException(format, message, 404)
    except Area.MultipleObjectsReturned:
        message = _('There were multiple areas that matched code {0} = {1}.').format(code_type, code_value)
        raise ViewException(format, message, 500)
    area_kwargs = {'area_id': area.id}
    if format:
        area_kwargs['format'] = format
    return HttpResponseRedirect(reverse('area', kwargs=area_kwargs))
Example #11
0
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
Example #12
0
def query_args_polygon(request, format, srid, area_ids):
    args = {}
    if not srid:
        srid = 4326 if format in ('kml', 'json', 'geojson') else settings.MAPIT_AREA_SRID
    args['srid'] = int(srid)

    try:
        args['simplify_tolerance'] = float(request.GET.get('simplify_tolerance', 0))
    except ValueError:
        raise ViewException(format, _('Badly specified tolerance'), 400)

    for area_id in area_ids:
        if not re.match('\d+$', area_id):
            raise ViewException(format, _('Bad area ID specified'), 400)

    return args
Example #13
0
def areas_by_point(request, srid, x, y, bb=False, format=''):
    location = Point(float(x), float(y), srid=int(srid))

    use_exceptions()

    try:
        location.transform(settings.MAPIT_AREA_SRID, clone=True)
    except:
        raise ViewException(format, _('Point outside the area geometry'), 400)

    method = 'box' if bb and bb != 'polygon' else 'polygon'

    q = query_args(request, format)

    if method == 'box':
        q &= Q(polygons__polygon__bbcontains=location)
    else:
        q &= Q(polygons__polygon__contains=location)
    areas = Area.objects.filter(q).distinct()

    return output_areas(request,
                        _('Areas covering the point ({0},{1})').format(x, y),
                        format,
                        areas,
                        indent_areas=True)
Example #14
0
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)
Example #15
0
def areas_by_point(request, srid, x, y, bb=False, format='json'):
    type = request.REQUEST.get('type', '')
    generation = request.REQUEST.get('generation',
                                     Generation.objects.current())
    if not generation: generation = Generation.objects.current()

    location = Point(float(x), float(y), srid=int(srid))
    gdal.UseExceptions()
    try:
        location.transform(settings.MAPIT_AREA_SRID, clone=True)
    except:
        raise ViewException(format, 'Point outside the area geometry', 400)

    method = 'box' if bb and bb != 'polygon' else 'polygon'

    args = {
        'generation_low__lte': generation,
        'generation_high__gte': generation
    }

    if ',' in type:
        args['type__code__in'] = type.split(',')
    elif type:
        args['type__code'] = type

    if type and method == 'polygon':
        args = dict(("area__%s" % k, v) for k, v in args.items())
        # So this is odd. It doesn't matter if you specify types, PostGIS will
        # do the contains test on all the geometries matching the bounding-box
        # index, even if it could be much quicker to filter some out first
        # (ie. the EUR ones).
        args['polygon__bbcontains'] = location
        shapes = Geometry.objects.filter(**args).defer('polygon')
        areas = []
        for shape in shapes:
            try:
                areas.append(
                    Area.objects.get(polygons__id=shape.id,
                                     polygons__polygon__contains=location))
            except:
                pass
    else:
        if method == 'box':
            args['polygons__polygon__bbcontains'] = location
        else:
            geoms = list(
                Geometry.objects.filter(
                    polygon__contains=location).defer('polygon'))
            args['polygons__in'] = geoms
        areas = Area.objects.filter(**args)

    areas = add_codes(areas)
    if format == 'html':
        return output_html(request,
                           'Areas covering the point (%s,%s)' % (x, y),
                           areas,
                           indent_areas=True)
    return output_json(dict((area.id, area.as_dict()) for area in areas))
Example #16
0
def area_from_code(request, code_type, code_value, format='json'):
    args = query_args(request, format)
    args['codes__type__code'] = code_type
    args['codes__code'] = code_value
    try:
        area = Area.objects.get(**args)
    except Area.DoesNotExist, e:
        message = 'No areas were found that matched code %s = %s.' % (code_type, code_value)
        raise ViewException(format, message, 404)
Example #17
0
def query_args(request, format, type=None):
    try:
        generation = int(request.GET.get('generation', 0))
    except ValueError:
        raise ViewException(format, _('Bad generation specified'), 400)
    if not generation:
        generation = Generation.objects.current().id

    try:
        min_generation = int(request.GET.get('min_generation', 0))
    except ValueError:
        raise ViewException(format, _('Bad min_generation specified'), 400)
    if not min_generation:
        min_generation = generation

    if type is None:
        type = request.GET.get('type', '')
    country_code = request.GET.get('country', '')

    args = {}
    if min_generation > -1:
        args = {
            'generation_low__lte': generation,
            'generation_high__gte': min_generation,
        }

    query = Q(**args)

    for attr, value in [
        (['type'], type),
        (['country', 'countries'], country_code),
    ]:
        q = Q()
        for a in attr:
            if ',' in value:
                q |= Q(**{a + '__code__in': value.split(',')})
            elif value:
                q |= Q(**{a + '__code': value})
        query &= q

    return query
Example #18
0
def nearest(request, srid, x, y, format='json'):
    location = Point(float(x), float(y), srid=int(srid))
    set_timeout(format)

    try:
        # Transform to database SRID for comparison (GeometryCentroidDistance does not yet do this)
        location.transform(4326)
    except:
        raise ViewException(format, _('Point outside the area geometry'), 400)

    try:
        # Ordering will be in 'degrees', so fetch a few and sort by actual distance
        postcodes = Postcode.objects.annotate(
            centroid_distance=GeometryCentroidDistance(
                'location', location)).annotate(distance=Distance(
                    'location', location)).order_by('centroid_distance')[:100]
        postcodes = sorted(postcodes, key=attrgetter('distance'))
        postcode = postcodes[0]
    except DatabaseError as e:
        if 'Cannot find SRID' in e.args[0]:
            raise ViewException(format, e.args[0], 400)
        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:
        raise ViewException(format,
                            'No postcode found near %s,%s (%s)' % (x, y, srid),
                            404)

    if format == 'html':
        return render(request, 'mapit/postcode.html', {
            'postcode': postcode.as_dict(),
            'json_view': 'mapit-postcode',
        })

    pc = postcode.as_dict()
    pc['distance'] = round(postcode.distance.m)
    return output_json({
        'postcode': pc,
    })
Example #19
0
def area_from_code(request, code_type, code_value, format='json'):
    generation = request.REQUEST.get('generation',
                                     Generation.objects.current())
    if not generation:
        generation = Generation.objects.current()
    try:
        area = Area.objects.get(codes__type__code=code_type,
                                codes__code=code_value,
                                generation_low__lte=generation,
                                generation_high__gte=generation)
    except Area.DoesNotExist, e:
        message = 'No areas were found that matched code %s = %s.' % (code_type, code_value)
        raise ViewException(format, message, 404)
Example #20
0
def areas_by_point(request, srid, x, y, bb=False, format='json'):
    location = Point(float(x), float(y), srid=int(srid))

    use_exceptions()

    try:
        location.transform(settings.MAPIT_AREA_SRID, clone=True)
    except:
        raise ViewException(format, _('Point outside the area geometry'), 400)

    method = 'box' if bb and bb != 'polygon' else 'polygon'

    args = query_args(request, format)
    type = request.GET.get('type', '')

    if type and method == 'polygon':
        args = dict(("area__%s" % k, v) for k, v in args.items())
        # So this is odd. It doesn't matter if you specify types, PostGIS will
        # do the contains test on all the geometries matching the bounding-box
        # index, even if it could be much quicker to filter some out first
        # (ie. the EUR ones).
        args['polygon__bbcontains'] = location
        shapes = Geometry.objects.filter(**args).defer('polygon')
        areas = []
        for shape in shapes:
            try:
                areas.append(
                    Area.objects.get(polygons__id=shape.id,
                                     polygons__polygon__contains=location))
            except:
                pass
    else:
        if method == 'box':
            args['polygons__polygon__bbcontains'] = location
        else:
            geoms = list(
                Geometry.objects.filter(
                    polygon__contains=location).defer('polygon'))
            args['polygons__in'] = geoms
        areas = Area.objects.filter(**args)

    return output_areas(request,
                        _('Areas covering the point ({0},{1})').format(x, y),
                        format,
                        areas,
                        indent_areas=True)
Example #21
0
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)
Example #22
0
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))
Example #23
0
    set_timeout(format)
    try:
        postcode = Postcode.objects.filter(
            location__distance_gte=(location, D(
                mi=0))).distance(location).order_by('distance')[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:
        raise ViewException(format,
                            'No postcode found near %s,%s (%s)' % (x, y, srid),
                            404)

    if format == 'html':
        return render(
            request, 'mapit/postcode.html', {
                'postcode': postcode.as_dict(),
                'json_view': 'mapit.views.postcodes.postcode',
            })

    pc = postcode.as_dict()
    pc['distance'] = round(postcode.distance.m)
    return output_json({
        'postcode': pc,
    })
Example #24
0
        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)
    except InternalError:
        raise ViewException(
            format, 'There was an internal error performing that query.', 500)

    if format == 'html':
        return output_html(request,
                           title %
                           ('<a href="%sarea/%d.html">%s</a>' %
                            (reverse('mapit_index'), area.id, area.name)),
                           areas,
                           norobots=True)
    return output_json(dict((a.id, a.as_dict()) for a in areas))


@ratelimit(minutes=3, requests=100)
def area_touches(request, area_id, format='json'):
    return area_intersect('touches', 'Areas touching %s', request, area_id,
                          format)
Example #25
0
def area_touches(request, area_id, format='json'):
    # XXX Exempt an error that throws a GEOS Exception
    if area_id == '2658':
        raise ViewException(format, 'There was an internal error performing that query.', 500)
    return area_intersect('touches', 'Areas touching %s', request, area_id, format)
Example #26
0
def check_area_ids(format, area_ids):
    for area_id in area_ids:
        if not re.match(r'\d+$', area_id):
            raise ViewException(format, _('Bad area ID specified'), 400)
Example #27
0
def get_object_or_404(klass, format='json', *args, **kwargs):
    try:
        return orig_get_object_or_404(klass, *args, **kwargs)
    except http.Http404 as e:
        from mapit.middleware import ViewException
        raise ViewException(format, str(e), 404)
Example #28
0
def convert_address(request, format='json'):
    address = request.GET.get('address')
    if not address:
        raise ViewException(format, 'No address was provided.', 400)

    converter = AddressConverter()
    locations = converter.resolve_address(address,
                                          partial=bool(
                                              request.GET.get('partial')))

    # this is a copy from mapit.views.areas.areas_by_point
    # because it's hard to reuse their code :(

    if PYGDAL:
        from osgeo import gdal
        gdal.UseExceptions()

    # we find areas for every lat/long coord we got back
    areas = []
    type = request.GET.get('type', '')
    for coords in locations:
        location = Point(float(coords['lng']), float(coords['lat']), srid=4326)
        try:
            location.transform(settings.MAPIT_AREA_SRID, clone=True)
        except:
            raise ViewException(format, _('Point outside the area geometry'),
                                400)

        args = query_args(request, format)
        if type:
            args = dict(("area__%s" % k, v) for k, v in args.items())
            # So this is odd. It doesn't matter if you specify types, PostGIS will
            # do the contains test on all the geometries matching the bounding-box
            # index, even if it could be much quicker to filter some out first
            # (ie. the EUR ones).
            coords['areas'] = []
            args['polygon__bbcontains'] = location
            shapes = Geometry.objects.filter(**args).defer('polygon')
            for shape in shapes:
                try:
                    area = Area.objects.get(
                        polygons__id=shape.id,
                        polygons__polygon__contains=location)
                    coords['areas'].append(str(area.id))
                    areas.append(area)
                except:
                    pass
        else:
            geoms = list(
                Geometry.objects.filter(
                    polygon__contains=location).defer('polygon'))
            args['polygons__in'] = geoms
            matches = Area.objects.filter(**args).all()
            coords['areas'] = [str(m.id) for m in matches]
            areas.extend(matches)

    areas = add_codes(areas)
    if format == 'html':
        return output_html(
            request,
            _("Areas matching the address '{0}'").format(address),
            areas,
            indent_areas=True)

    # hack to include the geocoded addresses in the results
    data = iterdict(
        chain(((area.id, area.as_dict()) for area in areas),
              [("addresses", locations)]))
    return output_json(data)