Skip to content
Snippets Groups Projects
test_gis_utils.py 69.5 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
    
    # 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