project/analysis/analyzers/render/default.py

166 lines
4.3 KiB
Python

import copy
import json
import logging
from typing import List
import datetime
import matplotlib.pyplot as plt
from analysis.analyzers import LogEntryCountAnalyzer
from analysis.util.meta_temp import GEOJSON_COORDINATES, GEOJSON_PATTERN, KML_PATTERN
from . import Render, Result
from analysis.analyzers import LocationAnalyzer
log = logging.getLogger(__name__)
class PrintRender(Render):
def render(self, results: List[Result], name=None):
print("\t" + "\n\t".join([str(r) for r in results]))
class JSONRender(Render):
def render(self, results: List[Result], name=None):
print(json.dumps([r.get() for r in self.filter(results)], indent=1))
class SpatialRender:
result_types = [LocationAnalyzer]
class TrackRender(SpatialRender, Render):
def render(self, results: List[Result], name=None):
data = []
log.debug(results)
for result in self.filter(results):
if len(result.get()) > 0:
data.append(
[[entry['location']['coordinates'][1], entry['location']['coordinates'][0]] for entry in
# TODO: configurable
result.get()])
dumps = json.dumps(data)
with open("track_data.js", "w") as out:
out.write("tracks=" + dumps + ";")
return dumps
def format_time(ts):
return datetime.datetime.fromtimestamp(ts / 1000).strftime("%Y-%m-%dT%H:%M:%S.%f")
class KMLRender(SpatialRender, Render):
def render(self, results: List[Result], name=None):
files = []
for result in self.filter(results):
times = ["<when>{time}</when>".format(time=format_time(entry["timestamp"])) for entry in result.get()]
coords = [
"<gx:coord>{long} {lat} 0.0</gx:coord>"
.format(
lat=entry['location']['coordinates'][1],
long=entry['location']['coordinates'][0])
for entry in result.get()
]
if name:
filename = str(name) + ".kml"
else:
filename = str(result.name) + ".kml"
print(filename)
with open(filename, "w") as out:
out.write(
KML_PATTERN.format(name=str(result.name), coordinates="\n".join(coords), when="\n".join(times)))
#with open(filename + ".json", "w") as out: #FIXME: why am I here??
# json.dump(result.get(), out, indent=1)
files.append(filename)
return files
class GeoJSON(SpatialRender, Render):
template = {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "LineString",
"coordinates": []
}
}
]
}
def make_geojson(self, src):
coordinates = []
times = []
for location in src:
#print(location)
coordinates.append(location["location"]["coordinates"])
times.append(location["timestamp"])
template = copy.deepcopy(self.template)
template["features"][0]["properties"] = {"times": times}
template["features"][0]["geometry"]["coordinates"] = coordinates
return template
def render(self, results: List[Result], name=None) -> [str]:
files = []
for result in self.filter(results):
if name:
filename = str(name) + ".geojson"
else:
filename = str(result.name) + ".geojson"
json = self.make_geojson(result.get())
with open(filename, "w") as out:
json.dump(self.template, out, indent=1)
files.append(filename)
return files
class HeatMapRender(TrackRender):
weight = 0.01
def render(self, results: List[Result], name=None):
raw = super(HeatMapRender, self).render(results)
data = []
for session in json.loads(raw):
data += [(entry[0], entry[1], self.weight) for entry in session]
dumps = json.dumps(data)
with open('heat_data.js', 'w') as out:
out.write("coords = " + dumps + ";")
return dumps
class LogEntryCountAnalyzerPlot(Render):
result_types = [LogEntryCountAnalyzer]
def render(self, results: List[Result], name=None):
raw_data = list(self.filter(results))[0].get()
print(raw_data)
labels = []
data = []
for x in sorted(raw_data.items()):
labels.append(str(x[0]).split(".")[-1])
data.append(x[1])
plt.bar(range(len(data)), list(data))
plt.xticks(range(len(data)), labels, rotation="vertical")
plt.tight_layout()
name = "plots/{}.png".format(name)
plt.savefig(name)
plt.cla()
plt.clf()
plt.close()
class LogEntryCountCSV(Render):
result_types = [LogEntryCountAnalyzer]
summary = None
def render(self, results: List[Result], name=None):
if self.summary is None:
return
for result in self.filter(results):
raw_data = result.get()
self.summary[name] = raw_data