diff --git a/city_model_structure/attributes/node.py b/city_model_structure/attributes/node.py index 50b617c6..6060539b 100644 --- a/city_model_structure/attributes/node.py +++ b/city_model_structure/attributes/node.py @@ -8,7 +8,6 @@ Contributor Milad milad.aghamohamadnia@concordia.ca import uuid from typing import List, TypeVar from city_model_structure.attributes.time_series import TimeSeries - Edge = TypeVar('Edge') diff --git a/city_model_structure/transport/bus_edge.py b/city_model_structure/transport/bus_edge.py index 9d9f967a..d5a02a32 100644 --- a/city_model_structure/transport/bus_edge.py +++ b/city_model_structure/transport/bus_edge.py @@ -4,9 +4,10 @@ SPDX - License - Identifier: LGPL - 3.0 - or -later Copyright © 2021 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca """ -from typing import List +from typing import List, TypeVar from city_model_structure.attributes.edge import Edge -from city_model_structure.transport.bus_node import BusNode + +BusNode = TypeVar('BusNode') class BusEdge(Edge): diff --git a/city_model_structure/transport/bus_node.py b/city_model_structure/transport/bus_node.py index 03113fdf..17274a4f 100644 --- a/city_model_structure/transport/bus_node.py +++ b/city_model_structure/transport/bus_node.py @@ -4,11 +4,12 @@ SPDX - License - Identifier: LGPL - 3.0 - or -later Copyright © 2021 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca """ -from typing import List +from typing import List, TypeVar from city_model_structure.attributes.node import Node from city_model_structure.attributes.point import Point -from city_model_structure.transport.bus_edge import BusEdge + +BusEdge = TypeVar('BusEdge') class BusNode(Node): diff --git a/city_model_structure/transport/origin_destination_edge.py b/city_model_structure/transport/origin_destination_edge.py index 664bdd81..32fa7cbb 100644 --- a/city_model_structure/transport/origin_destination_edge.py +++ b/city_model_structure/transport/origin_destination_edge.py @@ -5,11 +5,12 @@ Copyright © 2021 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.mons """ -from typing import List +from typing import List, TypeVar from city_model_structure.attributes.edge import Edge -from city_model_structure.transport.origin_destination_node import OriginDestinationNode from city_model_structure.attributes.schedule import Schedule +OriginDestinationNode = TypeVar('OriginDestinationNode') + class OriginDestinationEdge(Edge): """ diff --git a/city_model_structure/transport/origin_destination_node.py b/city_model_structure/transport/origin_destination_node.py index eabf06fb..ea84bd5c 100644 --- a/city_model_structure/transport/origin_destination_node.py +++ b/city_model_structure/transport/origin_destination_node.py @@ -3,13 +3,14 @@ Origin-Destination node module SPDX - License - Identifier: LGPL - 3.0 - or -later Copyright © 2021 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca """ -from typing import List +from typing import List, TypeVar from city_model_structure.attributes.node import Node from city_model_structure.attributes.point import Point from city_model_structure.attributes.polygon import Polygon from city_model_structure.city_object import CityObject -from city_model_structure.transport.origin_destination_edge import OriginDestinationEdge + +OriginDestinationEdge = TypeVar('OriginDestinationEdge') class OriginDestinationNode(Node): diff --git a/city_model_structure/transport/traffic_node.py b/city_model_structure/transport/traffic_node.py index 6391750e..6188e6e5 100644 --- a/city_model_structure/transport/traffic_node.py +++ b/city_model_structure/transport/traffic_node.py @@ -6,13 +6,14 @@ Contributor Milad milad.aghamohamadnia@concordia.ca Contributor Guille guille.gutierrezmorote@concordia.ca """ -from typing import List +from typing import List, TypeVar from city_model_structure.attributes.edge import Edge from city_model_structure.attributes.node import Node from city_model_structure.attributes.point import Point -from city_model_structure.transport.traffic_edge import TrafficEdge -from city_model_structure.transport.connection import Connection + +Connection = TypeVar('Connection') +TrafficEdge = TypeVar('TrafficEdge') class TrafficNode(Node): diff --git a/helpers/configuration_helper.py b/helpers/configuration_helper.py index 0a9b2d6c..de99f24a 100644 --- a/helpers/configuration_helper.py +++ b/helpers/configuration_helper.py @@ -38,4 +38,4 @@ class ConfigurationHelper: Get configured maximal coordinate value :return: 1.7976931348623157e+308 """ - return self._config.getfloat('buildings', 'max_coordinate') + return self._config.getfloat('buildings', 'max_coordinate').real diff --git a/imports/geometry/rhino.py b/imports/geometry/rhino.py new file mode 100644 index 00000000..66f200d8 --- /dev/null +++ b/imports/geometry/rhino.py @@ -0,0 +1,77 @@ +""" +Rhino module parses rhino files and import the geometry into the city model structure +SPDX - License - Identifier: LGPL - 3.0 - or -later +Copyright © 2020 Project Author Guille Gutierrez guillermo.gutierrezmorote@concordia.ca +""" +from rhino3dm import * +from rhino3dm._rhino3dm import MeshType +import numpy as np + +import helpers.configuration_helper +from city_model_structure.attributes.polygon import Polygon +from city_model_structure.building import Building +from city_model_structure.city import City +from city_model_structure.building_demand.surface import Surface as LibsSurface +from imports.geometry.helpers.geometry_helper import GeometryHelper +from helpers.configuration_helper import ConfigurationHelper + + +class Rhino: + def __init__(self, path): + self._model = File3dm.Read(str(path)) + max_float = 1.7976931348623157e+308 + min_float = -1.7976931348623157e+308 + self._min_x = self._min_y = self._min_z = max_float + self._max_x = self._max_y = self._max_z = min_float + print('init') + + @staticmethod + def _solid_points(coordinates) -> np.ndarray: + solid_points = np.fromstring(coordinates, dtype=float, sep=' ') + solid_points = GeometryHelper.to_points_matrix(solid_points) + return solid_points + + def _lower_corner(self, x, y, z): + if x < self._min_x: + self._min_x = x + if y < self._min_y: + self._min_y = y + if z < self._min_z: + self._min_z = z + if x > self._max_x: + self._max_x = x + if y > self._max_y: + self._max_y = y + if z > self._max_z: + self._max_z = z + + @property + def city(self) -> City: + buildings = [] + print('city') + for obj in self._model.Objects: + name = obj.Attributes.Id + surfaces = [] + for face in obj.Geometry.Faces: + if face is None: + break + _mesh = face.GetMesh(MeshType.Default) + for i in range(0, len(_mesh.Faces)): + faces = _mesh.Faces[i] + _points = '' + + for index in faces: + self._lower_corner(_mesh.Vertices[index].X, _mesh.Vertices[index].Y, _mesh.Vertices[index].Z) + _points = _points + f'{_mesh.Vertices[index].X} {_mesh.Vertices[index].Y} {_mesh.Vertices[index].Z} ' + polygon_points = Rhino._solid_points(_points.strip()) + print(_points) + surfaces.append(LibsSurface(Polygon(polygon_points), Polygon(polygon_points))) + buildings.append(Building(name, 3, surfaces, 'unknown', 'unknown', (self._min_x, self._min_y, self._min_z), [])) + lower_corner = (self._min_x, self._min_y, self._min_z) + upper_corner = (self._max_x, self._max_y, self._max_z) + city = City(lower_corner, upper_corner, 'Montreal') + for building in buildings: + city.add_city_object(building) + return city + + diff --git a/imports/geometry_factory.py b/imports/geometry_factory.py index ae2c3e29..d24199bf 100644 --- a/imports/geometry_factory.py +++ b/imports/geometry_factory.py @@ -8,6 +8,7 @@ from city_model_structure.city import City from imports.geometry.citygml import CityGml from imports.geometry.obj import Obj from imports.geometry.osm_subway import OsmSubway +from imports.geometry.rhino import Rhino class GeometryFactory: @@ -42,6 +43,14 @@ class GeometryFactory: """ return OsmSubway(self._path).city + @property + def _rhino(self) -> City: + """ + Enrich the city by using OpenStreetMap information as data source + :return: City + """ + return Rhino(self._path).city + @property def city(self) -> City: """ @@ -49,3 +58,11 @@ class GeometryFactory: :return: City """ return getattr(self, self._file_type, lambda: None) + + @property + def city_debug(self) -> City: + """ + Enrich the city given to the class using the class given handler + :return: City + """ + return Rhino(self._path).city diff --git a/requirements.txt b/requirements.txt index 48d73cf7..677cfa53 100644 --- a/requirements.txt +++ b/requirements.txt @@ -12,4 +12,5 @@ xlrd~=2.0.1 openpyxl~=3.0.7 networkx~=2.5.1 parseidf~=1.0.0 -ply~=3.11 \ No newline at end of file +ply~=3.11 +rhino3dm~=7.7.0 \ No newline at end of file