Compare commits
8 Commits
a51343d9c3
...
93cf6916f2
Author | SHA1 | Date | |
---|---|---|---|
93cf6916f2 | |||
8dbb281e19 | |||
f381936abb | |||
43e5666a9b | |||
26093f7bb2 | |||
e3e59c24de | |||
d824a8638f | |||
4b32d72f8f |
86
building_selection_tool.py
Normal file
86
building_selection_tool.py
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
"""
|
||||||
|
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_coordinates: list of coordinates forming the selection polygon
|
||||||
|
: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: None
|
||||||
|
"""
|
||||||
|
longitude = coordinate[0]
|
||||||
|
latitude = coordinate[1]
|
||||||
|
|
||||||
|
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 select_by_address(self, address):
|
||||||
|
"""
|
||||||
|
Select a building by inputting an address
|
||||||
|
:param address:
|
||||||
|
:return: None
|
||||||
|
"""
|
||||||
|
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):
|
||||||
|
"""
|
||||||
|
Save all selected buildings to an output file.
|
||||||
|
:param output_file_path: destination file path including file name and extension
|
||||||
|
:return: None
|
||||||
|
"""
|
||||||
|
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))
|
24
helpers.py
Normal file
24
helpers.py
Normal file
@ -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
|
42
latlong2.py
42
latlong2.py
@ -1,42 +0,0 @@
|
|||||||
import requests
|
|
||||||
|
|
||||||
def get_lat_lng(api_key, 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
|
|
||||||
|
|
||||||
def get_lat_lng_for_addresses(api_key, addresses):
|
|
||||||
coordinates = []
|
|
||||||
|
|
||||||
for address in addresses:
|
|
||||||
lat, lng = get_lat_lng(api_key, address)
|
|
||||||
if lat is not None and lng is not None:
|
|
||||||
coordinates.append((lat, lng))
|
|
||||||
|
|
||||||
return coordinates
|
|
||||||
|
|
||||||
# Replace 'YOUR_API_KEY' with your OpenCage Geocoding API key
|
|
||||||
api_key = '744ad0d2d58e49d1ac57d6fb04fe5d82'
|
|
||||||
|
|
||||||
# Example list of addresses
|
|
||||||
addresses = ["1600 Amphitheatre Parkway, Mountain View, CA",
|
|
||||||
"Eiffel Tower, Paris, France",
|
|
||||||
"Big Ben, London, UK"]
|
|
||||||
|
|
||||||
coordinates = get_lat_lng_for_addresses(api_key, addresses)
|
|
||||||
|
|
||||||
# Print the coordinates
|
|
||||||
for address, coord in zip(addresses, coordinates):
|
|
||||||
print(f"{address} -> Latitude: {coord[0]}, Longitude: {coord[1]}")
|
|
52
main.py
52
main.py
@ -1,40 +1,24 @@
|
|||||||
import json
|
from building_selection_tool import BuildingSelectionTool
|
||||||
from shapely import Polygon
|
|
||||||
from shapely import Point
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
# Make sure to enter your points in the clockwise direction
|
selection_tool = BuildingSelectionTool('./data/collinear_clean.geojson')
|
||||||
# and in the longitude, latitude format
|
|
||||||
#selection_box = Polygon([[-73.543833, 45.575932] ,
|
|
||||||
# [-73.541834, 45.575245],
|
|
||||||
# [-73.542275, 45.574652],
|
|
||||||
# [-73.544235, 45.575329],
|
|
||||||
# [-73.543833, 45.575932]])
|
|
||||||
x=-73.61574532884296
|
|
||||||
y=45.603911965131
|
|
||||||
diff=0.001
|
|
||||||
selection_box = Polygon([[x+diff, y-diff],
|
|
||||||
[x-diff, y-diff],
|
|
||||||
[x-diff, y+diff],
|
|
||||||
[x+diff, y+diff]])
|
|
||||||
geojson_file = Path('./data/collinear_clean 1.geojson').resolve()
|
|
||||||
output_file = Path('./output_buildings.geojson').resolve()
|
|
||||||
buildings_in_region = []
|
|
||||||
|
|
||||||
with open(geojson_file, 'r') as file:
|
# select all buildings within a polygon
|
||||||
city = json.load(file)
|
sample_polygon_coordinates = [[-73.543833, 45.575932],
|
||||||
buildings = city['features']
|
[-73.541834, 45.575245],
|
||||||
|
[-73.542275, 45.574652],
|
||||||
|
[-73.544235, 45.575329],
|
||||||
|
[-73.543833, 45.575932]]
|
||||||
|
|
||||||
for building in buildings:
|
selection_tool.select_by_polygon(sample_polygon_coordinates)
|
||||||
coordinates = building['geometry']['coordinates'][0]
|
|
||||||
building_polygon = Polygon(coordinates)
|
|
||||||
centroid = Point(building_polygon.centroid)
|
|
||||||
|
|
||||||
if centroid.within(selection_box):
|
# select building by address
|
||||||
buildings_in_region.append(building)
|
sample_address = "2155 Rue Guy, Montreal, Quebec"
|
||||||
|
selection_tool.select_by_address(sample_address)
|
||||||
|
|
||||||
output_region = {"type": "FeatureCollection",
|
# select building by [longitude, latitude] coordinate
|
||||||
"features": buildings_in_region}
|
sample_coordinate = [-73.5790796, 45.4972906]
|
||||||
|
selection_tool.select_by_coordinate(sample_coordinate)
|
||||||
|
|
||||||
with open(output_file, 'w') as file:
|
# save selected buildings in geojson format to specified output_file_path
|
||||||
file.write(json.dumps(output_region, indent=2))
|
output_file_path = "./output_files/sample_output.geojson"
|
||||||
|
selection_tool.save_selected_buildings(output_file_path)
|
||||||
|
2
output_files/.gitignore
vendored
Normal file
2
output_files/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
*
|
||||||
|
!.gitignore
|
4
requirements.txt
Normal file
4
requirements.txt
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
json
|
||||||
|
shapely
|
||||||
|
pathlib
|
||||||
|
requests
|
Loading…
Reference in New Issue
Block a user