-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathblur_location2city.r2py
167 lines (124 loc) · 5.02 KB
/
blur_location2city.r2py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
"""
A security layer for the functions get_location() and get_lastknown_location()
defined in getsensor.r2py. This program blurs the latitude/longitude
coordinates, received from the location sensors of an Android device,
to the geographic center of approximately the nearest city.
The blurring is done using a database lookup method. The database,
located at http://sensibilityclearinghouse.poly.edu/data/quad/, contains
a list of cities and their geodata, divided by their latitude/longitude
coordinates into cells. Each cell is a separate file in the database,
whose name is derived as "ceiling(latitude)_ceiling(longitude).txt".
For example, if a location has coordinates (40.78343, -73.96625), it
will be mapped to the file with name "41_-73.txt".
Usage:
start dylink.r2py encasementlib.r2py sensor_layer.r2py \
blur_location2city.r2py user-program.r2py
"""
location_blur_helper = dy_import_module("location_blur_helper.r2py")
def load_city_geodata(lat, lon):
"""
Loads all cities and corresponding geodata from the given file
into a dictionary.
Below is an example of a line from the file
http://sensibilityclearinghouse.poly.edu/data/quad/41_-73.txt,
with fields - city name, latitude, longitude, country code, state
code:
Manhattan 40.78343 -73.96625 US NY
The dictionary that is returned has the format:
{
city1: {"latitude": latitude, "longitude": longitude},
city2: {"latitude": latitude, "longitude": longitude},
...
}
"""
# Determine which file to download from the database.
filename = location_blur_helper.get_database_filename(lat, lon)
# Download the file from the city database.
location_blur_helper.get_city_file_from_server(filename)
# Obtain the list of cities and their geodata from the file.
cities_geodata = location_blur_helper.read_data_from_file(filename)
city_dict = {}
for line in cities_geodata:
# Ignore the empty line at the end of the file.
if line == "":
continue
city_geodata_record = line.split("\t")
city_name = city_geodata_record[0]
city_dict[city_name] = {
"latitude": float(city_geodata_record[1]),
"longitude": float(city_geodata_record[2])
}
return city_dict
def find_closest_city(lat, lon):
"""
Finds the city closest to the given latitude/longitude pair from the
dictionary of cities returned by the load_city_geodata() function,
and returns that city's geodata in the format:
{
"city_name": city name (string),
"latitude": latitude of the center of the city (float)
"longitude": longitude of the center of the city (float)
}
Note: We're looking for the closest city within the same cell as the
given latitude/longitude pair. There might be a closer city in the
surrounding cells.
"""
# Load all cities and corresponding geodata from the file.
city_dict = load_city_geodata(lat, lon)
return location_blur_helper.find_closest_location(lat, lon, city_dict)
def get_city_location():
"""
Blurring layer for the get_location() function. It replaces the exact
coordinates of the Android device with the coordinates for the
geographic center of the nearest city.
"""
location_data = get_location()
closest_city = find_closest_city(location_data["latitude"],
location_data["longitude"])
location_data["latitude"] = closest_city["latitude"]
location_data["longitude"] = closest_city["longitude"]
return location_data
def get_city_lastknown_location():
"""
Blurring layer for the get_lastknown_location() function. It replaces
the last-known coordinates of the Android device with the coordinates
for the geographic center of the nearest city.
"""
location_data = get_lastknown_location()
# Blur the coordinates of the first non-empty location data.
for location_provider, provider_location_data in location_data.items():
# Skip this provider's data if it doesn't contain a previous
# location.
if provider_location_data is None:
continue
closest_city = find_closest_city(provider_location_data["latitude"],
provider_location_data["longitude"])
break
# Copy the blurred coordinates into all providers' location data.
for location_provider, provider_location_data in location_data.items():
# Skip blurring this provider's data if it doesn't contain a previous
# location.
if provider_location_data is None:
continue
location_data[location_provider]["latitude"] = closest_city["latitude"]
location_data[location_provider]["longitude"] = closest_city["longitude"]
return location_data
# Mapping our blurring function get_city_location to get_location.
CHILD_CONTEXT_DEF["get_location"] = {
"type": "func",
"args": None,
"return": dict,
"exceptions": "any",
"target": get_city_location,
}
# Mapping our blurring function get_city_lastknown_location to
# get_lastknown_location.
CHILD_CONTEXT_DEF["get_lastknown_location"] = {
"type": "func",
"args": None,
"return": dict,
"exceptions": "any",
"target": get_city_lastknown_location,
}
# Dispatch.
secure_dispatch_module()