Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions added_locations.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[{"datetime": "2020-08-02T13:15:00", "position": {"type": "Point", "coordinates": [-15.528895845446813, 17.654046612805978]}}, {"datetime": "2020-08-02T13:20:00", "position": {"type": "Point", "coordinates": [-10.89935219622664, 26.46258578507198]}}, {"datetime": "2020-08-02T13:25:00", "position": {"type": "Point", "coordinates": [-12.437519592946614, 17.6231880600936]}}, {"datetime": "2020-08-02T13:30:00", "position": {"type": "Point", "coordinates": [-6.124614154977847, 27.532703560246155]}}, {"datetime": "2020-08-02T13:50:00", "position": {"type": "Point", "coordinates": [-15.399241292492714, 28.259275964081688]}}, {"datetime": "2020-08-03T00:35:00", "position": {"type": "Point", "coordinates": [21.441973204635552, 12.068393628524072]}}, {"datetime": "2020-08-03T03:00:00", "position": {"type": "Point", "coordinates": [-13.950751649319617, 16.268148347626877]}}, {"datetime": "2020-08-03T03:15:00", "position": {"type": "Point", "coordinates": [-16.39721357821592, 14.411531659541048]}}, {"datetime": "2020-08-03T03:25:00", "position": {"type": "Point", "coordinates": [-9.712259931791468, 23.140916549486946]}}, {"datetime": "2020-08-03T03:40:00", "position": {"type": "Point", "coordinates": [-21.00702695240026, 20.341405667191584]}}, {"datetime": "2020-08-03T03:45:00", "position": {"type": "Point", "coordinates": [-15.402484255592437, 21.937926531393295]}}, {"datetime": "2020-08-03T04:15:00", "position": {"type": "Point", "coordinates": [-21.35592413270321, 9.71380945775364]}}, {"datetime": "2020-08-03T04:55:00", "position": {"type": "Point", "coordinates": [-28.974312566024835, 2.51286060065754]}}, {"datetime": "2020-08-03T05:40:00", "position": {"type": "Point", "coordinates": [-22.168453897382168, 9.391664166981538]}}, {"datetime": "2020-08-03T05:45:00", "position": {"type": "Point", "coordinates": [-25.543959517336813, 5.541951190777789]}}, {"datetime": "2020-08-03T09:55:00", "position": {"type": "Point", "coordinates": [-24.313216723618247, 9.734322921375476]}}, {"datetime": "2020-08-03T10:05:00", "position": {"type": "Point", "coordinates": [-19.149004969165386, 11.472976277263932]}}, {"datetime": "2020-08-03T10:10:00", "position": {"type": "Point", "coordinates": [-22.538049699647512, 17.36245164236502]}}, {"datetime": "2020-08-03T10:35:00", "position": {"type": "Point", "coordinates": [-12.396171846516971, 18.279172640467515]}}, {"datetime": "2020-08-03T10:40:00", "position": {"type": "Point", "coordinates": [-10.395051797622896, 26.256725386902033]}}, {"datetime": "2020-08-03T11:00:00", "position": {"type": "Point", "coordinates": [-10.847484948019677, 25.776569243367316]}}, {"datetime": "2020-08-03T12:00:00", "position": {"type": "Point", "coordinates": [-6.810853155524966, 28.218062020178575]}}, {"datetime": "2020-08-03T12:20:00", "position": {"type": "Point", "coordinates": [-3.9789369091727558, 27.33303658853213]}}, {"datetime": "2020-08-03T13:55:00", "position": {"type": "Point", "coordinates": [-21.17639784281991, 15.891437288422537]}}, {"datetime": "2020-08-03T14:00:00", "position": {"type": "Point", "coordinates": [-18.685962872219, 22.04570299793444]}}, {"datetime": "2020-08-03T14:05:00", "position": {"type": "Point", "coordinates": [-15.77731689302551, 15.066287342986133]}}, {"datetime": "2020-08-03T14:10:00", "position": {"type": "Point", "coordinates": [-23.178985066415628, 18.74931725864583]}}, {"datetime": "2020-08-03T14:15:00", "position": {"type": "Point", "coordinates": [-20.314504810519434, 21.47538817415037]}}, {"datetime": "2020-08-03T17:55:00", "position": {"type": "Point", "coordinates": [-19.839419322020962, 23.412838086961614]}}, {"datetime": "2020-08-04T00:05:00", "position": {"type": "Point", "coordinates": [-20.58544542865478, 20.615504425081873]}}, {"datetime": "2020-08-04T00:10:00", "position": {"type": "Point", "coordinates": [-22.840059795649818, 10.768372886066663]}}, {"datetime": "2020-08-04T00:15:00", "position": {"type": "Point", "coordinates": [-17.022908913980036, 16.9568296362595]}}, {"datetime": "2020-08-04T00:35:00", "position": {"type": "Point", "coordinates": [20.49009292097366, 20.539509862709664]}}, {"datetime": "2020-08-04T00:50:00", "position": {"type": "Point", "coordinates": [23.28431715410108, 14.272866744483972]}}]
1 change: 1 addition & 0 deletions removed_locations.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[{"datetime": "2020-08-02T00:05:00", "position": {"type": "Point", "coordinates": [14.423899986147163, -26.068696785592756]}}, {"datetime": "2020-08-02T00:30:00", "position": {"type": "Point", "coordinates": [17.48120833067629, -28.841136830092744]}}, {"datetime": "2020-08-02T00:45:00", "position": {"type": "Point", "coordinates": [13.623266215220745, -27.459982585401512]}}, {"datetime": "2020-08-02T01:45:00", "position": {"type": "Point", "coordinates": [-11.150366846274526, -29.1466189396165]}}, {"datetime": "2020-08-02T01:50:00", "position": {"type": "Point", "coordinates": [-17.901225849973265, -23.58602191050181]}}, {"datetime": "2020-08-02T01:55:00", "position": {"type": "Point", "coordinates": [-16.437709854469116, -26.41298408344366]}}, {"datetime": "2020-08-02T02:05:00", "position": {"type": "Point", "coordinates": [-16.587268590835006, -21.991045741724836]}}, {"datetime": "2020-08-02T02:10:00", "position": {"type": "Point", "coordinates": [-10.87056845505196, -20.619649456900795]}}, {"datetime": "2020-08-02T03:40:00", "position": {"type": "Point", "coordinates": [1.8277974385294646, -29.011013934727497]}}, {"datetime": "2020-08-02T03:55:00", "position": {"type": "Point", "coordinates": [-8.39284196739923, -22.45919221493161]}}, {"datetime": "2020-08-02T04:05:00", "position": {"type": "Point", "coordinates": [-6.154542644969288, -28.601862674095095]}}, {"datetime": "2020-08-02T04:10:00", "position": {"type": "Point", "coordinates": [-15.501860720296232, -23.09128732343206]}}, {"datetime": "2020-08-02T04:15:00", "position": {"type": "Point", "coordinates": [-11.23858759608586, -19.986746490036317]}}, {"datetime": "2020-08-02T04:20:00", "position": {"type": "Point", "coordinates": [-21.232528286894198, -24.491206104895348]}}, {"datetime": "2020-08-02T04:40:00", "position": {"type": "Point", "coordinates": [-19.929148011689133, -18.89699260113361]}}, {"datetime": "2020-08-02T04:45:00", "position": {"type": "Point", "coordinates": [-10.151499068762845, -20.432250974613435]}}, {"datetime": "2020-08-02T05:05:00", "position": {"type": "Point", "coordinates": [-11.448700798499019, -25.050928190203493]}}, {"datetime": "2020-08-02T08:25:00", "position": {"type": "Point", "coordinates": [-19.168914003666846, -25.203679565290194]}}, {"datetime": "2020-08-02T10:40:00", "position": {"type": "Point", "coordinates": [-15.76507465222431, -27.937788725422486]}}, {"datetime": "2020-08-02T10:50:00", "position": {"type": "Point", "coordinates": [-11.368070429712803, -23.395736287305265]}}, {"datetime": "2020-08-02T11:30:00", "position": {"type": "Point", "coordinates": [-20.12161760304848, -26.719959691453862]}}, {"datetime": "2020-08-02T11:35:00", "position": {"type": "Point", "coordinates": [-11.736613288540951, -25.058082924822262]}}, {"datetime": "2020-08-02T11:40:00", "position": {"type": "Point", "coordinates": [-7.80381009656635, -27.58914300032983]}}, {"datetime": "2020-08-02T11:45:00", "position": {"type": "Point", "coordinates": [-11.197427990467054, -25.48141992475583]}}, {"datetime": "2020-08-02T12:15:00", "position": {"type": "Point", "coordinates": [-14.788072515829718, -27.302213944836964]}}, {"datetime": "2020-08-02T12:20:00", "position": {"type": "Point", "coordinates": [-16.940304741030822, -24.611494796255336]}}, {"datetime": "2020-08-03T07:10:00", "position": {"type": "Point", "coordinates": [-23.13492980308152, -17.232067260101264]}}, {"datetime": "2020-08-03T07:20:00", "position": {"type": "Point", "coordinates": [-26.119068368943413, -6.857579818735121]}}, {"datetime": "2020-08-03T09:00:00", "position": {"type": "Point", "coordinates": [-27.042024057507668, -8.342142548696131]}}, {"datetime": "2020-08-04T01:35:00", "position": {"type": "Point", "coordinates": [-8.282865941153673, -27.644765249845904]}}, {"datetime": "2020-08-04T01:40:00", "position": {"type": "Point", "coordinates": [-12.883302719392468, -23.422180772781893]}}, {"datetime": "2020-08-04T01:45:00", "position": {"type": "Point", "coordinates": [-7.46602954494418, -28.379382680669842]}}, {"datetime": "2020-08-04T02:25:00", "position": {"type": "Point", "coordinates": [-14.94780253022277, -23.932884553138244]}}, {"datetime": "2020-08-04T02:30:00", "position": {"type": "Point", "coordinates": [-19.020251305011627, -22.538883321852015]}}, {"datetime": "2020-08-04T02:55:00", "position": {"type": "Point", "coordinates": [-12.694131380379694, -24.479730256572516]}}, {"datetime": "2020-08-04T03:00:00", "position": {"type": "Point", "coordinates": [-20.43729222969682, -14.609186539947967]}}, {"datetime": "2020-08-04T03:05:00", "position": {"type": "Point", "coordinates": [-12.619005482240777, -21.57753087546039]}}, {"datetime": "2020-08-04T03:10:00", "position": {"type": "Point", "coordinates": [-17.94091009366484, -14.558333426560385]}}, {"datetime": "2020-08-04T03:15:00", "position": {"type": "Point", "coordinates": [-10.246199932230109, -22.765701580612273]}}, {"datetime": "2020-08-04T03:20:00", "position": {"type": "Point", "coordinates": [-9.199356339920948, -28.56803074301874]}}, {"datetime": "2020-08-04T03:55:00", "position": {"type": "Point", "coordinates": [20.69523170250868, -23.14674470959883]}}, {"datetime": "2020-08-04T04:40:00", "position": {"type": "Point", "coordinates": [10.897656443332341, -27.143051024558122]}}, {"datetime": "2020-08-04T05:00:00", "position": {"type": "Point", "coordinates": [15.61261170684185, -25.652885974637552]}}, {"datetime": "2020-08-04T05:40:00", "position": {"type": "Point", "coordinates": [25.53417703032249, -6.0446124086808]}}, {"datetime": "2020-08-04T05:45:00", "position": {"type": "Point", "coordinates": [15.753317058223233, -15.944492067989904]}}, {"datetime": "2020-08-04T05:50:00", "position": {"type": "Point", "coordinates": [21.92145054134533, -23.4785862469253]}}, {"datetime": "2020-08-04T05:55:00", "position": {"type": "Point", "coordinates": [16.72751124035251, -20.588219076647682]}}, {"datetime": "2020-08-04T08:55:00", "position": {"type": "Point", "coordinates": [13.657423917868483, -20.676673552101306]}}, {"datetime": "2020-08-04T09:00:00", "position": {"type": "Point", "coordinates": [15.962075969450602, -15.948848277230386]}}, {"datetime": "2020-08-04T09:05:00", "position": {"type": "Point", "coordinates": [20.615673934000597, -25.37576092920021]}}, {"datetime": "2020-08-04T09:15:00", "position": {"type": "Point", "coordinates": [16.7412554504296, -25.53340272035631]}}, {"datetime": "2020-08-04T09:20:00", "position": {"type": "Point", "coordinates": [12.64368260831742, -22.709855318778448]}}, {"datetime": "2020-08-04T09:30:00", "position": {"type": "Point", "coordinates": [11.014820539924113, -22.28844197412622]}}, {"datetime": "2020-08-04T09:55:00", "position": {"type": "Point", "coordinates": [11.944337646801266, -23.872540792744395]}}, {"datetime": "2020-08-04T10:00:00", "position": {"type": "Point", "coordinates": [16.72561462004265, -21.35339727196152]}}]
3 changes: 3 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
matplotlib==3.4.2
matplotlib-terminal==0.1a2
Shapely==1.7.1
112 changes: 112 additions & 0 deletions task.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import json
import os
from shapely.geometry import Polygon, Point
import matplotlib.pyplot as plt
import matplotlib_terminal
from datetime import datetime

