diff --git a/building_selection_tool.py b/building_selection_tool.py new file mode 100644 index 0000000..dcfaeb9 --- /dev/null +++ b/building_selection_tool.py @@ -0,0 +1,77 @@ +""" +Building Selection Tool +SPDX - License - Identifier: LGPL - 3.0 - or -later +Copyright © 2023 Concordia CERC group +Project Coder Koa Wells kekoa.wells@concordia.ca +""" + +import json +from pathlib import Path +from shapely import Polygon +from shapely import Point + +import helpers +class BuildingSelectionTool: + """ + BuildingSelectionTool class + """ + def __init__(self, geojson_file_path): + geojson_file = Path(geojson_file_path).resolve() + with open(geojson_file, 'r') as file: + self.city = json.load(file) + self.buildings = self.city['features'] + + self.selected_buildings = [] + + def select_by_polygon(self, selection_polygon_coordinates): + """ + Get all buildings within a specified polygon and write the output to output_file_path + :param selection_polygon: list of coordinates forming the selection polygon + :param output_file_path: path and file name for output file containing selected buildings and their metadata + :return: None + """ + selection_polygon = Polygon(selection_polygon_coordinates) + for building in self.buildings: + coordinates = building['geometry']['coordinates'][0] + building_polygon = Polygon(coordinates) + centroid = Point(building_polygon.centroid) + + if centroid.within(selection_polygon): + self.selected_buildings.append(building) + + def select_by_coordinate(self, coordinate): + """ + :param coordinate: longitude, latitude coordinate of selected + :return: + """ + pass + + def select_by_address(self, address): + """ + + :param address: + :return: + """ + coordinates = helpers.get_gps_coordinate_by_address(address) + longitude = coordinates[1] + latitude = coordinates[0] + + point = Point([longitude, latitude]) + + for building in self.buildings: + building_coordinates = building['geometry']['coordinates'][0] + building_polygon = Polygon(building_coordinates) + if point.within(building_polygon): + self.selected_buildings.append(building) + + def save_selected_buildings(self, output_file_path): + """ + + :return: + """ + output_file = Path(output_file_path).resolve() + output_region = {"type": "FeatureCollection", + "features": self.selected_buildings} + + with open(output_file, 'w') as file: + file.write(json.dumps(output_region, indent=2)) diff --git a/data/.gitignore b/data/.gitignore index c96a04f..cf57c3b 100644 --- a/data/.gitignore +++ b/data/.gitignore @@ -1,2 +1,2 @@ -* +.gitignore !.gitignore \ No newline at end of file diff --git a/helpers.py b/helpers.py new file mode 100644 index 0000000..7de1af1 --- /dev/null +++ b/helpers.py @@ -0,0 +1,24 @@ +""" +Helpers +""" +import requests + +#OpenCage Geocoding API key +API_KEY = '744ad0d2d58e49d1ac57d6fb04fe5d82' + +def get_gps_coordinate_by_address(address): + base_url = "https://api.opencagedata.com/geocode/v1/json" + params = { + 'q': address, + 'key': API_KEY, + } + + response = requests.get(base_url, params=params) + data = response.json() + + if response.status_code == 200 and data['status']['code'] == 200: + location = data['results'][0]['geometry'] + return location['lat'], location['lng'] + else: + print(f"Error: {data['status']['message']}") + return None, None \ No newline at end of file diff --git a/main.py b/main.py index 0e23d69..48331ab 100644 --- a/main.py +++ b/main.py @@ -1,34 +1,17 @@ -import json -from shapely import Polygon -from shapely import Point -from pathlib import Path +from building_selection_tool import BuildingSelectionTool -# Make sure to enter your points in the clockwise direction -# and in the longitude, latitude format -selection_box = Polygon([[-73.543833, 45.575932] , +selection_tool = BuildingSelectionTool('./data/collinear_clean.geojson') + +sample_polygon_coordinates = [[-73.543833, 45.575932], [-73.541834, 45.575245], [-73.542275, 45.574652], [-73.544235, 45.575329], - [-73.543833, 45.575932]]) + [-73.543833, 45.575932]] -geojson_file = Path('./data/collinear_clean.geojson').resolve() -output_file = Path('./output_buildings.geojson').resolve() -buildings_in_region = [] +selection_tool.select_by_polygon(sample_polygon_coordinates) -with open(geojson_file, 'r') as file: - city = json.load(file) - buildings = city['features'] +sample_address = "2155 Rue Guy, Montreal, Quebec" +selection_tool.select_by_address(sample_address) -for building in buildings: - coordinates = building['geometry']['coordinates'][0] - building_polygon = Polygon(coordinates) - centroid = Point(building_polygon.centroid) - - if centroid.within(selection_box): - buildings_in_region.append(building) - -output_region = {"type": "FeatureCollection", - "features": buildings_in_region} - -with open(output_file, 'w') as file: - file.write(json.dumps(output_region, indent=2)) +output_file_path = "./output_files/sample_output.geojson" +selection_tool.save_selected_buildings(output_file_path) diff --git a/output_files/.gitignore b/output_files/.gitignore new file mode 100644 index 0000000..c96a04f --- /dev/null +++ b/output_files/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore \ No newline at end of file