Example #1
0
def pointToWorld(point, view):
    bounds = view["bounds"]
    camPos = view["cameraPosition"]
    x = mu.lerp((bounds[1], bounds[0]), point["x"])
    y = camPos[1]
    z = mu.lerp((bounds[3], bounds[2]), point["y"])
    return { "x": x, "y": y, "z": z }
Example #2
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)
    }
Example #3
0
def getCountryLabels(userOptions={}):
    global items

    cfg = {}
    options = {"y": 0.5}
    options.update(userOptions)

    countryCol = "country"
    latCol = "lat"
    lonCol = "lon"
    if countryCol not in items[0]:
        print(
            "`countryColumn` needs to be set in config yml to support country labels; they will not show otherwise."
        )
        return (None, None)

    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 country labels; they will not show otherwise.")
        return (None, None)

    latRange = (90.0, -90.0)
    lonRange = (-180.0, 180.0)
    groups = lu.groupList(items, countryCol)  # group by country
    counts = [group["count"] for group in groups]
    minCount, maxCount = (min(counts), max(counts))
    labels = []
    for group in groups:
        firstItem = group["items"][0]
        label = firstItem[countryCol]
        lon = firstItem[lonCol]
        lat = firstItem[latCol]
        y = options["y"]
        x = 1.0 - mu.norm(lon, lonRange)
        z = 1.0 - mu.norm(lat, latRange)
        # HACK: offset z slightly to acommodate size of bar
        w = mu.norm(group["count"], (minCount, maxCount))
        w = mu.lerp((0.01, 1.0), w)
        # assume height is half the depth; divide by 6 for radius calculation (see geometry.js)
        radius = 0.5 / 6.0 * w + 0.005
        z = z - radius
        labels += [
            round(x, PRECISION),
            round(y, PRECISION),
            round(z, PRECISION), label
        ]

    return (cfg, labels)
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)
Example #5
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)
def makeSpriteFile(audioFn, dataFn, filenames, dur, matchDbValue=-9, reverb=0, quantities=None, sampleWidth=2, sampleRate=48000, channels=2):
    totalDuration = dur * len(filenames)
    if quantities is not None:
        totalDuration *= len(quantities)

    baseAudio = getBlankAudio(totalDuration, sampleWidth, sampleRate, channels)
    sprites = []

    for i, fn in enumerate(filenames):
        audio = getAudio(fn, sampleWidth, sampleRate, channels)
        audio = matchDb(audio, matchDbValue) # normalize audio
        if reverb > 0:
            audio = applyReverb(audio, reverb)

        if quantities is not None:
            for j, q in enumerate(quantities):
                sectionStart = i * len(quantities) * dur + j * dur
                sectionBaseAudio = getBlankAudio(dur, sampleWidth, sampleRate, channels)
                volumeRange = (0.2, 0.8)
                count = q["count"]
                clipDur = int(1.0 * dur / q["count"])
                audioClip = getAudioClip(audio, 0, clipDur, clipFadeIn=10, clipFadeOut=10)
                for k in range(q["count"]):
                    p = 1.0 * k / (q["count"]-1)
                    volume = mu.lerp((volumeRange[1], volumeRange[0]), p)
                    qstart = k * clipDur
                    dbAdjust = volumeToDb(volume)
                    modifiedAudio = audioClip.apply_gain(dbAdjust)
                    sectionBaseAudio = sectionBaseAudio.overlay(modifiedAudio, position=qstart)
                audioDur = len(sectionBaseAudio)
                # clip audio if necessary
                if audioDur > dur:
                    sectionBaseAudio = sectionBaseAudio[:dur]
                # fade in and out
                sectionBaseAudio = sectionBaseAudio.fade_in(10).fade_out(20)
                baseAudio = baseAudio.overlay(sectionBaseAudio, position=sectionStart)
                sprite = {
                    "src": os.path.basename(fn),
                    "start": sectionStart,
                    "dur": dur,
                    "quantity": q["name"]
                }
                sprites.append(sprite)
        else:
            start = i*dur
            audioDur = len(audio)
            # clip audio if necessary
            if audioDur > dur:
                audio = audio[:dur]
            # fade in and out
            audio = audio.fade_in(10).fade_out(20)
            # paste section on base audio
            baseAudio = baseAudio.overlay(audio, position=start)
            sprite = {
                "src": os.path.basename(fn),
                "start": start,
                "dur": dur
            }
            sprites.append(sprite)

    format = os.path.basename(audioFn).split(".")[-1]
    baseAudio.export(audioFn, format=format)
    jsonOut = {
        "name": os.path.basename(audioFn),
        "sprites": sprites
    }
    io.writeJSON(dataFn, jsonOut, pretty=True)
    return jsonOut
            # for each chunk
            groupChunks = []
            for l in range(chunkCount):

                # for each dot
                chunkDots = []
                for m in range(chunkSize):
                    groupItemsIndex = l * chunkSize + m

                    if groupItemsIndex >= len(groupItems):
                        break

                    # determine pixel color
                    item = groupItems[groupItemsIndex]
                    r = g = b = int(
                        round(mu.lerp((255 - a.MIN_ALPHA, 0), item["nalpha"])))
                    if confidenceKey is not None:
                        confidence = item[confidenceKey]
                        if confidence < 1.0:
                            if item["Acquisition Year"] >= 9999:
                                r = g = b = 0
                            r = int(round(mu.lerp((255.0, r), confidence)))

                    # determine position
                    dotRow = int(1.0 * m / chunkColCount)
                    dotCol = m % chunkColCount
                    dotDrawData = {
                        "x": dotCol * a.DOT_WIDTH + dotCol - 1,
                        "y": dotRow * a.DOT_WIDTH + dotRow - 1,
                        "width": a.DOT_WIDTH,
                        "height": a.DOT_WIDTH,
Example #8
0
def getSphereCategoryTimelineLayout(userOptions={}):
    global items
    global sets
    cfg = {"layout": "spheres"}

    categoryCol = "category"
    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()
    if categoryCol not in sets:
        print(
            "Could not find column %s in sets, please add this column to metadata cols with 'asIndex' = true"
            % categoryCol)
        sys.exit()

    categorySet = sets[categoryCol]
    categoryCount = len(categorySet)
    dimensions = 3
    groups = lu.groupList(items, yearCol)  # group by year
    groups = sorted(groups, key=lambda group: group[yearCol])
    years = [item[yearCol] for item in items]
    minYear = min(years)
    maxYear = max(years) + 1
    nUnit = 1.0 / (maxYear - minYear)

    # determine category sphere count range
    minCount = 9999999999
    maxCount = 0
    for i, group in enumerate(groups):
        subgroups = lu.groupList(group["items"],
                                 categoryCol)  # group by category
        for subgroup in subgroups:
            minCount = min(minCount, subgroup["count"])
            maxCount = max(maxCount, subgroup["count"])
        groups[i]["categoryGroups"] = subgroups

    # assign position values
    values = np.zeros(len(items) * dimensions)
    for i, group in enumerate(groups):
        z = mu.norm(
            group[yearCol],
            (minYear,
             maxYear)) + nUnit * 0.5  # place spheres in the center of the year
        subgroups = group["categoryGroups"]
        subgroupLookup = lu.createLookup(subgroups, categoryCol)
        for j, category in enumerate(categorySet):
            x = 1.0 - 1.0 * j / (categoryCount - 1)
            categoryKey = str(j)
            if categoryKey in subgroupLookup:
                subgroup = subgroupLookup[categoryKey]
                y = mu.norm(subgroup["count"], (minCount, maxCount))
                y = mu.lerp((0.01, 1.0), y)
                for catItem in subgroup["items"]:
                    itemIndex = catItem["index"]
                    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)