dir_path = os.path.dirname(os.path.realpath('__file__'))

site_old_json_file = dir_path + "/site_old.json"
site_new_json_file = dir_path + "/site_new.json"
locations_json_file = dir_path + "/locations.json"


def _construct_polygon(coordinates):
polygon = Polygon(coordinates)
return polygon


def read_json_file(file_path):
data = {}
with open(file_path) as f:
data = json.loads(f.read())
return data


def convert_datetimeiso_to_datetime_obj(
iso_format):
return datetime.fromisoformat(iso_format)


def read_site_json_and_construct_polygon(json_file):
data = read_json_file(json_file)
geofence = data.get("geofence", {})
start_datetime = convert_datetimeiso_to_datetime_obj(
data.get("start_datetime"))
end_datetime = convert_datetimeiso_to_datetime_obj(
data.get("end_datetime"))
coordinates = []
if geofence.get("type") == "Polygon":
coordinates = geofence.get("coordinates")[0]
if coordinates:
polygon = _construct_polygon(coordinates)
return start_datetime, end_datetime, polygon


def write_to_file(data, file_name):
with open(file_name, 'w') as outfile:
json.dump(data, outfile)


def find_added_and_removed_locations(
site_old_json_file, site_new_json_file, locations_json_file,
create_graph=True):
start_datetime, end_datetime, old_site_polygon = \
read_site_json_and_construct_polygon(
site_old_json_file)
start_datetime, end_datetime, new_site_polygon = \
read_site_json_and_construct_polygon(
site_new_json_file)
# find the difference
removed_area = old_site_polygon.difference(new_site_polygon)
added_area = new_site_polygon.difference(old_site_polygon)
no_longer_contained_locations = []
newly_added_locations = []
added_location_xs = []
added_location_ys = []
removed_location_xs = []
removed_location_ys = []

