{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import json\nimport numpy as np\nimport pandas as pd\nfrom pathlib import Path\nimport multiprocessing\nfrom tqdm import tqdm","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"SEED = 1111\n\nFLOOR_MAP = {\"B2\":-2, \"B1\":-1, \"F1\":0, \"F2\":1, \"F3\":2, \"F4\":3, \"F5\":4, \"F6\":5, \"F7\":6, \"F8\":7, \"F9\":8,\n             \"1F\":0, \"2F\":1, \"3F\":2, \"4F\":3, \"5F\":4, \"6F\":5, \"7F\":6, \"8F\":7, \"9F\":8}\n\nWAYPOINTS_DF = pd.read_csv('/kaggle/input/indoor-supplementals-for-postprocessing/waypoint.csv')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def metadata_dir():\n    return Path('/kaggle/input/indoor-location-navigation/metadata')\n\ndef floor2strs(floor):\n    return [key for key, val in FLOOR_MAP.items() if val == floor]\n\ndef get_map_info(site, floor):\n    for floor_str in floor2strs(floor):\n        json_path = metadata_dir() / site / floor_str / \"floor_info.json\"\n        if json_path.exists():\n            break\n    with open(json_path, \"r\") as f:\n        info = json.load(f)\n    height = info['map_info']['height']\n    width  = info['map_info']['width']\n    return height, width\n\ndef find_nearest_waypoints(xy, waypoints):\n    r = np.sum((waypoints - xy)**2, axis=1)\n    j = np.argmin(r)\n    return waypoints[j, :]\n\ndef coodinate_to_pixel(x, y, height, width, shape):\n    p_x = int((x / width)  * shape[1])\n    p_y = int((1 - y / height) * shape[0])\n    p_x = max(0, min(shape[1] - 1, p_x))\n    p_y = max(0, min(shape[0] - 1, p_y))\n    return p_x, p_y","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def generate_grid_point(args):\n    site, floor = args\n    if site == '5d27075f03f801723c2e360f':\n        # フロアサイズ修正の影響が分からないのでスキップ\n        return None\n\n    permitted_mask = np.load(f'/kaggle/input/indoor-hallway-images/{site}_{floor}.npy')\n    waypoints = WAYPOINTS_DF[(WAYPOINTS_DF['site'] == site) & (WAYPOINTS_DF['floor'] == floor)][['x', 'y']].values\n    height, width = get_map_info(site, floor)\n    extra_grid_points = np.zeros((0, 2))\n    \n    rgen = np.random.default_rng(SEED)\n    for i in range(10000):\n        x = rgen.uniform(low=0.0, high=width)\n        y = rgen.uniform(low=0.0, high=height)\n        p_x, p_y = coodinate_to_pixel(x, y, height, width, permitted_mask.shape)\n        if permitted_mask[p_y, p_x] == 1:\n            xy = np.array([x, y])\n            xy_near_1 = find_nearest_waypoints(xy, waypoints)\n            r1 = np.sqrt(np.sum((xy - xy_near_1)**2))\n            if extra_grid_points.shape[0] > 0:\n                xy_near_2 = find_nearest_waypoints(xy, extra_grid_points)\n                r2 = np.sqrt(np.sum((xy - xy_near_2)**2))\n            else:\n                r2 = float('inf')\n            if (r1 > 5.0) and (r2 > 2.5):\n                extra_grid_points = np.concatenate([extra_grid_points, np.expand_dims(xy, axis=0)])\n    if extra_grid_points.shape[0] == 0:\n        return None\n    else:\n        out_df = pd.DataFrame({\n            'x' : extra_grid_points[:, 0],\n            'y' : extra_grid_points[:, 1],\n        })\n        out_df['site']  = site\n        out_df['floor'] = floor\n        return out_df","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def main():\n    sub = pd.read_csv('/kaggle/input/indoor-submissions/submission_raw_5728_fix_floor.csv')\n    tmp = sub['site_path_timestamp'].apply(lambda x: pd.Series(x.split('_')))\n    sub['site'] = tmp[0]\n    site_floor = sub[['site', 'floor']].drop_duplicates().values\n    processes = multiprocessing.cpu_count()\n    with multiprocessing.Pool(processes=processes) as pool:\n        dfs = pool.imap_unordered(generate_grid_point, site_floor)\n        dfs = tqdm(dfs)\n        dfs = [df for df in dfs if df is not None]\n    df = pd.concat(dfs).sort_values(['site', 'floor'])\n    df.to_csv('extra_grid_points_v2.csv', index=False)\n    return","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"main()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}