Skip to content
Snippets Groups Projects
test_gis_utils.py 88.4 KiB
Newer Older
  • Learn to ignore specific revisions
  • Pedro Magalhães's avatar
    Pedro Magalhães committed
    # imports
    
    # standard
    
    from ast import literal_eval
    import random
    
    # local, external
    
    from geopandas import GeoDataFrame
    from pandas import concat, MultiIndex, Series
    import networkx as nx
    import osmnx as ox
    from shapely.geometry import Point, LineString
    
    from shapely import intersects
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
    
    # local, internal
    
    import src.topupopt.data.gis.identify as gis_iden
    import src.topupopt.data.gis.utils as gis_utils
    import src.topupopt.data.gis.osm as _osm
    
    ox.settings.use_cache = True
    
    
    # *****************************************************************************
    # *****************************************************************************
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
    class TestGisUtils:
        # *************************************************************************
        # *************************************************************************
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
        def test_examples(self):
            # test io
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
    
            self.example_io_geodataframe(preserve_original_gdf=True, identify_columns=False)
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            self.example_io_geodataframe(
                preserve_original_gdf=False, identify_columns=False
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            # example_io_geodataframe(
            #     preserve_original_gdf=True, identify_columns=True
            #     )
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            # example_io_geodataframe(
            #     preserve_original_gdf=False, identify_columns=True
            #     )
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            # TODO: handle GeoJSON files
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            # example_io_geodataframe(preserve_original_gdf=True,
            #                         file_extension='.json')
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            # example_io_geodataframe(preserve_original_gdf=False,
            #                         file_extension='.json')
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
        # *************************************************************************
        # *************************************************************************
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
        def test_identifying_entrances_simple_no_driveway(self):
            # no driveway, all nodes
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            self.example_identify_entrances_simple_no_driveway(
                AB_right_BC_wrong=True,
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                focus_on_node_P_only=False,
            )
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            self.example_identify_entrances_simple_no_driveway(
                AB_right_BC_wrong=False,
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                focus_on_node_P_only=False,
            )
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            self.example_identify_entrances_simple_no_driveway(
                AB_right_BC_wrong=True,
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                focus_on_node_P_only=False,
            )
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            self.example_identify_entrances_simple_no_driveway(
                AB_right_BC_wrong=False,
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                focus_on_node_P_only=False,
            )
    
    
            # no driveway, all nodes, multiple addresses per edge
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            self.example_identify_entrances_simple_no_driveway(
                AB_right_BC_wrong=True,
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
                focus_on_node_P_only=False,
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                use_multiple_addresses=True,
            )
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            self.example_identify_entrances_simple_no_driveway(
                AB_right_BC_wrong=False,
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
                focus_on_node_P_only=False,
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                use_multiple_addresses=True,
            )
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            self.example_identify_entrances_simple_no_driveway(
                AB_right_BC_wrong=True,
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
                focus_on_node_P_only=False,
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                use_multiple_addresses=True,
            )
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            self.example_identify_entrances_simple_no_driveway(
                AB_right_BC_wrong=False,
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
                focus_on_node_P_only=False,
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                use_multiple_addresses=True,
            )
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            # no driveway, all nodes, revert projection
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            self.example_identify_entrances_simple_no_driveway(
                AB_right_BC_wrong=False,
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
                focus_on_node_P_only=False,
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                revert_to_original_crs=True,
            )
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            # no driveway, limited selection of nodes
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            self.example_identify_entrances_simple_no_driveway(
                AB_right_BC_wrong=True,
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                focus_on_node_P_only=True,
            )
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            self.example_identify_entrances_simple_no_driveway(
                AB_right_BC_wrong=False,
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                focus_on_node_P_only=True,
            )
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            self.example_identify_entrances_simple_no_driveway(
                AB_right_BC_wrong=True,
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                focus_on_node_P_only=True,
            )
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            self.example_identify_entrances_simple_no_driveway(
                AB_right_BC_wrong=False,
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                focus_on_node_P_only=True,
            )
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            # driveway, all nodes
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            self.example_identify_entrances_simple_driveway(
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                AB_right_BC_wrong=True, create_reversed_edges=False
            )
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            self.example_identify_entrances_simple_driveway(
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                AB_right_BC_wrong=False, create_reversed_edges=False
            )
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            self.example_identify_entrances_simple_driveway(
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                AB_right_BC_wrong=True, create_reversed_edges=True
            )
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            self.example_identify_entrances_simple_driveway(
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                AB_right_BC_wrong=False, create_reversed_edges=True
            )
    
    
            # driveway, all nodes, multiple addresses per edge
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            self.example_identify_entrances_simple_driveway(
                AB_right_BC_wrong=True,
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                use_multiple_addresses=True,
            )
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            self.example_identify_entrances_simple_driveway(
                AB_right_BC_wrong=False,
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                use_multiple_addresses=True,
            )
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            self.example_identify_entrances_simple_driveway(
                AB_right_BC_wrong=True,
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                use_multiple_addresses=True,
            )
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            self.example_identify_entrances_simple_driveway(
                AB_right_BC_wrong=False,
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                use_multiple_addresses=True,
            )
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            # driveway, limited selection
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            self.example_identify_entrances_simple_driveway(
                AB_right_BC_wrong=True,
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                focus_on_node_P_only=True,
            )
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            self.example_identify_entrances_simple_driveway(
                AB_right_BC_wrong=False,
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                focus_on_node_P_only=True,
            )
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            self.example_identify_entrances_simple_driveway(
                AB_right_BC_wrong=True,
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                focus_on_node_P_only=True,
            )
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            self.example_identify_entrances_simple_driveway(
                AB_right_BC_wrong=False,
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                focus_on_node_P_only=True,
            )
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            # driveway variation
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            self.example_identify_entrances_simple_driveway(
                AB_right_BC_wrong=True,
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
                focus_on_node_P_only=False,
                BD_with_name=False,
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                BD_right_address=False,
            )
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            self.example_identify_entrances_simple_driveway(
                AB_right_BC_wrong=True,
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
                focus_on_node_P_only=False,
                BD_with_name=True,
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                BD_right_address=False,
            )
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            self.example_identify_entrances_simple_driveway(
                AB_right_BC_wrong=False,
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
                focus_on_node_P_only=False,
                BD_with_name=True,
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                BD_right_address=False,
            )
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            self.example_identify_entrances_simple_driveway(
                AB_right_BC_wrong=True,
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
                focus_on_node_P_only=False,
                BD_with_name=True,
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                BD_right_address=True,
            )
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            # special cases
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            self.example_identify_entrances_simple_special(
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
                revert_to_original_crs=False,
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                focus_on_node_P_only=False,
            )
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            self.example_identify_entrances_simple_special(
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
                revert_to_original_crs=False,
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                focus_on_node_P_only=False,
            )
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            self.example_identify_entrances_simple_special(
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
                revert_to_original_crs=False,
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                focus_on_node_P_only=True,
            )
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            self.example_identify_entrances_simple_special(
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
                revert_to_original_crs=False,
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                focus_on_node_P_only=True,
            )
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            # no matching street name in the entire network
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            self.example_identify_entrances_simple_special(
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
                revert_to_original_crs=False,
                focus_on_node_P_only=False,
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                CE_wrong=True,
            )
    
    
            # TODO: test a case with multiple parallel edges
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
        # *************************************************************************
        # *************************************************************************
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
        def test_generating_node_containers(self):
            # test generating containers
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            self.example_generate_node_container(False, False)
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            self.example_generate_node_container(True, False)
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            self.example_generate_node_container(False, True)
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            self.example_generate_node_container(True, True)
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            self.example_generate_node_container(False, False, True)
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
        # *************************************************************************
        # *************************************************************************
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
    
        def get_node_gdf_A(
            self,
            right_address: str = "right",
            wrong_address: str = "wrong",
            country_code: str = _osm.KEY_COUNTRY_DK,
        ):
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            # 4 nodes: A, B, C and P
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
    
            # node A
    
            osmid_A = "A"
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            xy_A = (0, 0)
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            geo_A = Point(xy_A)
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            node_uid_A = 5123
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            address_A = None
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            # node B
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
    
            osmid_B = "B"
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            xy_B = (1, 0)
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            geo_B = Point(xy_B)
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            node_uid_B = 1844
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            address_B = None
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            # node C
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
    
            osmid_C = "C"
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            xy_C = (2, 0)
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            geo_C = Point(xy_C)
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            node_uid_C = 1845
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            address_C = None
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            # node P
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
    
            osmid_P = "P"
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            xy_P = (0.5, 1)
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            geo_P = Point(xy_P)
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            node_uid_P = 9475
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            address_P = right_address
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
    
            # **************************************************************************
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            # geodataframe: should have 'addr:street', 'osak:identifier' and index
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            gdf = GeoDataFrame(
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                data={
                    _osm.KEY_OSM_STREET: [
                        address_A,  # A
                        address_B,  # B
                        address_C,  # C
                        address_P,
                    ],  # P
                    _osm.KEY_OSM_BUILDING_ENTRANCE_ID[country_code]: [
                        node_uid_A,  # A
                        node_uid_B,  # B
                        node_uid_C,  # C
                        node_uid_P,
                    ],  # P
                    _osm.KEY_OSMNX_ELEMENT_TYPE: ["node", "node", "node", "node"],
                    _osm.KEY_OSMNX_OSMID: [osmid_A, osmid_B, osmid_C, osmid_P],
                },
                geometry=[geo_A, geo_B, geo_C, geo_P],
            )
    
            gdf.set_index(
                [_osm.KEY_OSMNX_ELEMENT_TYPE, _osm.KEY_OSMNX_OSMID], drop=True, inplace=True
            )
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            return gdf
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
    
            # **************************************************************************
    
    
        # *****************************************************************************
        # *****************************************************************************
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
    
        def get_node_gdf_B(
            self,
            right_address: str = "right",
            wrong_address: str = "wrong",
            country_code: str = _osm.KEY_COUNTRY_DK,
        ):
            # **************************************************************************
    
            gdf = self.get_node_gdf_A(
                right_address=right_address,
                wrong_address=wrong_address,
                country_code=country_code,
            )
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            # add another node D closer to P than A, B and C
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
    
            osmid_D = "D"
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            xy_D = (0.75, 1)
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            geo_D = Point(xy_D)
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            node_uid_D = 8842
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            # address_D = None
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
    
            gdf_node_D = GeoDataFrame(
                {
                    _osm.KEY_OSMNX_GEOMETRY: [geo_D],
                    _osm.KEY_OSM_BUILDING_ENTRANCE_ID[country_code]: [node_uid_D],
                    # _osm.KEY_OSM_STREET: [address_D],# P
                    # _osm.KEY_OSMNX_ELEMENT_TYPE: ['node'],
                    # _osm.KEY_OSMNX_OSMID: [osmid_D]
                },
                # index=[('node', osmid_D)],
                index=MultiIndex.from_tuples(
                    [("node", osmid_D)],
                    names=[_osm.KEY_OSMNX_ELEMENT_TYPE, _osm.KEY_OSMNX_OSMID],
                ),
            )
    
            # **************************************************************************
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            gdf = concat([gdf, gdf_node_D])
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            return gdf
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
    
            # **************************************************************************
    
    
        # *****************************************************************************
        # *****************************************************************************
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
    
        def get_node_gdf_C(
            self,
            right_address: str = "right",
            wrong_address: str = "wrong",
            country_code: str = _osm.KEY_COUNTRY_DK,
        ):
            # **************************************************************************
    
            gdf = self.get_node_gdf_B(
                right_address=right_address,
                wrong_address=wrong_address,
                country_code=country_code,
            )
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            # add another node E, east of C
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
    
            osmid_E = "E"
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            xy_E = (3, 0)
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            geo_E = Point(xy_E)
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            node_uid_E = 9173
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
    
            # address_E = right_address
    
            gdf_node_E = GeoDataFrame(
                {
                    _osm.KEY_OSMNX_GEOMETRY: [geo_E],
                    _osm.KEY_OSM_BUILDING_ENTRANCE_ID[country_code]: [node_uid_E],
                    # _osm.KEY_OSM_STREET: [address_E],
                },
                # index=[('node', osmid_E)]
                index=MultiIndex.from_tuples(
                    [("node", osmid_E)],
                    names=[_osm.KEY_OSMNX_ELEMENT_TYPE, _osm.KEY_OSMNX_OSMID],
                ),
            )
    
            # **************************************************************************
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            gdf = concat([gdf, gdf_node_E])
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            return gdf
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
    
            # **************************************************************************
    
    
        # *****************************************************************************
        # *****************************************************************************
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
    
        def get_network_A(
            self,
            gdf: GeoDataFrame,
            right_address: str = "right",
            wrong_address: str = "wrong",
            AB_right_BC_wrong: bool = True,
            country_code: str = _osm.KEY_COUNTRY_DK,
            use_multiple_addresses: bool = False,
        ):
            # **************************************************************************
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            # create network
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
    
            (
                node_keys,
                node_data_container,
                node_key_to_gdf_index_dict,
            ) = gis_utils.prepare_node_data_from_geodataframe(
                include_geometry=True, gdf=gdf
            )
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            network = nx.MultiDiGraph()
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
    
            network.graph["crs"] = "EPSG:4326"
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            network.add_nodes_from(node_data_container)
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
    
            # **************************************************************************
    
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
    
            node_key_A = "A"
            node_key_B = "B"
            node_key_C = "C"
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            geo_AB = LineString(
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                [
                    (
                        network.nodes[node_key_A][_osm.KEY_OSMNX_X],
                        network.nodes[node_key_A][_osm.KEY_OSMNX_Y],
                    ),
                    (
                        network.nodes[node_key_B][_osm.KEY_OSMNX_X],
                        network.nodes[node_key_B][_osm.KEY_OSMNX_Y],
                    ),
                ]
            )
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            length_AB = network.nodes[node_key_A][_osm.KEY_OSMNX_GEOMETRY].distance(
                network.nodes[node_key_B][_osm.KEY_OSMNX_GEOMETRY]
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
            )
    
            network.add_edge(
                node_key_A,
                node_key_B,
                **{
                    _osm.KEY_OSMNX_GEOMETRY: geo_AB,
                    _osm.KEY_OSMNX_LENGTH: length_AB,
                    _osm.KEY_OSMNX_NAME: (
                        ["HZ", (right_address if AB_right_BC_wrong else wrong_address)]
                        if use_multiple_addresses
                        else (right_address if AB_right_BC_wrong else wrong_address)
                    ),
                }
            )
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            geo_BC = LineString(
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                [
                    (
                        network.nodes[node_key_B][_osm.KEY_OSMNX_X],
                        network.nodes[node_key_B][_osm.KEY_OSMNX_Y],
                    ),
                    (
                        network.nodes[node_key_C][_osm.KEY_OSMNX_X],
                        network.nodes[node_key_C][_osm.KEY_OSMNX_Y],
                    ),
                ]
            )
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            length_BC = network.nodes[node_key_B][_osm.KEY_OSMNX_GEOMETRY].distance(
                network.nodes[node_key_C][_osm.KEY_OSMNX_GEOMETRY]
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
            )
    
            network.add_edge(
                node_key_B,
                node_key_C,
                **{
                    _osm.KEY_OSMNX_GEOMETRY: geo_BC,
                    _osm.KEY_OSMNX_LENGTH: length_BC,
                    _osm.KEY_OSMNX_NAME: (
                        [(wrong_address if AB_right_BC_wrong else right_address), "UQ"]
                        if use_multiple_addresses
                        else (wrong_address if AB_right_BC_wrong else right_address)
                    ),
                }
            )
    
            # **************************************************************************
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            return network, node_keys, node_key_to_gdf_index_dict
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
    
            # **************************************************************************
    
    
        # *****************************************************************************
        # *****************************************************************************
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
    
        def get_network_B(
            self,
            gdf: GeoDataFrame,
            right_address: str = "right",
            wrong_address: str = "wrong",
            AB_right_BC_wrong: bool = True,
            BD_with_name: bool = False,
            BD_right_address: bool = False,
            country_code: str = _osm.KEY_COUNTRY_DK,
            use_multiple_addresses: bool = False,
        ):
            # **************************************************************************
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            # create network
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            network, node_keys, node_key_to_gdf_index_dict = self.get_network_A(
                gdf=gdf,
                right_address=right_address,
                wrong_address=wrong_address,
                country_code=country_code,
                AB_right_BC_wrong=AB_right_BC_wrong,
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                use_multiple_addresses=use_multiple_addresses,
            )
    
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
    
            node_key_B = "B"
            node_key_D = "D"
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            geo_BD = LineString(
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                [
                    (
                        network.nodes[node_key_B][_osm.KEY_OSMNX_X],
                        network.nodes[node_key_B][_osm.KEY_OSMNX_Y],
                    ),
                    (
                        network.nodes[node_key_D][_osm.KEY_OSMNX_X],
                        network.nodes[node_key_D][_osm.KEY_OSMNX_Y],
                    ),
                ]
            )
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            length_BD = network.nodes[node_key_B][_osm.KEY_OSMNX_GEOMETRY].distance(
                network.nodes[node_key_D][_osm.KEY_OSMNX_GEOMETRY]
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            BD_dict = {
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                _osm.KEY_OSMNX_GEOMETRY: geo_BD,
                _osm.KEY_OSMNX_LENGTH: length_BD,
                # _osm.KEY_OSMNX_NAME: ( # no name for BD
                #    right_address if AB_right_BC_wrong else
                #    wrong_address)
            }
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            if BD_with_name:
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                BD_dict[_osm.KEY_OSMNX_NAME] = (
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
                    right_address if BD_right_address else wrong_address
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                )
    
            network.add_edge(node_key_B, node_key_D, **BD_dict)
    
            # **************************************************************************
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            return network, node_keys, node_key_to_gdf_index_dict
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
    
            # **************************************************************************
    
    
        # *****************************************************************************
        # *****************************************************************************
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
    
        def get_network_C(
            self,
            gdf: GeoDataFrame,
            right_address: str = "right",
            wrong_address: str = "wrong",
            country_code: str = _osm.KEY_COUNTRY_DK,
            CE_wrong: bool = False,
            use_multiple_addresses: bool = False,
        ):
            # **************************************************************************
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            # create network
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            network, node_keys, node_key_to_gdf_index_dict = self.get_network_B(
                gdf=gdf,
                right_address=wrong_address,
                wrong_address=wrong_address,
                country_code=country_code,
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                AB_right_BC_wrong=True,
            )
    
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
    
            node_key_C = "C"
            node_key_E = "E"
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            geo_CE = LineString(
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                [
                    (
                        network.nodes[node_key_C][_osm.KEY_OSMNX_X],
                        network.nodes[node_key_C][_osm.KEY_OSMNX_Y],
                    ),
                    (
                        network.nodes[node_key_E][_osm.KEY_OSMNX_X],
                        network.nodes[node_key_E][_osm.KEY_OSMNX_Y],
                    ),
                ]
            )
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            length_CE = network.nodes[node_key_C][_osm.KEY_OSMNX_GEOMETRY].distance(
                network.nodes[node_key_E][_osm.KEY_OSMNX_GEOMETRY]
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
            )
    
            network.add_edge(
                node_key_C,
                node_key_E,
                **{
                    _osm.KEY_OSMNX_GEOMETRY: geo_CE,
                    _osm.KEY_OSMNX_LENGTH: length_CE,
                    _osm.KEY_OSMNX_NAME: (wrong_address if CE_wrong else right_address),
                }
            )
    
            # **************************************************************************
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            return network, node_keys, node_key_to_gdf_index_dict
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
    
            # **************************************************************************
    
    
        # *****************************************************************************
        # *****************************************************************************
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
        def example_identify_entrances_simple_special(
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
            self,
            create_reversed_edges: bool = False,
            revert_to_original_crs: bool = False,
            focus_on_node_P_only: bool = False,
            CE_wrong: bool = False,
        ):
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            # get problem details
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            country_code = _osm.KEY_COUNTRY_DK
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            gdf = self.get_node_gdf_C(country_code=country_code)
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            network, node_keys, node_key_to_gdf_index_dict = self.get_network_C(
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                gdf=gdf, country_code=country_code, CE_wrong=CE_wrong
            )
    
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                previous_edge_keys = list(edge_key for edge_key in network.edges(keys=True))
    
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                    edge_dict = network.get_edge_data(
                        u=edge_key[0], v=edge_key[1], key=edge_key[2]
                    )
    
                    network.add_edge(
                        u_for_edge=edge_key[1], v_for_edge=edge_key[0], **edge_dict
                    )
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            if focus_on_node_P_only:
    
                nearest_edge_keys, _, _ = gis_utils.identify_building_entrance_edges(
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                    gdf=gdf,
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
                    gdf_street_column=_osm.KEY_OSM_STREET,
                    network=network,
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                    node_key_to_gdf_index_dict={"P": node_key_to_gdf_index_dict["P"]},
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
                    crs=None,
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                    revert_to_original_crs=revert_to_original_crs,
                )
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            else:
    
                nearest_edge_keys, _, _ = gis_utils.identify_building_entrance_edges(
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                    gdf=gdf,
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
                    gdf_street_column=_osm.KEY_OSM_STREET,
                    network=network,
                    node_key_to_gdf_index_dict=node_key_to_gdf_index_dict,
                    crs=None,
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                    revert_to_original_crs=revert_to_original_crs,
                )
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            # validate the outcome
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            if CE_wrong:
    
                # no edges with the right address, the closest edge should be selected
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
    
                assert ("B", "D", 0) == nearest_edge_keys["P"] or (
                    "D",
                    "B",
                    0,
                ) == nearest_edge_keys["P"]
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            else:
                # CE has the right address, it should be selected
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
    
                assert ("C", "E", 0) == nearest_edge_keys["P"] or (
                    "E",
                    "C",
                    0,
                ) == nearest_edge_keys["P"]
    
            # **************************************************************************
    
    
        # *****************************************************************************
        # *****************************************************************************
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
        def example_identify_entrances_simple_driveway(
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
            self,
            AB_right_BC_wrong: bool = True,
            create_reversed_edges: bool = False,
            revert_to_original_crs: bool = False,
            focus_on_node_P_only: bool = False,
            BD_with_name: bool = False,
            BD_right_address: bool = False,
            use_multiple_addresses: bool = False,
        ):
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            # get problem details
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            country_code = _osm.KEY_COUNTRY_DK
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            gdf = self.get_node_gdf_B(country_code=country_code)
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            network, node_keys, node_key_to_gdf_index_dict = self.get_network_B(
                gdf=gdf,
                country_code=country_code,
                BD_with_name=BD_with_name,
                BD_right_address=BD_right_address,
                AB_right_BC_wrong=AB_right_BC_wrong,
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                use_multiple_addresses=use_multiple_addresses,
            )
    
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                previous_edge_keys = list(edge_key for edge_key in network.edges(keys=True))
    
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                    edge_dict = network.get_edge_data(
                        u=edge_key[0], v=edge_key[1], key=edge_key[2]
                    )
    
                    network.add_edge(
                        u_for_edge=edge_key[1], v_for_edge=edge_key[0], **edge_dict
                    )
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            if focus_on_node_P_only:
    
                nearest_edge_keys, _, _ = gis_utils.identify_building_entrance_edges(
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                    gdf=gdf,
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
                    gdf_street_column=_osm.KEY_OSM_STREET,
                    network=network,
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                    node_key_to_gdf_index_dict={"P": node_key_to_gdf_index_dict["P"]},
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
                    crs=None,
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                    revert_to_original_crs=revert_to_original_crs,
                )
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            else:
    
                nearest_edge_keys, _, _ = gis_utils.identify_building_entrance_edges(
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                    gdf=gdf,
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
                    gdf_street_column=_osm.KEY_OSM_STREET,
                    network=network,
                    node_key_to_gdf_index_dict=node_key_to_gdf_index_dict,
                    crs=None,
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                    revert_to_original_crs=revert_to_original_crs,
                )
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            # validate the outcome
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            if BD_with_name and not BD_right_address:
                if AB_right_BC_wrong:
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                    assert ("A", "B", 0) == nearest_edge_keys["P"] or (
                        "B",
                        "A",
                        0,
                    ) == nearest_edge_keys["P"]
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
                else:
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                    assert ("B", "C", 0) == nearest_edge_keys["P"] or (
                        "C",
                        "B",
                        0,
                    ) == nearest_edge_keys["P"]
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            # elif BD_with_name and BD_right_address:
    
            #     assert (('B','D', 0) == nearest_edge_keys['P'] or
            #             ('D','B', 0) == nearest_edge_keys['P'])
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            else:
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                assert ("B", "D", 0) == nearest_edge_keys["P"] or (
                    "D",
                    "B",
                    0,
                ) == nearest_edge_keys["P"]
    
            # **************************************************************************
    
    
        # *****************************************************************************
        # *****************************************************************************
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
        def example_identify_entrances_simple_no_driveway(
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
            self,
            AB_right_BC_wrong: bool = True,
            create_reversed_edges: bool = False,
            focus_on_node_P_only: bool = False,
            revert_to_original_crs: bool = False,
            use_multiple_addresses: bool = False,
        ):
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            # get problem details
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            country_code = _osm.KEY_COUNTRY_DK
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            gdf = self.get_node_gdf_A(country_code=country_code)
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            network, node_keys, node_key_to_gdf_index_dict = self.get_network_A(
                gdf=gdf,
                country_code=country_code,
                AB_right_BC_wrong=AB_right_BC_wrong,
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                use_multiple_addresses=use_multiple_addresses,
            )
    
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                previous_edge_keys = list(edge_key for edge_key in network.edges(keys=True))
    
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                    edge_dict = network.get_edge_data(
                        u=edge_key[0], v=edge_key[1], key=edge_key[2]
                    )
    
                    network.add_edge(
                        u_for_edge=edge_key[1], v_for_edge=edge_key[0], **edge_dict
                    )
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            if focus_on_node_P_only:
    
                nearest_edge_keys, _, _ = gis_utils.identify_building_entrance_edges(
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                    gdf=gdf,
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
                    gdf_street_column=_osm.KEY_OSM_STREET,
                    network=network,
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                    node_key_to_gdf_index_dict={"P": node_key_to_gdf_index_dict["P"]},
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
                    crs=None,
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                    revert_to_original_crs=revert_to_original_crs,
                )
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            else:
    
                nearest_edge_keys, _, _ = gis_utils.identify_building_entrance_edges(
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                    gdf=gdf,
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
                    gdf_street_column=_osm.KEY_OSM_STREET,
                    network=network,
                    node_key_to_gdf_index_dict=node_key_to_gdf_index_dict,
                    crs=None,
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
                    revert_to_original_crs=revert_to_original_crs,
                )
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            # validate the outcome
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            if AB_right_BC_wrong:
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
    
                assert ("A", "B", 0) == nearest_edge_keys["P"]
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            else:
    
    Pedro L. Magalhães's avatar
    Pedro L. Magalhães committed
    
                assert ("B", "C", 0) == nearest_edge_keys["P"]
    
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
        # *************************************************************************
        # *************************************************************************
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
        def test_identify_entrances_simple_no_driveway_closest(self):
            # get problem details
    
    Pedro Magalhães's avatar
    Pedro Magalhães committed
            country_code = _osm.KEY_COUNTRY_DK