Commit 26b53077 by Corey Koval

AOI GUI Prep 99% done, just needs back end functionality

parent f2d1b022
......@@ -328,11 +328,42 @@ def write_czml(best_point, all_the_points, ellipsedata):
}
}
}
area_of_interest_properties = {
"granularity": 0.008722222,
"height": 0,
"material": {
"solidColor": {
"color": {
"rgba": [0, 255, 0, 25]
}
}
},
"outline": True,
"outlineWidth": 2,
"outlineColor": {"rgba": [53, 184, 240, 255],},
},
exclusion_area_properties = {
"granularity": 0.008722222,
"height": 0,
"material": {
"solidColor": {
"color": {
"rgba": [242, 10, 0, 25]
}
}
},
"outline": True,
"outlineWidth": 2,
"outlineColor": {"rgba": [224, 142, 0, 255],},
},
top = Preamble(name="Geolocation Data")
all_point_packets = []
best_point_packets = []
ellipse_packets = []
aoi_packets = []
# exclusion_packets = []
if len(all_the_points) > 0 and (ms.plotintersects or ms.eps == 0):
all_the_points = np.array(all_the_points)
......@@ -370,9 +401,27 @@ def write_czml(best_point, all_the_points, ellipsedata):
ellipse_info = {"semiMajorAxis": semiMajorAxis, "semiMinorAxis": semiMinorAxis, "rotation": rotation}
ellipse_packets.append(Packet(id=str(x[4]) + ", " + str(x[3]),
ellipse={**ellipse_properties, **ellipse_info},
position={"cartographicDegrees": [ x[3], x[4], 15 ]}))
output = Document([top] + best_point_packets + all_point_packets + ellipse_packets)
position={"cartographicDegrees": [ x[3], x[4], 0 ]}))
for x in fetch_aoi_data():
aoi = {
'uid': x[0],
'aoi_type': x[1],
'latitude': x[2],
'longitude': x[3],
'radius': x[4]
}
if aoi['aoi_type'] == "aoi":
aoi_properties = area_of_interest_properties[0]
elif aoi['aoi_type'] == "exclusion":
aoi_properties = exclusion_area_properties[0]
aoi_info = {"semiMajorAxis": aoi['radius'], "semiMinorAxis": aoi['radius'], "rotation": 0}
aoi_packets.append(Packet(id=aoi['aoi_type'] + str(aoi['uid']),
ellipse={**aoi_properties, **aoi_info},
position={"cartographicDegrees": [ aoi['longitude'], aoi['latitude'], 0 ]}))
output = Document([top] + best_point_packets + all_point_packets + ellipse_packets +
aoi_packets)
return output
......@@ -593,6 +642,46 @@ def update_rx(action):
return redirect('/rx_params')
###############################################
# Returns a JSON file to the WebUI with
# information to fill in the AOI cards.
###############################################
@get('/interest_areas')
def rx_params():
all_aoi = {'aois':{}}
aoi_properties = []
for x in fetch_aoi_data():
aoi = {
'uid': x[0],
'aoi_type': x[1],
'latitude': x[2],
'longitude': x[3],
'radius': x[4]
}
aoi_properties.append(aoi)
all_aoi['aois'] = aoi_properties
response.headers['Content-Type'] = 'application/json'
return json.dumps(all_aoi)
##########################################
# PUT request to add new AOI to DB
##########################################
@put('/interest_areas/<action>')
def handle_interest_areas(action):
data = json.load(request.body)
if action == "new" and not "" in data.values():
aoi_type = data['aoi_type']
lat = data['latitude']
lon = data['longitude']
radius = data['radius']
add_aoi(aoi_type, lat, lon, radius)
elif action == "del":
conn = sqlite3.connect(database_name)
c = conn.cursor()
c.execute("DELETE FROM interest_areas WHERE uid=?", [data['uid']])
conn.commit()
conn.close()
###############################################
# Starts the Bottle webserver.
###############################################
def start_server(ipaddr = "127.0.0.1", port=8080):
......@@ -709,7 +798,6 @@ def run_receiver(receivers):
#################################################
def compute_single_intersections(lat_rxa, lon_rxa, doa_rxa, conf_rxa,
lat_rxb, lon_rxb, doa_rxb, conf_rxb):
intersection = plot_intersects(lat_rxa, lon_rxa,
doa_rxa, lat_rxb, lon_rxb, doa_rxb)
# print(type(intersection))
......@@ -806,6 +894,38 @@ def del_receiver(del_rx):
conn.commit()
conn.close()
###############################################
# Updates the database with new interest areas.
###############################################
def add_aoi(aoi_type, lat, lon, radius):
conn = sqlite3.connect(database_name)
c = conn.cursor()
c.execute('''CREATE TABLE IF NOT EXISTS interest_areas (
uid INTEGER,
aoi_type TEXT,
latitude REAL,
longitude REAL,
radius INTEGER)
''')
prev_uid = c.execute('SELECT MAX(uid) from interest_areas').fetchone()[0]
print(prev_uid)
uid = (prev_uid + 1) if prev_uid != None else 0
to_table = [uid, aoi_type, lat, lon, radius]
c.execute('INSERT INTO interest_areas VALUES (?,?,?,?,?)', to_table)
conn.commit()
conn.close()
#########################################
# Read all the AOIs from the DB
#########################################
def fetch_aoi_data():
conn = sqlite3.connect(database_name)
c = conn.cursor()
c.execute('SELECT * FROM interest_areas')
aoi_list = c.fetchall()
conn.close()
return aoi_list
if __name__ == '__main__':
###############################################
# Help info printed when calling the program
......
......@@ -24,14 +24,25 @@ add_button.onchange = function() {
}
var aoi_br = document.createElement("br");
var aoi_latlon_label = document.createTextNode("Lat, Lon:");
var aoi_lat_lon = document.createElement('input');
aoi_lat_lon.type = 'text';
aoi_lat_lon.id = 'aoi-new-latlon';
aoi_lat_lon.style.width = '300px';
var aoi_latlabel = document.createTextNode("Lat:");
var aoi_lat = document.createElement('input');
aoi_lat.type = 'text';
aoi_lat.id = 'aoi-new-lat';
aoi_lat.style.width = '140px';
var new_aoi = document.getElementById("new-aoi");
new_aoi.appendChild(aoi_latlon_label);
new_aoi.appendChild(aoi_lat_lon);
new_aoi.appendChild(aoi_latlabel);
new_aoi.appendChild(aoi_lat);
var aoi_br = document.createElement("br");
var aoi_lonlabel = document.createTextNode(" Lon:");
var aoi_lon = document.createElement('input');
aoi_lon.type = 'text';
aoi_lon.id = 'aoi-new-lon';
aoi_lon.style.width = '140px';
var new_aoi = document.getElementById("new-aoi");
new_aoi.appendChild(aoi_lonlabel);
new_aoi.appendChild(aoi_lon);
var aoi_radius_label = document.createTextNode("Radius:");
var aoi_radius = document.createElement('input');
aoi_radius.type = 'text';
......@@ -45,8 +56,9 @@ add_aoi.onchange = function() {
if (add_aoi.checked) {
clearHover();
document.getElementById("add_aoi_icon").innerHTML = "save";
pickCenter(aoi_lat_lon, aoi_radius, Cesium.Color.CORNFLOWERBLUE);
aoi_lat_lon.value = "";
pickCenter(aoi_lat, aoi_lon, aoi_radius, Cesium.Color.CORNFLOWERBLUE);
aoi_lat.value = "";
aoi_lon.value = "";
aoi_radius.value = "";
document.getElementById("new_aoi_div").style.height = 'auto';
document.getElementById("new_aoi_div").style.visibility = "visible";
......@@ -56,19 +68,32 @@ add_aoi.onchange = function() {
document.getElementById("new_aoi_div").style.visibility = "hidden";
document.getElementById("new_aoi_div").style.padding = "0";
document.getElementById("add_aoi_icon").innerHTML = "add_circle_outline";
makeNewAoi("aoi", aoi_lat.value, aoi_lon.value, aoi_radius.value);
scene.primitives.remove(area);
clearHover();
}
}
var exclusion_br = document.createElement("br");
var exclusion_latlon_label = document.createTextNode("Lat, Lon:");
var exclusion_lat_lon = document.createElement('input');
exclusion_lat_lon.type = 'text';
exclusion_lat_lon.id = 'exclusion-new-latlon';
exclusion_lat_lon.style.width = '300px';
var exclusion_latlabel = document.createTextNode("Lat:");
var exclusion_lat = document.createElement('input');
exclusion_lat.type = 'text';
exclusion_lat.id = 'exclusion-new-lat';
exclusion_lat.style.width = '140px';
var new_exclusion = document.getElementById("new-exclusion");
new_exclusion.appendChild(exclusion_latlon_label);
new_exclusion.appendChild(exclusion_lat_lon);
new_exclusion.appendChild(exclusion_latlabel);
new_exclusion.appendChild(exclusion_lat);
var exclusion_br = document.createElement("br");
var exclusion_lonlabel = document.createTextNode(" Lon:");
var exclusion_lon = document.createElement('input');
exclusion_lon.type = 'text';
exclusion_lon.id = 'exclusion-new-lon';
exclusion_lon.style.width = '140px';
var new_exclusion = document.getElementById("new-exclusion");
new_exclusion.appendChild(exclusion_lonlabel);
new_exclusion.appendChild(exclusion_lon);
var exclusion_radius_label = document.createTextNode("Radius:");
var exclusion_radius = document.createElement('input');
exclusion_radius.type = 'text';
......@@ -82,8 +107,9 @@ add_exclusion.onchange = function() {
if (add_exclusion.checked) {
clearHover();
document.getElementById("add_exclusion_icon").innerHTML = "save";
pickCenter(exclusion_lat_lon, exclusion_radius, Cesium.Color.ORANGE);
exclusion_lat_lon.value = "";
pickCenter(exclusion_lat, exclusion_lon, exclusion_radius, Cesium.Color.ORANGE);
exclusion_lat.value = "";
exclusion_lon.value = "";
exclusion_radius.value = "";
document.getElementById("new_exclusion_div").style.height = 'auto';
document.getElementById("new_exclusion_div").style.visibility = "visible";
......@@ -93,6 +119,8 @@ add_exclusion.onchange = function() {
document.getElementById("new_exclusion_div").style.visibility = "hidden";
document.getElementById("new_exclusion_div").style.padding = "0";
document.getElementById("add_exclusion_icon").innerHTML = "add_circle_outline";
makeNewAoi("exclusion", exclusion_lat.value, exclusion_lon.value, exclusion_radius.value);
scene.primitives.remove(area);
clearHover();
}
}
// *************************************************
// * Gets AOI data from backend
// *************************************************
function updateAoi(callBack, id) {
fetch("/interest_areas")
.then(data => { return data.json() })
.then(res => { callBack(res, id);
// console.log("updateRx Complete");
console.log(res);
})
}
// ****************************************************
// * Sends AOI Information to backend and refreshes map
// ****************************************************
function makeNewAoi(aoi_type, latitude, longitude, radius) {
const new_aoi = {
"aoi_type": aoi_type,
"latitude": latitude,
"longitude": longitude,
"radius": radius
};
// console.log(new_rx);
const otherParams = {
headers: {
"content-type": "application/json"
},
body: JSON.stringify(new_aoi),
method: "PUT"
};
clearOld();
fetch("/interest_areas/new", otherParams)
.then(res => {
updateAoi(createAois, true);
loadAllCzml();
})
}
// *******************************************
// * Removes Rx from Backend and Reloads Map
// *******************************************
function deleteAoi(uid) {
const del_aoi = { "uid": uid };
// console.log(new_rx);
const otherParams = {
headers: {
"content-type": "application/json"
},
body: JSON.stringify(del_aoi),
method: "PUT"
};
clearOld();
fetch("/interest_areas/del", otherParams)
.then(res => {
// removerx(uid);
loadAoi(createAois);
loadAllCzml();
})
}
// *****************************************
// * Removes ALL of the RX Cards
// *****************************************
function destroyAoiCards() {
document.querySelectorAll('.aoi').forEach(e => e.remove());
}
// *******************************************
// * Fills in AOI UI cards with AOI info
// *******************************************
function showAois(aoi_json, index, uid) {
const interest_areas = aoi_json['aois'];
var locationHtml =
"Location: " + interest_areas[index].latitude + "&#176;, " + interest_areas[index].longitude + "&#176;";
var radius =
"Radius: " + interest_areas[index].radius + " meters";
const locationspan = document.getElementById(uid + "-aoi_location");
const radiusspan = document.getElementById(uid + "-aoi_radius");
locationspan.innerHTML = locationHtml;
radiusspan.innerHTML = radius;
}
// ****************************************************
// * Creates cards on UI for AOI information.
// * Iterates through AOI objects on page load/AOI add.
// ****************************************************
function createAois(aoi_json, id) {
destroyAoiCards();
let interest_areas = aoi_json['aois'];
// console.log(interest_areas);
for (let i = 0; i < Object.keys(interest_areas).length; i++) {
const aoicard = document.createElement('div');
aoicard.className = "aoi";
aoicard.id = "aoi-" + interest_areas[i].uid;
const locationspan = document.createElement('span');
const radiusspan = document.createElement('span');
const deleteiconspan = document.createElement('span');
deleteiconspan.classList.add("material-icons", "delete-icon", "no-select");
deleteiconspan.innerHTML = "delete";
const deletecheck = document.createElement('input');
deletecheck.classList.add("edit-checkbox", "delete-icon");
deletecheck.type = 'checkbox';
deletecheck.id = interest_areas[i].uid + "-aoi_delete";
deletecheck.setAttribute('onclick', "deleteAoi(" + interest_areas[i].uid + ")");
locationspan.id = interest_areas[i].uid + "-aoi_location";
radiusspan.id = interest_areas[i].uid + "-aoi_radius";
if (interest_areas[i].aoi_type == "aoi") {
document.getElementById("aoicards").insertBefore(aoicard, document.getElementById("add_aoi"));
} else if (interest_areas[i].aoi_type == "exclusion") {
document.getElementById("exclusioncards").insertBefore(aoicard, document.getElementById("add_exclusion"));
const purgeiconspan = document.createElement('span');
purgeiconspan.classList.add("material-icons", "edit-icon", "no-select");
purgeiconspan.innerHTML = "rule";
const purgecheck = document.createElement('input');
purgecheck.classList.add("edit-checkbox", "edit-icon");
purgecheck.type = 'checkbox';
purgecheck.id = interest_areas[i].uid + "-aoi_purge";
purgecheck.setAttribute('onclick', "purgeAoi(" + interest_areas[i].uid + ")");
purgecheck.setAttribute("title", "Purge database of entries inside this area.\nThis cannot be undone!");
aoicard.appendChild(purgeiconspan);
aoicard.appendChild(purgecheck);
}
aoicard.appendChild(locationspan);
aoicard.appendChild(radiusspan);
aoicard.appendChild(deleteiconspan);
aoicard.appendChild(deletecheck);
showAois(aoi_json, i, interest_areas[i].uid);
}
}
// ****************************************************
// * Refreshes info on Aoi UI Cards (Refresh button)
// ****************************************************
function refreshAoi(aoi_json, id) {
const interest_areas = aoi_json['interest_areas'];
for (let i = 0; i < Object.keys(interest_areas).length; i++) {
showAois(aoi_json, interest_areas[i].uid);
}
}
// ****************************************************
// * Main function - Loads all Receivers
// ****************************************************
function loadAoi(action) {
updateAoi(action, null);
}
......@@ -100,6 +100,8 @@ body {
/* to stop flickering of text in safari */
transform: none;
transition: transform 0.5s cubic-bezier(0.77,0.2,0.05,1.0);
max-height: 80%;
overflow-y: scroll;
}
#menu li {
......@@ -128,7 +130,7 @@ body {
vertical-align: middle;
}
.receiver {
.receiver, .aoi {
position: relative;
background: #d4d4d4;
color: #111;
......@@ -137,7 +139,7 @@ body {
margin: 5px;
vertical-align: middle;
}
.receiver span {
.receiver span, .aoi span {
display: block;
}
......
......@@ -9,12 +9,13 @@
<!-- Include the CesiumJS JavaScript and CSS files -->
<script src="https://cesium.com/downloads/cesiumjs/releases/1.76/Build/Cesium/Cesium.js"></script>
<script src="/static/receiver_configurator.js"></script>
<script src="/static/interest_areas.js"></script>
<link href="https://cesium.com/downloads/cesiumjs/releases/1.76/Build/Cesium/Widgets/widgets.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link href="/static/style.css" rel="stylesheet">
<link href="/static/menu.css" rel="stylesheet">
</head>
<body onload="loadRx(createReceivers)">
<body onload="loadRx(createReceivers); loadAoi(createAois);">
<div id="cesiumContainer">
</div>
......@@ -26,8 +27,6 @@
// terrainProvider: Cesium.createWorldTerrain(),
homeButton: false,
timeline: false,
selectionIndicator: false,
infoBox: false,
});
var clock = new Cesium.Clock({
clockStep : Cesium.ClockStep.SYSTEM_CLOCK_MULTIPLIER
......@@ -51,7 +50,9 @@
var radius;
// Pick the center point of a circle
function pickCenter(lat_element_id, radius_element_id, outlineColor) {
function pickCenter(lat_element_id, lon_element_id, radius_element_id, outlineColor) {
viewer.selectionIndicator = false;
viewer.infoBox = false;
var entity = viewer.entities.add({
label: {
show: false,
......@@ -78,15 +79,15 @@
cartographic.latitude
).toFixed(5);
lat_element_id.value = center_lat + ", " + center_lon;
// lon_element_id.value = center_lon;
lat_element_id.value = center_lat;
lon_element_id.value = center_lon;
entity.position = cartesian;
entity.label.show = true;
entity.label.text =
"Lon: " +
(" " + center_lon).slice(-10) +
"\nLat: " +
(" " + center_lat).slice(-10);
"Lat: " +
(" " + center_lat).slice(-10) +
"\nLon: " +
(" " + center_lon).slice(-10);
} else {
entity.label.show = false;
}
......@@ -98,15 +99,17 @@
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
}
var area;
//Stop pickng things
function clearHover() {
viewer.selectionIndicator = true;
viewer.infoBox = true;
viewer.entities.removeAll();
handler = handler && handler.destroy();
};
//Pick the outside edge, radius, of a circle.
function pickRadius(radius_element_id, center_carto, outlineColor) {
var area;
var entity = viewer.entities.add({
label: {
show: false,
......@@ -221,6 +224,7 @@
// const buildingTileset = viewer.scene.primitives.add(Cesium.createOsmBuildings());
</script>
<div id="cardsmenu">
<div id="menuToggle">
<input id="burgerbars" type="checkbox" />
......@@ -261,6 +265,7 @@
</div>
</ul>
</div>
</div>
<script src="/static/cardsmenu.js"></script>
<div class="slidecontainer">
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment