diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..2d1cceb
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,6 @@
+.vscode
+venv
+solargeo.json
+bfg-1.13.0.jar
+*\google_creds.json
+*\keys.json
diff --git a/Aptfile b/Aptfile
new file mode 100644
index 0000000..6f0ea40
--- /dev/null
+++ b/Aptfile
@@ -0,0 +1,4 @@
+libsm6
+libxrender1
+libfontconfig1
+libice6
\ No newline at end of file
diff --git a/Procfile b/Procfile
new file mode 100644
index 0000000..6f18d33
--- /dev/null
+++ b/Procfile
@@ -0,0 +1 @@
+web: gunicorn api:app
\ No newline at end of file
diff --git a/README.md b/README.md
index 91a2b2c..247f147 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1 @@
-# EarthXHackothon
- Hackathon Repo
+# envohacks
diff --git a/__init__.py b/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/__pycache__/get_map.cpython-38.pyc b/__pycache__/get_map.cpython-38.pyc
new file mode 100644
index 0000000..c69e9d9
Binary files /dev/null and b/__pycache__/get_map.cpython-38.pyc differ
diff --git a/__pycache__/get_prediction.cpython-38.pyc b/__pycache__/get_prediction.cpython-38.pyc
new file mode 100644
index 0000000..5e42dc8
Binary files /dev/null and b/__pycache__/get_prediction.cpython-38.pyc differ
diff --git a/__pycache__/get_size.cpython-38.pyc b/__pycache__/get_size.cpython-38.pyc
new file mode 100644
index 0000000..587e20a
Binary files /dev/null and b/__pycache__/get_size.cpython-38.pyc differ
diff --git a/api.py b/api.py
new file mode 100644
index 0000000..afe4450
--- /dev/null
+++ b/api.py
@@ -0,0 +1,51 @@
+from flask import Flask, request, jsonify
+from detector import rooftop_detection as rd
+from flask_cors import CORS
+
+import os
+app = Flask(__name__)
+CORS(app)
+
+@app.route('/')
+def home():
+ return '
Deployed to Wherever!
'
+ #Environment variables: os.environ['varName']
+
+@app.route('/process', methods=['GET'])
+def stuff():
+ lat = float(request.args.get('lat'))
+ lon = float(request.args.get('lon'))
+ sol = float(request.args.get('solar'))
+ response = rd.get_roof_data(lat,lon)
+ image = response['image']
+ #response.pop('image', None)
+ coeffecient = {
+ "prism": 0.75,
+ "flat": 1,
+ "slantedprism": 0.6,
+ "pyramid": 0.5,
+ "complex": 0.4
+ }
+ response["adjusted"]=coeffecient[response["name"]] * sol
+ return jsonify(response)
+
+
+if __name__ == "__main__":
+ app.run()
+
+# Sample request
+# {
+# "methods": "GET",
+# "solar": "3.121",
+# "lat": "7.721321321313",
+# "lon": "7.721321321313",
+# }
+
+
+# Sample response
+# {
+# "category": "slantedprism",
+# "image": image,
+# "calculatedArea":"something something m^2",
+# "powerRating":"something something kWh/ m^2",
+# }
\ No newline at end of file
diff --git a/detector/__pycache__/get_map.cpython-38.pyc b/detector/__pycache__/get_map.cpython-38.pyc
new file mode 100644
index 0000000..651a96a
Binary files /dev/null and b/detector/__pycache__/get_map.cpython-38.pyc differ
diff --git a/detector/__pycache__/get_prediction.cpython-38.pyc b/detector/__pycache__/get_prediction.cpython-38.pyc
new file mode 100644
index 0000000..3fa9d3e
Binary files /dev/null and b/detector/__pycache__/get_prediction.cpython-38.pyc differ
diff --git a/detector/__pycache__/get_size.cpython-38.pyc b/detector/__pycache__/get_size.cpython-38.pyc
new file mode 100644
index 0000000..e2af877
Binary files /dev/null and b/detector/__pycache__/get_size.cpython-38.pyc differ
diff --git a/detector/__pycache__/rooftop_detection.cpython-38.pyc b/detector/__pycache__/rooftop_detection.cpython-38.pyc
new file mode 100644
index 0000000..eace993
Binary files /dev/null and b/detector/__pycache__/rooftop_detection.cpython-38.pyc differ
diff --git a/detector/get_map.py b/detector/get_map.py
new file mode 100644
index 0000000..50164ae
--- /dev/null
+++ b/detector/get_map.py
@@ -0,0 +1,30 @@
+import requests, urllib, json
+
+with open('keys.json', 'r') as f:
+ keys = json.load(f)
+
+maps_static_key = keys["maps-static"]
+
+imagewidth = 400
+imageheight = 400
+scale = 2
+
+def get_map(zoom, latitude, longitude):
+ url = "https://maps.googleapis.com/maps/api/staticmap?"
+ center = str(latitude) + "," + str(longitude)
+
+ urlparams = urllib.parse.urlencode({'center': center,
+ 'zoom': str(zoom),
+ 'size': str(imagewidth) + 'x' + str(imageheight),
+ 'maptype': 'satellite',
+ 'sensor': 'false',
+ 'scale': str(scale),
+ 'key': maps_static_key})
+ print(url + urlparams)
+ r = requests.get(url + urlparams)
+
+ if not (r.status_code==404 or r.status_code==403):
+ return r.content
+ else:
+ return 0
+
diff --git a/detector/get_prediction.py b/detector/get_prediction.py
new file mode 100644
index 0000000..72794e3
--- /dev/null
+++ b/detector/get_prediction.py
@@ -0,0 +1,76 @@
+import os, json, math
+from google.cloud import automl_v1beta1
+from google.cloud.automl_v1beta1.proto import service_pb2
+
+from detector import get_map as gm
+
+os.environ['GOOGLE_APPLICATION_CREDENTIALS'] = "google_creds.json"
+
+with open('keys.json', 'r') as f:
+ keys = json.load(f)
+
+ml_project_id = keys["ml-project-id"]
+ml_model_id = keys["ml-model-id"]
+
+
+# 'content' is base-64-encoded image data.
+def get_prediction(content, project_id, model_id):
+ prediction_client = automl_v1beta1.PredictionServiceClient()
+
+ name = 'projects/{}/locations/us-central1/models/{}'.format(project_id, model_id)
+ payload = {'image': {'image_bytes': content }}
+ params = {}
+ request = prediction_client.predict(name, payload, params)
+ return request # waits till request is returned
+
+def calculateDistance(x1,y1,x2,y2):
+ dist = math.sqrt((x2 - x1)**2 + (y2 - y1)**2)
+ return dist
+
+def make_recursive_prediction(zoom, latitude, longitude):
+ # Gets image of map from lat and long
+ img = gm.get_map(zoom, latitude, longitude)
+
+ if (zoom > 18):
+ # Try running the following code without errors
+ try:
+ # make a prediction on the image
+ prediction = get_prediction(img, ml_project_id, ml_model_id)
+
+ center = ((gm.imagewidth*gm.scale)/2,(gm.imageheight*gm.scale)/2)
+ dists = []
+
+ # iterate through each detection and calculate their distance to the center
+ for i in range (0, len(prediction.payload)):
+ detection = prediction.payload[i]
+ box = detection.image_object_detection.bounding_box.normalized_vertices
+ x1 = box[0].x*gm.imageheight*gm.scale
+ y1 = box[0].y*gm.imageheight*gm.scale
+ x2 = box[1].x*gm.imageheight*gm.scale
+ y2 = box[1].y*gm.imageheight*gm.scale
+ boxcenter = ((x1+x2)/2,(y1+y2)/2)
+ distToCenter = calculateDistance(boxcenter[0], boxcenter[1], center[0],center[1])
+ dists.append((distToCenter,i))
+
+ # find the box closest to the center of the frame
+ closestDist = dists[0]
+ for box in dists:
+ if box[0] < closestDist[0]:
+ closestDist = box
+
+ # return values of the closest box
+ payload = prediction.payload[closestDist[1]]
+ name = payload.display_name
+ score = payload.image_object_detection.score
+ box = payload.image_object_detection.bounding_box.normalized_vertices
+ x1 = box[0].x*gm.imageheight*gm.scale
+ y1 = box[0].y*gm.imageheight*gm.scale
+ x2 = box[1].x*gm.imageheight*gm.scale
+ y2 = box[1].y*gm.imageheight*gm.scale
+ return img, name, score, x1, y1, x2, y2, zoom
+
+ # if no detections are found, zoom out and recursively run the function over again
+ except (IndexError, KeyError, TypeError):
+ zoom -= 1
+ return make_recursive_prediction(zoom, latitude, longitude)
+ else: return 0
\ No newline at end of file
diff --git a/detector/get_size.py b/detector/get_size.py
new file mode 100644
index 0000000..68133ad
--- /dev/null
+++ b/detector/get_size.py
@@ -0,0 +1,20 @@
+import math
+
+def get_roof_size(rType,x1,y1,x2,y2, latitude, zoom):
+ if zoom == 21:
+ metersPerPx = 2/46
+ elif zoom == 20:
+ metersPerPx = 5/57
+ elif zoom == 19:
+ metersPerPx = 10/57
+ else:
+ metersPerPx = (156543.03392 * math.cos(latitude * math.pi / 180) / math.pow(2, zoom))/234
+
+ widthM = (x2-x1)*metersPerPx
+ lengthM = (y2-y1)*metersPerPx
+ area = widthM*lengthM
+ print(area, widthM, lengthM)
+
+ return area
+
+
diff --git a/detector/rooftop_detection.py b/detector/rooftop_detection.py
new file mode 100644
index 0000000..990d5b9
--- /dev/null
+++ b/detector/rooftop_detection.py
@@ -0,0 +1,40 @@
+import cv2, base64
+import numpy as np
+
+from detector import get_size as gs
+from detector import get_prediction as gp
+
+def draw_box(img, x1, y1, x2, y2):
+ start = (int(x1),int(y1))
+ end = (int(x2),int(y2))
+ image = np.asarray(bytearray(img), dtype="uint8")
+ image = cv2.imdecode(image, cv2.IMREAD_COLOR)
+
+ cv2.rectangle(image, start, end, 0, 4)
+ #cv2.imshow("lalala", image)
+ #k = cv2.waitKey(0)
+
+ b64img= cv2.imencode('.png', image)[1].tostring()
+ retval, buffer = cv2.imencode('.png', image)
+ png_as_text = base64.b64encode(buffer)
+ return png_as_text
+
+def get_roof_data(latitude, longitude):
+ zoom = 20
+ image, name, score, x1, y1, x2, y2, endZoom = gp.make_recursive_prediction(zoom, latitude, longitude)
+ size = gs.get_roof_size(name, x1,y1,x2,y2, latitude, endZoom)
+
+ image = draw_box(image, x1, y1, x2, y2)
+
+ response = {}
+ response['image']=str(image)[2:-1]
+ response['name']=name
+ response['score']=score
+ response['size']=size
+ return response
+
+if __name__ == "__main__":
+ lat = 43.7322193485497874
+ longi = -79.6181400203285
+
+ get_roof_data(lat, longi)
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000..c3d9d67
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1,28 @@
+cachetools==4.1.0
+certifi==2020.4.5.1
+chardet==3.0.4
+click==7.1.1
+Flask==1.1.2
+Flask-Cors==3.0.8
+google-api-core==1.17.0
+google-auth==1.14.1
+google-cloud==0.34.0
+google-cloud-automl==0.10.0
+googleapis-common-protos==1.51.0
+grpcio==1.28.1
+gunicorn==20.0.4
+idna==2.9
+itsdangerous==1.1.0
+Jinja2==2.11.2
+MarkupSafe==1.1.1
+numpy==1.18.3
+opencv-python==4.2.0.34
+protobuf==3.11.3
+pyasn1==0.4.8
+pyasn1-modules==0.2.8
+pytz==2019.3
+requests==2.23.0
+rsa==4.0
+six==1.14.0
+urllib3==1.25.9
+Werkzeug==1.0.1