def getYearSounds(spriteData, userOptions={}):
    global items
    cfg = {
        "dimension": 2 # use z-axis
    }

    yearCol = "year"
    if yearCol not in items[0]:
        print("Could not find column %s in items, please add this column to metadata cols with 'type' = 'int'" % yearCol)
        sys.exit()

    sprites = spriteCount = None
    if spriteData is not None:
        sprites = spriteData["sprites"]
        spriteCount = len(sprites)

    years = [item[yearCol] for item in items]
    minYear = min(years)
    maxYear = max(years) + 1
    nUnit = 1.0 / (maxYear-minYear)

    sounds = []
    for i in range(maxYear-minYear):
        x = y = 0.5
        year = minYear + i
        z = mu.norm(year, (minYear, maxYear)) + nUnit*0.5 # center
        sounds += [round(x, PRECISION), round(y, PRECISION), round(z, PRECISION)]
        if sprites is not None:
            spriteIndex = mu.roundInt(1.0 * z * (spriteCount-1))
            sprite = sprites[spriteIndex]
            sounds += [sprite["start"], sprite["dur"]]

    return (cfg, sounds)
def getGeographyBarsLayout(userOptions={}):
    global items
    cfg = {
        "layout": "bars"
    }

    latCol = "lat"
    lonCol = "lon"
    if latCol not in items[0] or lonCol not in items[0]:
        print("`latitudeColumn` and `latitudeColumn` need to be set in config yml to support geographyBars layout")
        return (False, False)

    # create unique key for lat lon
    for i, item in enumerate(items):
        items[i]["lonLatKey"] = (mu.roundInt(item[lonCol]*PRECISION), mu.roundInt(item[latCol]*PRECISION))

    latRange = (90.0, -90.0)
    lonRange = (-180.0, 180.0)
    dimensions = 3
    groups = lu.groupList(items, "lonLatKey") # group by lat lon
    counts = [group["count"] for group in groups]
    minCount, maxCount = (min(counts), max(counts))

    # assign position values
    values = np.zeros(len(items) * dimensions)
    for group in groups:
        y = mu.norm(group["count"], (minCount, maxCount))
        y = mu.lerp((0.01, 1.0), y)
        for item in group["items"]:
            itemIndex = item["index"]
            x = 1.0 - mu.norm(item[lonCol], lonRange)
            z = 1.0 - mu.norm(item[latCol], latRange)
            itemY = y
            # a bit of a hack to ensure highighted items are visible
            if itemHasStory(item):
                itemY = y + 1.05
            values[itemIndex*dimensions] = round(x, PRECISION)
            values[itemIndex*dimensions+1] = round(itemY, PRECISION)
            values[itemIndex*dimensions+2] = round(z, PRECISION)

    values = values.tolist()
    return (cfg, values)
Beispiel #3
0
def getCategoryTimelineHotspot(view, content):
    global items
    global sets

    year = None

    if "year" in content:
        year = content["year"]
    elif "visibleTimeRange" in content:
        year = mu.roundInt(mu.lerp(tuple(content["visibleTimeRange"]), 0.5))

    if year is None:
        print("Need to set year or time range in content")
        return None

    yearCol = "year"
    if yearCol not in items[0]:
        print(
            "Could not find column %s in items, please add this column to metadata cols with 'type' = 'int'"
            % yearCol)
        return None
    years = [item[yearCol] for item in items]
    minYear = min(years)
    maxYear = max(years) + 1
    nUnit = 1.0 / (maxYear - minYear)

    if "category" not in sets:
        print("Could not find column 'category' in sets")
        return None

    categories = sets["category"]
    if "category" not in content:
        print("Could not find column 'category' in content")
        return None
    if content["category"] not in categories:
        print("Could not find %s in categories" % content["category"])
        return None

    categoryCount = len(categories)
    categoryIndex = categories.index(content["category"])

    # place at in the center of the year
    z = mu.norm(year, (minYear, maxYear)) + nUnit * 0.5
    # place at center of region
    x = 1.0 - 1.0 * categoryIndex / (categoryCount - 1)
    # place at top of bounds
    y = 0.0
    return {
        "x": round(x, PRECISION),
        "y": round(y, PRECISION),
        "z": round(z, PRECISION)
    }
Beispiel #4
0
def getGeographyBarsLayout(userOptions={}):
    global items
    cfg = {"layout": "bars"}

    latCol = "lat"
    lonCol = "lon"
    if latCol not in items[0] or lonCol not in items[0]:
        print(
            "Could not find column (%s, %s) in items, please add these columns to metadata cols with 'type' = 'float'"
            % (lonCol, latCol))
        sys.exit()

    # create unique key for lat lon
    for i, item in enumerate(items):
        items[i]["lonLatKey"] = (mu.roundInt(item[lonCol] * PRECISION),
                                 mu.roundInt(item[latCol] * PRECISION))

    latRange = (90.0, -90.0)
    lonRange = (-180.0, 180.0)
    dimensions = 3
    groups = lu.groupList(items, "lonLatKey")  # group by lat lon
    counts = [group["count"] for group in groups]
    minCount, maxCount = (min(counts), max(counts))

    # assign position values
    values = np.zeros(len(items) * dimensions)
    for group in groups:
        y = mu.norm(group["count"], (minCount, maxCount))
        y = mu.lerp((0.01, 1.0), y)
        for item in group["items"]:
            itemIndex = item["index"]
            x = 1.0 - mu.norm(item[lonCol], lonRange)
            z = 1.0 - mu.norm(item[latCol], latRange)
            values[itemIndex * dimensions] = round(x, PRECISION)
            values[itemIndex * dimensions + 1] = round(y, PRECISION)
            values[itemIndex * dimensions + 2] = round(z, PRECISION)

    values = values.tolist()
    return (cfg, values)
Beispiel #5
0
def makeCategoryTrackOverlay(filename, width=2048, lineThickness=4):
    global categories

    categoryCount = len(categories)

    if categoryCount < 1:
        return

    height = width
    baseImg = Image.new(mode="RGB", size=(width, height), color=(255, 255, 255))
    draw = ImageDraw.Draw(baseImg)

    barWidth = (width - (categoryCount-1) * lineThickness) / categoryCount
    for i, cat in enumerate(categories):
        x0 = mu.roundInt(i * (barWidth + lineThickness))
        x1 = mu.roundInt(x0 + barWidth)
        y0 = 0
        y1 = height
        if i >= (categoryCount-1):
            x1 = width
        draw.rectangle([x0, y0, x1, y1], fill=cat["color"])

    baseImg.save(filename)
Beispiel #6
0
def containImage(img, w, h, resampleType="default", bgcolor=[0,0,0]):
    # Lanczos = good for downsizing
    resampleType = Image.LANCZOS if resampleType=="default" else resampleType
    vw, vh = img.size

    if vw == w and vh == h:
        return img

    # create a base image
    w = mu.roundInt(w)
    h = mu.roundInt(h)
    if img.mode=="RGBA" and len(bgcolor)==3:
        bgcolor.append(0)
    baseImg = Image.new(mode=img.mode, size=(w, h), color=tuple(bgcolor))

    ratio = 1.0 * w / h
    vratio = 1.0 * vw / vh

    # first, resize image
    newW = w
    newH = h
    pasteX = 0
    pasteY = 0
    if vratio > ratio:
        newH = w / vratio
        pasteY = mu.roundInt((h-newH) * 0.5)
    else:
        newW = h * vratio
        pasteX = mu.roundInt((w-newW) * 0.5)
    try:
        resized = img.resize((mu.roundInt(newW), mu.roundInt(newH)), resample=resampleType)
        # then paste the resized image
        baseImg.paste(resized, (pasteX, pasteY))
    except OSError:
        print("Error in resizing")
        baseImg = None

    return baseImg
        cumulative = match["collection"]
        for division in divisions:
            if division in match and match[division] != "":
                breakdown.append(match[division])
        if len(breakdown) > 0:
            breakdown.append(cumulative-sum(breakdown))
        annualData[i]["cumulative"] = cumulative
        annualData[i]["breakdown"] = breakdown

# fill in the remainder data
model = annualData[-1]
for i, d in enumerate(annualData):
    if i > 0 and d["cumulative"] < 1:
        n = 1.0 * i / (len(annualData)-1)
        nEased = mu.ease(n, "quadIn")
        cumulative = mu.roundInt(nEased * model["cumulative"])
        annualData[i]["cumulative"] = cumulative

# add some randomness to the data
for i, d in enumerate(annualData):
    if i > 1 and i < len(annualData)-1:
        prev = annualData[i-1]
        delta = d["cumulative"] - prev["cumulative"]
        if delta > 0:
            half = mu.roundInt(delta * 0.5)
            random.seed(i)
            rdelta = random.randint(-int(half/2), int(half/2))
            annualData[i-1]["cumulative"] += rdelta
            annualData[i]["cumulative"] -= rdelta

# ensure each year increases
Beispiel #8
0
# Add item slides from stories to item metadata
storyItems = {}
if "stories" in config:
    stories = config["stories"]
    for key, story in stories.items():
        for slide in story["slides"]:
            if "itemId" in slide:
                slideMeta = slide.copy()
                slideMeta.pop("itemId", None)
                storyItems[str(slide["itemId"])] = slideMeta

itemsPerFile = a.ITEMS_PER_FILE
if itemsPerFile < 1:
    targetFiles = 1000
    itemsPerFile = mu.roundInt(1.0 * itemCount / targetFiles)
    itemsPerFile = min(itemsPerFile, 1000)

totalFiles = mu.ceilInt(1.0 * itemCount / itemsPerFile)
print(f'{itemsPerFile} per file with a total of {totalFiles} files')

fileItems = []
fileIndex = 0
for i, item in enumerate(items):

    itemOut = []
    for field in itemFields:
        if field["column"] not in item:
            continue
        value = item[field["column"]]