def getSphereCategoryTimelineLayout(userOptions={}):
    global items
    global categories
    cfg = {
        "layout": "spheres"
    }

    categoryCol = "category"
    yearCol = "year"
    if yearCol not in items[0]:
        print("`dateColumn` needs to be set in config yml to support timelineTracks layout")
        return (False, False)

    if categoryCol not in items[0]:
        print("`groupByColumn` needs to be set in config yml to support timelineTracks layout")
        return (False, False)

    categoryCount = len(categories)
    dimensions = 3
    groups = lu.groupList(items, yearCol) # group by year
    groups = sorted(groups, key=lambda group: group[yearCol])
    years = [item[yearCol] for item in items]
    minYear = min(years)
    maxYear = max(years) + 1
    nUnit = 1.0 / (maxYear-minYear)

    # determine category sphere count range
    minCount = 9999999999
    maxCount = 0
    for i, group in enumerate(groups):
        subgroups = lu.groupList(group["items"], categoryCol) # group by category
        for subgroup in subgroups:
            minCount = min(minCount, subgroup["count"])
            maxCount = max(maxCount, subgroup["count"])
        groups[i]["categoryGroups"] = subgroups

    # assign position values
    values = np.zeros(len(items) * dimensions)
    for i, group in enumerate(groups):
        z = mu.norm(group[yearCol], (minYear, maxYear)) + nUnit*0.5 # place spheres in the center of the year
        subgroups = group["categoryGroups"]
        subgroupLookup = lu.createLookup(subgroups, categoryCol)
        for j, category in enumerate(categories):
            x = 1.0 - 1.0 * j / (categoryCount-1)
            categoryKey = category["text"]
            if categoryKey in subgroupLookup:
                subgroup = subgroupLookup[categoryKey]
                y = mu.norm(subgroup["count"], (minCount, maxCount))
                y = mu.lerp((0.01, 1.0), y)
                for catItem in subgroup["items"]:
                    itemIndex = catItem["index"]
                    cy = y
                    # a bit of a hack to ensure highighted items are visible
                    if itemHasStory(catItem):
                        cy = y + 1.25
                    values[itemIndex*dimensions] = round(x, PRECISION)
                    values[itemIndex*dimensions+1] = round(cy, PRECISION)
                    values[itemIndex*dimensions+2] = round(z, PRECISION)

    values = values.tolist()

    return (cfg, values)