with open(locations_json_file) as f:
for line in f:
item = json.loads(line)
location_datetime = convert_datetimeiso_to_datetime_obj(
item.get("datetime"))
# for a site to contain a Location, the time of the
# location should be in the time interval of the Site
if not (start_datetime < location_datetime < end_datetime):
continue
if item.get("position", {}).get("type") == "Point":
coordinates = item.get("position").get("coordinates")
point = Point(coordinates)
if added_area.contains(point):
newly_added_locations.append(item)
if create_graph:
added_location_xs.append(point.x)
added_location_ys.append(point.y)
elif removed_area.contains(point):
no_longer_contained_locations.append(item)
if create_graph:
removed_location_xs.append(point.x)
removed_location_ys.append(point.y)
else:
continue
# writes to json file in a single write
write_to_file(no_longer_contained_locations, 'removed_locations.json')
write_to_file(newly_added_locations, 'added_locations.json')
if create_graph:
x, y = old_site_polygon.exterior.xy
a, b = new_site_polygon.exterior.xy
plt.plot(a, b, c="green")
plt.plot(x, y, c="red")
plt.scatter(added_location_xs, added_location_ys,
c="green", label="Added locations")
plt.scatter(removed_location_xs, removed_location_ys, c="red",
label="Removed locations")
plt.savefig('visualization.png')
plt.close()


find_added_and_removed_locations(
site_old_json_file, site_new_json_file, locations_json_file)
Binary file added visualization.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.