Esempio n. 1
0
File: api.py Progetto: yeleman/dmd
def json_data_record_for(request, period_str, entity_uuid, indicator_slug):

    entity = Entity.get_or_none(entity_uuid)
    if entity is None:
        raise Http404(_("Unknown entity UUID `{u}`").format(u=entity_uuid))

    period = process_period_filter(request, period_str, 'period').get('period')
    if period is None:
        raise Http404(_("Unknown period `{p}`").format(p=period_str))

    indicator = Indicator.get_or_none(indicator_slug)
    if indicator is None:
        raise Http404(_("Unknown indicator `{s}`").format(s=indicator_slug))

    return JsonResponse(DataRecord.get_for(period, entity, indicator),
                        safe=False)
Esempio n. 2
0
def json_data_record_for(request, period_str, entity_uuid, indicator_slug):

    entity = Entity.get_or_none(entity_uuid)
    if entity is None:
        raise Http404(_("Unknown entity UUID `{u}`").format(u=entity_uuid))

    period = process_period_filter(request, period_str, 'period').get('period')
    if period is None:
        raise Http404(_("Unknown period `{p}`").format(p=period_str))

    indicator = Indicator.get_or_none(indicator_slug)
    if indicator is None:
        raise Http404(_("Unknown indicator `{s}`").format(s=indicator_slug))

    return JsonResponse(DataRecord.get_for(period, entity, indicator),
                        safe=False)
Esempio n. 3
0
File: gis.py Progetto: yeleman/dmd
def gen_map_for(entity, periods, indicator, save_as=None,
                with_title=True, with_legend=True,
                with_index=True, with_scale=True):

    children = sorted(entity.get_children(), key=lambda x: x.short_name)
    bbox = children_bounds(entity)

    # data = indicator.data_for(periods=periods, entity=entity)
    data = DataRecord.get_for(periods[-1] if periods else None,
                              entity, indicator)
    # from pprint import pprint as pp ; pp(data.values())
    scale = QuantileScale(values=[x['value'] for x in data.values()],
                          colors=MAP_COLORS)

    def color_for(e):
        if data is None:
            return COLOR_INITIAL
        try:
            return scale.color_for_value(data[e.uuids]['value'])
        except KeyError:
            return COLOR_INITIAL

    # setup coordinate system
    xdist = bbox[2] - bbox[0]
    ydist = bbox[3] - bbox[1]
    iwidth = CANVAS_SIZE
    iheight = CANVAS_SIZE
    xratio = iwidth / xdist
    yratio = iheight / ydist

    def mmap(x, y):
        return int(iwidth - ((bbox[2] - x) * xratio)), \
            int((bbox[3] - y) * yratio)

    # blank (transparent) sheet
    image = get_image(CANVAS_SIZE, CANVAS_SIZE)

    # draw each feature independently
    for index, child in enumerate(children):
        if not child.geojson.get('geometry'):
            continue
        pixels = []

        if child.geojson['geometry']['type'] == 'MultiPolygon':
            coordinates = child.geojson['geometry']['coordinates']
        else:
            coordinates = [child.geojson['geometry']['coordinates']]

        pixels = [mmap(x, y)
                  for feature_coord in coordinates
                  for x, y in feature_coord[0]]

        # draw polygon
        feature_draw = ImageDraw.Draw(image)
        feature_draw.polygon(pixels,
                             outline=OUTLINE_COLOR,
                             fill=color_for(child))

        # draw thicker boundaries
        feature_draw.line(pixels, fill=OUTLINE_COLOR, width=OUTLINE_WIDTH)
        for pixel in pixels:
            feature_draw.ellipse(
                (pixel[0] - OUTLINE_WIDTH // 2,
                 pixel[1] - OUTLINE_WIDTH // 2,
                 pixel[0] + OUTLINE_WIDTH // 2,
                 pixel[1] + OUTLINE_WIDTH // 2),
                fill=OUTLINE_COLOR)

        # draw a letter
        if with_index and child.gps:
            coords = mmap(*child.gps)
            negpad = CANVAS_SIZE // 80 // 2
            index_font = get_font('Regular', CANVAS_SIZE // 80, mono=True)
            feature_draw.text(
                (coords[0] - negpad, coords[1] - negpad),
                letter_for(index),
                font=index_font, fill=INDEX_COLOR)

    if with_legend:
        legend = build_legend_for(scale)
        image.paste(legend, (CANVAS_SIZE - LEGEND_PADDING - legend.size[0],
                             CANVAS_SIZE - LEGEND_PADDING - legend.size[1]),
                    mask=legend)

    if with_title:
        title = build_title_for(indicator, periods, entity)
        export_width = image.size[0] + title.size[1]
        export_height = CANVAS_SIZE + title.size[1]
        export_image = get_image(export_width, export_height)
        export_image.paste(title, (0, 0), mask=title)
        export_image.paste(image, (title.size[1], title.size[1]), mask=image)

        # replace main image with new one (larger with title)
        image = export_image

    if with_index:
        index = build_index_for(indicator, periods, children)
        ileft_coords = (INDEX_PADDING, title.size[1] + INDEX_PADDING)
        iright_coords = (image.size[0] - index.size[0] - INDEX_PADDING,
                         title.size[1] + INDEX_PADDING)
        index_coords = iright_coords if display_right(entity) else ileft_coords
        image.paste(index, index_coords,
                    mask=index)

    if with_scale:
        visual_scale = build_scale_for(bbox)
        image.paste(visual_scale,
                    (SCALE_PADDING,
                     image.size[1] - SCALE_PADDING - visual_scale.size[1]),
                    mask=visual_scale)

    # save end result to file or buffer
    if save_as:
        image.save(save_as, "PNG", mode="RGBA")
    else:
        return image