Add initial version of building selection tool
This commit is contained in:
parent
ed445529f9
commit
5da9766da6
52
building_region_selector.py
Normal file
52
building_region_selector.py
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
import json
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
from shapely.geometry import Polygon
|
||||||
|
|
||||||
|
"""
|
||||||
|
BuildingSelectionTool is a tool that allows for a subset of buildings to be selected from a larger geojson dataset.
|
||||||
|
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||||
|
Copyright © 2023 Concordia CERC group
|
||||||
|
Project Coder Koa Wells kekoa.wells@concordia.ca
|
||||||
|
"""
|
||||||
|
|
||||||
|
class BuildingSelectionTool:
|
||||||
|
def __init__(self, city_file, output_file):
|
||||||
|
self._city_file = city_file
|
||||||
|
self._city = json.load(city_file)
|
||||||
|
self._buildings = self._city['features']
|
||||||
|
self._polygon_points = []
|
||||||
|
|
||||||
|
def _assign_buildings_to_regions(self):
|
||||||
|
for building in self._buildings:
|
||||||
|
if building['geometry']['type'] == 'Polygon':
|
||||||
|
building_centroid = Polygon(building["geometry"]["coordinates"][0]).centroid
|
||||||
|
elif building['geometry']['type'] == 'MultiPolygon':
|
||||||
|
# use the centroid of the first polygon inside of the multipolygon
|
||||||
|
building_centroid = Polygon(building["geometry"]["coordinates"][0][0]).centroid
|
||||||
|
|
||||||
|
building['properties']['centroid'] = [building_centroid.x, building_centroid.y]
|
||||||
|
building['properties']['district_property'] = []
|
||||||
|
|
||||||
|
target_regions = []
|
||||||
|
region_assigned = False
|
||||||
|
|
||||||
|
target_region = self._regions[len(self._regions) / 2]
|
||||||
|
while not region_assigned:
|
||||||
|
if building_centroid.within(Polygon(target_region['geometry']['coordinates'])):
|
||||||
|
region_assigned = True
|
||||||
|
break
|
||||||
|
|
||||||
|
target_region_centroid = Polygon(target_region['geometry']['coordinates']).centroid
|
||||||
|
|
||||||
|
if building_centroid.x <= target_region_centroid.x:
|
||||||
|
if building_centroid.y >= target_region_centroid.y:
|
||||||
|
regions = regions[0:len(regions) / 2]
|
||||||
|
elif building_centroid.y < target_region_centroid.y:
|
||||||
|
regions = regions[len(regions) / 2:len(regions) - 1]
|
||||||
|
elif building_centroid.x > target_region_centroid.x:
|
||||||
|
if building_centroid.y >= target_region_centroid.y:
|
||||||
|
regions = regions[0:len(regions) / 2]
|
||||||
|
elif building_centroid.y < target_region_centroid.y:
|
||||||
|
regions = regions[len(regions) / 2:len(regions) - 1]
|
||||||
|
|
2
data/.gitignore
vendored
Normal file
2
data/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
*
|
||||||
|
!.gitignore
|
34
main.py
Normal file
34
main.py
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import json
|
||||||
|
from shapely import Polygon
|
||||||
|
from shapely import Point
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
# Make sure to enter your points in the clockwise direction
|
||||||
|
# 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]])
|
||||||
|
|
||||||
|
geojson_file = Path('./data/collinear_clean.geojson').resolve()
|
||||||
|
output_file = Path('./output_buildings.geojson').resolve()
|
||||||
|
buildings_in_region = []
|
||||||
|
|
||||||
|
with open(geojson_file, 'r') as file:
|
||||||
|
city = json.load(file)
|
||||||
|
buildings = city['features']
|
||||||
|
|
||||||
|
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))
|
27
map_view_simple_example.py
Normal file
27
map_view_simple_example.py
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import tkinter
|
||||||
|
import tkintermapview
|
||||||
|
|
||||||
|
# create tkinter window
|
||||||
|
root_tk = tkinter.Tk()
|
||||||
|
root_tk.geometry(f"{1000}x{700}")
|
||||||
|
root_tk.title("Building Selection Tool")
|
||||||
|
|
||||||
|
# create map widget
|
||||||
|
map_widget = tkintermapview.TkinterMapView(root_tk, width=1000, height=700, corner_radius=0)
|
||||||
|
map_widget.pack(fill="both", expand=True)
|
||||||
|
|
||||||
|
# set other tile server (standard is OpenStreetMap)
|
||||||
|
map_widget.set_tile_server("https://mt0.google.com/vt/lyrs=m&hl=en&x={x}&y={y}&z={z}&s=Ga", max_zoom=22) # google normal
|
||||||
|
# map_widget.set_tile_server("https://mt0.google.com/vt/lyrs=s&hl=en&x={x}&y={y}&z={z}&s=Ga", max_zoom=22) # google satellite
|
||||||
|
|
||||||
|
# set current position and zoom
|
||||||
|
map_widget.set_position(45.497059, -73.578451, marker=False) # Berlin, Germany
|
||||||
|
map_widget.set_zoom(11)
|
||||||
|
|
||||||
|
# set current position with address
|
||||||
|
# map_widget.set_address("Berlin Germany", marker=False)
|
||||||
|
|
||||||
|
def marker_click(marker):
|
||||||
|
print(f"marker clicked - text: {marker.text} position: {marker.position}")
|
||||||
|
|
||||||
|
root_tk.mainloop()
|
Loading…
Reference in New Issue
Block a user