用 Wolfram 语言可视化东京地铁高峰时段列车的2D/3D 时空数据
东京Metro是日本的专用铁路公司,在东京都市区及周边地区运营地铁系统,东京Metro运营9条地铁线路,2020年东京Metro日均乘客量为498万人次。
三年前,我发布了东京地铁系统的 3D 视图(https://community.wolfram.com/groups/-/m/t/1632078),
这一次,我试图将从第一班地铁到早上 8 点的高峰时段的运行可视化。
地铁线
九条地铁线的名称:
line9Names={"ginza","marunouchi","hibiya","tozai","chiyoda","yurakucho","hanzomon","namboku","fukutoshin"};
其标志:
line9logs=Import["https://www.tokyometro.jp/library/common/img/route/icon_"<>#<>".png"]&/@line9Names
从标志中提取每条线的颜色:
line9cols=DominantColors[#][[1]]&/@line9logs
车站
每条线的车站信息(编号、日文名、英文名、地理位置、离地面的深度)如下。地理位置信息可以从网页 API(https://developer.tokyometroapp.jp/ja/info)获取,深度是从日文书中获得。
line9inf3D=InterpretationBox[DynamicModuleBox[{Set[Typeset`open, False]}, TemplateBox[{"List", "ListIcon", GridBox[{{ItemBox[RowBox[{TagBox["\"Head: \"", "IconizedLabel"], "\:f360", TagBox["List", "IconizedItem"]}]]}, {ItemBox[RowBox[{TagBox["\"Length: \"", "IconizedLabel"], "\:f360", TagBox["9", "IconizedItem"]}]]}, {ItemBox[RowBox[{TagBox["\"Byte count: \"", "IconizedLabel"], "\:f360", TagBox["52104", "IconizedItem"]}]]}}, GridBoxAlignment -> {"Columns" -> {{Left}}}, DefaultBaseStyle -> "Column", GridBoxItemSize -> {"Columns" -> {{Automatic}}, "Rows" -> {{Automatic}}}], Dynamic[Typeset`open]}, "IconizedObject"]], {{{1, "\:6e0b\:8c37", "Shibuya", {35.6590979695481`, 139.702673404052`}, 12.1`}, {2, "\:8868\:53c2\:9053", "Omote-sando", {35.665042546167`, 139.712472695145`}, -8.1`}, {3, "\:5916\:82d1\:524d", "Gaiemmae", {35.670375`, 139.717825`}, -9.5`}, {4, "\:9752\:5c71\:4e00\:4e01\:76ee", "Aoyama-itchome", {35.6727891830525`, 139.724145270768`}, -7.7`}, {5, "\:8d64\:5742\:898b\:9644", "Akasaka-mitsuke", {35.6768452185605`, 139.737347347875`}, -11.9`}, {6, "\:6e9c\:6c60\:5c71\:738b", "Tameike-sanno", {35.6715112700871`, 139.741942591836`}, -9.4`}, {7, "\:864e\:30ce\:9580", "Toranomon", {35.67016`, 139.75012`}, -8.5`}, {8, "\:65b0\:6a4b", "Shimbashi", {35.667381603947`, 139.758511675365`}, -10`}, {9, "\:9280\:5ea7", "Ginza", {35.6714990808382`, 139.765365883533`}, -9.3`}, {10, "\:4eac\:6a4b", "Kyobashi", {35.6767036291704`, 139.770109153624`}, -10.3`}, {11, "\:65e5\:672c\:6a4b", "Nihombashi", {35.6818799645189`, 139.773335055395`}, -10.5`}, {12, "\:4e09\:8d8a\:524d", "Mitsukoshimae", {35.6871737671005`, 139.773582291216`}, -9.8`}, {13, "\:795e\:7530", "Kanda", {35.693715`, 139.77089`}, -8`}, {14, "\:672b\:5e83\:753a", "Suehirocho", {35.7027802724813`, 139.771762651858`}, -7.4`}, {15, "\:4e0a\:91ce\:5e83\:5c0f\:8def", "Ueno-hirokoji", {35.7077658457101`, 139.773011683371`}, -8`}, {16, "\:4e0a\:91ce", "Ueno", {35.7118359292102`, 139.775624742036`}, -10.1`}, {17, "\:7a32\:8377\:753a", "Inaricho", {35.7113882905237`, 139.782210573068`}, -6.8`}, {18, "\:7530\:539f\:753a", "Tawaramachi", {35.7099170877701`, 139.790306456761`}, -7.7`}, {19, "\:6d45\:8349", "Asakusa", {35.7107463060383`, 139.79777333243`}, -8.8`}}, {{1, "\:837b\:7aaa", "Ogikubo", {35.704175`, 139.61976`}, -10.7`}, {2, "\:5357\:963f\:4f50\:30b1\:8c37", "Minami-asagaya", {35.699455`, 139.635575`}, -7.7`}, {3, "\:65b0\:9ad8\:5186\:5bfa", "Shin-koenji", {35.69786`, 139.64851`}, -7`}, {4, "\:6771\:9ad8\:5186\:5bfa", "Higashi-koenji", {35.697965`, 139.658295`}, -6.4`}, {5, "\:65b0\:4e2d\:91ce", "Shin-nakano", {35.697475`, 139.66951`}, -7.3`}, {6, "\:4e2d\:91ce\:5742\:4e0a", "Nakano-sakaue", {35.697085`, 139.682205`}, -9.8`}, {7, "\:897f\:65b0\:5bbf", "Nishi-shinjuku", {35.694515`, 139.69256`}, -10`}, {8, "\:65b0\:5bbf", "Shinjuku", {35.6924518824762`, 139.700547546631`}, -11.2`}, {9, "\:65b0\:5bbf\:4e09\:4e01\:76ee", "Shinjuku-sanchome", {35.69118`, 139.70421`}, -11`}, {10, "\:65b0\:5bbf\:5fa1\:82d1\:524d", "Shinjuku-gyoemmae", {35.688525`, 139.710915`}, -7.6`}, {11, "\:56db\:8c37\:4e09\:4e01\:76ee", "Yotsuya-sanchome", {35.687835`, 139.719325`}, -7.5`}, {12, "\:56db\:30c4\:8c37", "Yotsuya", {35.6841963947417`, 139.730047469488`}, 5.5`}, {13, "\:8d64\:5742\:898b\:9644", "Akasaka-mitsuke", {35.6768452185605`, 139.737347347875`}, -11.7`}, {14, "\:56fd\:4f1a\:8b70\:4e8b\:5802\:524d", "Kokkai-gijidomae", {35.6749267100241`, 139.745472827969`}, -11.2`}, {15, "\:971e\:30b1\:95a2", "Kasumigaseki", {35.674235`, 139.75268`}, -11.3`}, {16, "\:9280\:5ea7", "Ginza", {35.6714990808382`, 139.765365883533`}, -10.3`}, {17, "\:6771\:4eac", "Tokyo", {35.681935`, 139.7648`}, -10.3`}, {18, "\:5927\:624b\:753a", "Otemachi", {35.6868754460118`, 139.766203207735`}, -10.2`}, {19, "\:6de1\:8def\:753a", "Awajicho", {35.69487`, 139.767455`}, -8.1`}, {20, "\:5fa1\:8336\:30ce\:6c34", "Ochanomizu", {35.70043`, 139.764405`}, -7.6`}, {21, "\:672c\:90f7\:4e09\:4e01\:76ee", "Hongo-sanchome", {35.7067264129514`, 139.760153917871`}, -6.3`}, {22, "\:5f8c\:697d\:5712", "Korakuen", {35.7073066769895`, 139.7508602691`}, 3.5`}, {23, "\:8317\:8377\:8c37", "Myogadani", {35.7172`, 139.736895`}, -5.9`}, {24, "\:65b0\:5927\:585a", "Shin-otsuka", {35.726129638041`, 139.729354745865`}, -6.8`}, {25, "\:6c60\:888b", "Ikebukuro", {35.730345`, 139.71115`}, -8.7`}}, {{1, "\:4e2d\:76ee\:9ed2", "Naka-meguro", {35.6441080202301`, 139.698832425194`}, 5.2`}, {2, "\:6075\:6bd4\:5bff", "Ebisu", {35.6470397634141`, 139.708700341105`}, -11.2`}, {3, "\:5e83\:5c3e", "Hiro-o", {35.6514999604126`, 139.72220861331`}, -10`}, {4, "\:516d\:672c\:6728", "Roppongi", {35.6628`, 139.731155`}, -11.8`}, {5, "\:795e\:8c37\:753a", "Kamiyacho", {35.662625`, 139.744725`}, -11.3`}, {6, "\:864e\:30ce\:9580\:30d2\:30eb\:30ba", "Toranomon-hills", {35.667309`, 139.747738`}, -8`}, {7, "\:971e\:30b1\:95a2", "Kasumigaseki", {35.674235`, 139.75268`}, -16.4`}, {8, "\:65e5\:6bd4\:8c37", "Hibiya", {35.6742710013047`, 139.760600691986`}, -18.8`}, {9, "\:9280\:5ea7", "Ginza", {35.6714990808382`, 139.765365883533`}, -15.8`}, {10, "\:6771\:9280\:5ea7", "Higashi-ginza", {35.6691280784214`, 139.767633152719`}, -15.3`}, {11, "\:7bc9\:5730", "Tsukiji", {35.6679270909774`, 139.772473360068`}, -10.2`}, {12, "\:516b\:4e01\:5800", "Hatchobori", {35.6753682794216`, 139.777334452681`}, -12.2`}, {13, "\:8305\:5834\:753a", "Kayabacho", {35.6790786660457`, 139.779619026388`}, -8.5`}, {14, "\:4eba\:5f62\:753a", "Ningyocho", {35.6862586172466`, 139.782338414834`}, -10.4`}, {15, "\:5c0f\:4f1d\:99ac\:753a", "Kodemmacho", {35.6904226740354`, 139.778757334227`}, -9.7`}, {16, "\:79cb\:8449\:539f", "Akihabara", {35.6979648586317`, 139.775529188988`}, -12.4`}, {17, "\:4ef2\:5fa1\:5f92\:753a", "Naka-okachimachi", {35.706655`, 139.77619`}, -9.6`}, {18, "\:4e0a\:91ce", "Ueno", {35.7118359292102`, 139.775624742036`}, -13.7`}, {19, "\:5165\:8c37", "Iriya", {35.7205648909451`, 139.78446653599`}, -9.2`}, {20, "\:4e09\:30ce\:8f2a", "Minowa", {35.729285`, 139.791165`}, -10.8`}, {21, "\:5357\:5343\:4f4f", "Minami-senju", {35.73231`, 139.79878`}, 8`}, {22, "\:5317\:5343\:4f4f", "Kita-senju", {35.7499044695792`, 139.805591721424`}, 14.4`}}, {{1, "\:4e2d\:91ce", "Nakano", {35.70574`, 139.665605`}, 0.7`}, {2, "\:843d\:5408", "Ochiai", {35.710635`, 139.685965`}, -12.6`}, {3, "\:9ad8\:7530\:99ac\:5834", "Takadanobaba", {35.71328`, 139.705045`}, -12.9`}, {4, "\:65e9\:7a32\:7530", "Waseda", {35.70568`, 139.72219`}, -10.8`}, {5, "\:795e\:697d\:5742", "Kagurazaka", {35.703865`, 139.73452`}, -11.6`}, {6, "\:98ef\:7530\:6a4b", "Iidabashi", {35.7014035648064`, 139.74652120252`}, -10.8`}, {7, "\:4e5d\:6bb5\:4e0b", "Kudanshita", {35.6960918116116`, 139.751265393273`}, -11.4`}, {8, "\:7af9\:6a4b", "Takebashi", {35.69044`, 139.75767`}, -11.1`}, {9, "\:5927\:624b\:753a", "Otemachi", {35.6868754460118`, 139.766203207735`}, -18.4`}, {10, "\:65e5\:672c\:6a4b", "Nihombashi", {35.6818799645189`, 139.773335055395`}, -19.1`}, {11, "\:8305\:5834\:753a", "Kayabacho", {35.6790786660457`, 139.779619026388`}, -15.3`}, {12, "\:9580\:524d\:4ef2\:753a", "Monzen-nakacho", {35.6718922843785`, 139.79609888639`}, -11.4`}, {13, "\:6728\:5834", "Kiba", {35.6693553078894`, 139.807115133107`}, -22.4`}, {14, "\:6771\:967d\:753a", "Toyocho", {35.66959`, 139.81768`}, -10.9`}, {15, "\:5357\:7802\:753a", "Minami-sunamachi", {35.668415`, 139.831695`}, -6.2`}, {16, "\:897f\:845b\:897f", "Nishi-kasai", {35.6645619687544`, 139.85960016266`}, 10`}, {17, "\:845b\:897f", "Kasai", {35.6636167072847`, 139.872529795679`}, 9`}, {18, "\:6d66\:5b89", "Urayasu", {35.6659023964693`, 139.893236272609`}, 8.6`}, {19, "\:5357\:884c\:5fb3", "Minami-gyotoku", {35.6727297584295`, 139.902275205104`}, 7.7`}, {20, "\:884c\:5fb3", "Gyotoku", {35.6826190668061`, 139.914185779577`}, 7.4`}, {21, "\:5999\:5178", "Myoden", {35.6910143049273`, 139.924286391921`}, 7.4`}, {22, "\:539f\:6728\:4e2d\:5c71", "Baraki-nakayama", {35.7033`, 139.941915`}, 6.7`}, {23, "\:897f\:8239\:6a4b", "Nishi-funabashi", {35.7071745319225`, 139.958767346288`}, 0.9`}}, {{1, "\:4ee3\:3005\:6728\:4e0a\:539f", "Yoyogi-uehara", {35.6690171565856`, 139.679883961114`}, 8.6`}, {2, "\:4ee3\:3005\:6728\:516c\:5712", "Yoyogi-koen", {35.6691046359305`, 139.689790650732`}, -11.1`}, {3, "\:660e\:6cbb\:795e\:5bae\:524d\:3008\:539f\:5bbf\:3009", "Meiji-jingumae", {35.6691233335104`, 139.703943466256`}, -17.4`}, {4, "\:8868\:53c2\:9053", "Omote-sando", {35.665042546167`, 139.712472695145`}, -18.8`}, {5, "\:4e43\:6728\:5742", "Nogizaka", {35.6665919073782`, 139.72622853745`}, -19.3`}, {6, "\:8d64\:5742", "Akasaka", {35.6721047636732`, 139.736413627931`}, -15`}, {7, "\:56fd\:4f1a\:8b70\:4e8b\:5802\:524d", "Kokkai-gijidomae", {35.6749267100241`, 139.745472827969`}, -37.9`}, {8, "\:971e\:30b1\:95a2", "Kasumigaseki", {35.674235`, 139.75268`}, -8.2`}, {9, "\:65e5\:6bd4\:8c37", "Hibiya", {35.6742710013047`, 139.760600691986`}, -14.4`}, {10, "\:4e8c\:91cd\:6a4b\:524d", "Nijubashimae", {35.680505`, 139.76178`}, -15.3`}, {11, "\:5927\:624b\:753a", "Otemachi", {35.6868754460118`, 139.766203207735`}, -14.1`}, {12, "\:65b0\:5fa1\:8336\:30ce\:6c34", "Shin-ochanomizu", {35.696925`, 139.76545`}, -24.3`}, {13, "\:6e6f\:5cf6", "Yushima", {35.7068051447369`, 139.769980717045`}, -12.4`}, {14, "\:6839\:6d25", "Nezu", {35.717325`, 139.76575`}, -15.8`}, {15, "\:5343\:99c4\:6728", "Sendagi", {35.725745759653`, 139.763303354368`}, -15.4`}, {16, "\:897f\:65e5\:66ae\:91cc", "Nishi-nippori", {35.7323551550662`, 139.76688994252`}, -15.3`}, {17, "\:753a\:5c4b", "Machiya", {35.7420683621958`, 139.780047547035`}, -16.3`}, {18, "\:5317\:5343\:4f4f", "Kita-senju", {35.7499044695792`, 139.805591721424`}, -11.3`}, {19, "\:7dbe\:702c", "Ayase", {35.762285`, 139.82489`}, 7.1`}}, {{1, "\:548c\:5149\:5e02", "Wakoshi", {35.78835`, 139.612865`}, 1.7`}, {2, "\:5730\:4e0b\:9244\:6210\:5897", "Chikatetsu-narimasu", {35.77674`, 139.63117`}, -16.1`}, {3, "\:5730\:4e0b\:9244\:8d64\:585a", "Chikatetsu-akatsuka", {35.7699805639494`, 139.644000328985`}, -15.2`}, {4, "\:5e73\:548c\:53f0", "Heiwadai", {35.757555`, 139.6543`}, -17.7`}, {5, "\:6c37\:5ddd\:53f0", "Hikawadai", {35.74962`, 139.66547`}, -17.7`}, {6, "\:5c0f\:7af9\:5411\:539f", "Kotake-mukaihara", {35.743395`, 139.67952`}, -17.3`}, {7, "\:5343\:5ddd", "Senkawa", {35.738175`, 139.6894`}, -12.3`}, {8, "\:8981\:753a", "Kanamecho", {35.733215`, 139.69848`}, -16.1`}, {9, "\:6c60\:888b", "Ikebukuro", {35.730345`, 139.71115`}, -12.2`}, {10, "\:6771\:6c60\:888b", "Higashi-ikebukuro", {35.72595`, 139.718865`}, -13.8`}, {11, "\:8b77\:56fd\:5bfa", "Gokokuji", {35.71918`, 139.72745`}, -16.7`}, {12, "\:6c5f\:6238\:5ddd\:6a4b", "Edogawabashi", {35.709295`, 139.73413`}, -16`}, {13, "\:98ef\:7530\:6a4b", "Iidabashi", {35.7014035648064`, 139.74652120252`}, -19.1`}, {14, "\:5e02\:30b1\:8c37", "Ichigaya", {35.6925762746704`, 139.736890527153`}, -8.9`}, {15, "\:9eb4\:753a", "Kojimachi", {35.684785`, 139.73735`}, -15.9`}, {16, "\:6c38\:7530\:753a", "Nagatacho", {35.6778958247308`, 139.741772993339`}, -23.7`}, {17, "\:685c\:7530\:9580", "Sakuradamon", {35.6774584921549`, 139.751886486826`}, -17.1`}, {18, "\:6709\:697d\:753a", "Yurakucho", {35.675973756726`, 139.762285960634`}, -19.4`}, {19, "\:9280\:5ea7\:4e00\:4e01\:76ee", "Ginza-itchome", {35.6745195757797`, 139.76678626058`}, -23`}, {20, "\:65b0\:5bcc\:753a", "Shintomicho", {35.6705284247117`, 139.773594368618`}, -21`}, {21, "\:6708\:5cf6", "Tsukishima", {35.6647105856136`, 139.784405550668`}, -22.5`}, {22, "\:8c4a\:6d32", "Toyosu", {35.6551537828668`, 139.795994442972`}, -19`}, {23, "\:8fb0\:5df3", "Tatsumi", {35.645775`, 139.81033`}, -21.9`}, {24, "\:65b0\:6728\:5834", "Shin-kiba", {35.64578`, 139.826605`}, 7.8`}}, {{1, "\:6e0b\:8c37", "Shibuya", {35.6590979695481`, 139.702673404052`}, -14.9`}, {2, "\:8868\:53c2\:9053", "Omote-sando", {35.665042546167`, 139.712472695145`}, -8.5`}, {3, "\:9752\:5c71\:4e00\:4e01\:76ee", "Aoyama-itchome", {35.6727891830525`, 139.724145270768`}, -14.6`}, {4, "\:6c38\:7530\:753a", "Nagatacho", {35.6778958247308`, 139.741772993339`}, -36`}, {5, "\:534a\:8535\:9580", "Hanzomon", {35.68538`, 139.741695`}, -18.3`}, {6, "\:4e5d\:6bb5\:4e0b", "Kudanshita", {35.6960918116116`, 139.751265393273`}, -21.9`}, {7, "\:795e\:4fdd\:753a", "Jimbocho", {35.6960214599323`, 139.757559947799`}, -22.1`}, {8, "\:5927\:624b\:753a", "Otemachi", {35.6868754460118`, 139.766203207735`}, -27.1`}, {9, "\:4e09\:8d8a\:524d", "Mitsukoshimae", {35.6871737671005`, 139.773582291216`}, -27.8`}, {10, "\:6c34\:5929\:5bae\:524d", "Suitengumae", {35.6830006854283`, 139.785171447926`}, -22`}, {11, "\:6e05\:6f84\:767d\:6cb3", "Kiyosumi-shirakawa", {35.6821194593983`, 139.799840016026`}, -21.5`}, {12, "\:4f4f\:5409", "Sumiyoshi", {35.6887047396681`, 139.815667793097`}, -32.6`}, {13, "\:9326\:7cf8\:753a", "Kinshicho", {35.6974400894785`, 139.814956190081`}, -21.8`}, {14, "\:62bc\:4e0a\:3008\:30b9\:30ab\:30a4\:30c4\:30ea\:30fc\:524d\:3009", "Oshiage", {35.708467369776`, 139.81373493359`}, -21.6`}}, {{1, "\:76ee\:9ed2", "Meguro", {35.632485`, 139.71566`}, -19.8`}, {2, "\:767d\:91d1\:53f0", "Shirokanedai", {35.63777`, 139.72586`}, -28.3`}, {3, "\:767d\:91d1\:9ad8\:8f2a", "Shirokane-takanawa", {35.643145`, 139.734285`}, -29.8`}, {4, "\:9ebb\:5e03\:5341\:756a", "Azabu-juban", {35.65481`, 139.737045`}, -24.3`}, {5, "\:516d\:672c\:6728\:4e00\:4e01\:76ee", "Roppongi-itchome", {35.665075`, 139.7389`}, -22.3`}, {6, "\:6e9c\:6c60\:5c71\:738b", "Tameike-sanno", {35.6715112700871`, 139.741942591836`}, -16.2`}, {7, "\:6c38\:7530\:753a", "Nagatacho", {35.6778958247308`, 139.741772993339`}, -26.7`}, {8, "\:56db\:30c4\:8c37", "Yotsuya", {35.6841963947417`, 139.730047469488`}, -21.2`}, {9, "\:5e02\:30b1\:8c37", "Ichigaya", {35.6925762746704`, 139.736890527153`}, -20.5`}, {10, "\:98ef\:7530\:6a4b", "Iidabashi", {35.7014035648064`, 139.74652120252`}, -20.3`}, {11, "\:5f8c\:697d\:5712", "Korakuen", {35.7073066769895`, 139.7508602691`}, -37.5`}, {12, "\:6771\:5927\:524d", "Todaimae", {35.7180144569886`, 139.757880841327`}, -21.9`}, {13, "\:672c\:99d2\:8fbc", "Hon-komagome", {35.7243643481249`, 139.753811585144`}, -19.4`}, {14, "\:99d2\:8fbc", "Komagome", {35.7359129556168`, 139.746909222771`}, -16.9`}, {15, "\:897f\:30b1\:539f", "Nishigahara", {35.745945`, 139.74226`}, -14.1`}, {16, "\:738b\:5b5 0", "Oji", {35.754470148697`, 139.737361772041`}, -17.5`}, {17, "\:738b\:5b5 0\:795e\:8c37", "Oji-kamiya", {35.765291996165`, 139.735640949866`}, -20.2`}, {18, "\:5fd7\:8302", "Shimo", {35.778025`, 139.7325`}, -16.4`}, {19, "\:8d64\:7fbd\:5ca9\:6df5", "Akabane-iwabuchi", {35.783355`, 139.72211`}, -18`}}, {{1, "\:548c\:5149\:5e02", "Wakoshi", {35.78835`, 139.612865`}, 1.7`}, {2, "\:5730\:4e0b\:9244\:6210\:5897", "Chikatetsu-narimasu", {35.77674`, 139.63117`}, -16.1`}, {3, "\:5730\:4e0b\:9244\:8d64\:585a", "Chikatetsu-akatsuka", {35.7699805639494`, 139.644000328985`}, -15.2`}, {4, "\:5e73\:548c\:53f0", "Heiwadai", {35.757555`, 139.6543`}, -17.7`}, {5, "\:6c37\:5ddd\:53f0", "Hikawadai", {35.74962`, 139.66547`}, -17.7`}, {6, "\:5c0f\:7af9\:5411\:539f", "Kotake-mukaihara", {35.743395`, 139.67952`}, -17.3`}, {7, "\:5343\:5ddd", "Senkawa", {35.738175`, 139.6894`}, -19`}, {8, "\:8981\:753a", "Kanamecho", {35.733215`, 139.69848`}, -22`}, {9, "\:6c60\:888b", "Ikebukuro", {35.730345`, 139.71115`}, -25`}, {10, "\:96d1\:53f8\:304c\:8c37", "Zoshigaya", {35.7202`, 139.714715`}, -33.8`}, {11, "\:897f\:65e9\:7a32\:7530", "Nishi-waseda", {35.707806110104`, 139.709119374838`}, -33.8`}, {12, "\:6771\:65b0\:5bbf", "Higashi-shinjuku", {35.6998289700799`, 139.707845464868`}, -35`}, {13, "\:65b0\:5bbf\:4e09\:4e01\:76ee", "Shinjuku-sanchome", {35.69118`, 139.70421`}, -15.3`}, {14, "\:5317\:53c2\:9053", "Kita-sando", {35.6785026700415`, 139.705468241239`}, -16.4`}, {15, "\:660e\:6cbb\:795e\:5bae\:524d\:3008\:539f\:5bbf\:3009", "Meiji-jingumae", {35.6691233335104`, 139.703943466256`}, -27.7`}, {16, "\:6e0b\:8c37", "Shibuya", {35.6590979695481`, 139.702673404052`}, -28.6`}}}, SelectWithContents -> True, Selectable -> False];\[IndentingNewLine]stationNames=Flatten[line9inf3D,1][[All,3]]//Union;\[IndentingNewLine]stationNames//Length
将车站的位置更改为位置{x, y, z}。z 被校正以使可视化看起来更好。
h=800;(* station->{x,y,z}@line *)line9StationCoordinates3DN=line9inf3D/.{n_,jp_,en_,{lat_,lon_},d_}->en->{lon,lat,d};\[IndentingNewLine](* {x,y,z}@line *)\[IndentingNewLine]line9StationCoordinates3D=Values@line9StationCoordinates3DN;\[IndentingNewLine](* station->{x,y}@line *)line9StationCoordinates2DN=line9StationCoordinates3DN/.{x_,y_,z_}->{x,y};\[IndentingNewLine](* {x,y}@line *)\[IndentingNewLine]line9StationCoordinates2D=Values@line9StationCoordinates2DN;\[IndentingNewLine](* station->{x,y} *)\[IndentingNewLine]stationCoordinates =Flatten[line9StationCoordinates2DN,1]//Union;\[IndentingNewLine]\[IndentingNewLine](* station->{x,y,z/h}@line *)line9StationCoordinates3DhN=line9inf3D/.{n_,jp_,en_,{lat_,lon_},d_}->en->{lon,lat,d/h};\[IndentingNewLine](* {x,y,z/h}@line *)\[IndentingNewLine]line9StationCoordinates3Dh=Values@line9StationCoordinates3DhN;
将车站的位置转换为海拔高度,而不是距离地面的深度。
esl[lineno_]:=Module[{altitude,depth},\
[IndentingNewLine]altitude=GeoElevationData[Reverse@#]&/@line9StationCoordinates3D[[lineno,All,;;2]];\
[IndentingNewLine]depth=Quantity[#,"Meters"]&/@(line9StationCoordinates3D[[lineno,All,3]]);\[IndentingNewLine]MapThread[Join[#1,
{#2}]&,\[IndentingNewLine]{line9StationCoordinates3D[[lineno]][[All,;;2]],\[IndentingNewLine]QuantityMagnitude[altitude+depth]}]\
[IndentingNewLine]]\[IndentingNewLine]eslh[lineno_]:=Module[{tmp,altitude,depth},\[IndentingNewLine]tmp=esl[lineno];\
[IndentingNewLine]tmp/.{x_,y_,z_}->{x,y,z/h}\[IndentingNewLine]]\[IndentingNewLine]\[IndentingNewLine](* the elevation above sea
level *)\[IndentingNewLine](* {x,y,z/h}@line *)\[IndentingNewLine]line9StationCoordinates3DESLh=eslh/@Range[Length@line9Names];\
[IndentingNewLine](* station->{x,y,z/h}@line *)\[IndentingNewLine]line9StationCoordinates3DESLhN=Thread[line9inf3D[[#,All,3]]-
>line9StationCoordinates3DESLh[[#]]]&/@Range[Length@line9Names];\[IndentingNewLine](* Join Yurakucho Line and Fukutoshin Line for
interconnection *)\
[IndentingNewLine]line9StationCoordinates3DESLhN[[6]]=Join[line9StationCoordinates3DESLhN[[6]],line9StationCoordinates3DESLhN[[9]]];\
[IndentingNewLine]line9StationCoordinates3DESLhN[[9]]=line9StationCoordinates3DESLhN[[6]];
可视化地铁线
生成二维图:
{{x1,x2},{y1,y2},{z1,z2}}=MinMax/@Transpose@Flatten[line9StationCoordinates3Dh,1];\[IndentingNewLine]plotrange2D={{x1-0.003,x2+0.003},{y1-0.005,y2+0.003}};\[IndentingNewLine]disk=Graphics[{EdgeForm[Directive[Thickness[.2],Blue]],FaceForm[White],Disk[{0,0},1]}];\[IndentingNewLine]\[IndentingNewLine]g2D=ListLinePlot[line9StationCoordinates3Dh[[All,All,1;;2]],\[IndentingNewLine]PlotMarkers->{disk,0.025},(* station *)\[IndentingNewLine]PlotStyle->({Thickness[.005],line9cols[[#]]}&/@Range[9]),(* line *)\[IndentingNewLine]Axes->None,PlotRangePadding->0,PlotRange->plotrange2D,\[IndentingNewLine]Epilog->{InterpretationBox[DynamicModuleBox[{Set[Typeset`open, False]}, TemplateBox[{"Expression", "SequenceIcon", GridBox[{{ItemBox[RowBox[{TagBox["\"Head: \"", "IconizedLabel"], "\:f360", TagBox["Sequence", "IconizedItem"]}]]}, {ItemBox[RowBox[{TagBox["\"Length: \"", "IconizedLabel"], "\:f360", TagBox["16", "IconizedItem"]}]]}, {ItemBox[RowBox[{TagBox["\"Byte count: \"", "IconizedLabel"], "\:f360", TagBox["6688", "IconizedItem"]}]]}}, GridBoxAlignment -> {"Columns" -> {{Left}}}, DefaultBaseStyle -> "Column", GridBoxItemSize -> {"Columns" -> {{Automatic}}, "Rows" -> {{Automatic}}}], Dynamic[Typeset`open]}, "IconizedObject"]], Sequence[Inset[Style["Tokyo", 8, Bold], Plus[ReplaceAll["Tokyo", $CellContext`stationCoordinates], {-0.011`, 0.003`}]], Inset[Style["Shibuya", 8, Bold], Plus[ReplaceAll["Shibuya", $CellContext`stationCoordinates], {-0.018`, 0}]], Inset[Style["Asakusa", 8, Bold], Plus[ReplaceAll["Asakusa", $CellContext`stationCoordinates], {0.015`, 0.005`}]], Inset[Style["Ogikubo", 8, Bold], Plus[ReplaceAll["Ogikubo", $CellContext`stationCoordinates], {0.005`, 0.008`}]], Inset[Style["Ikebukuro", 8, Bold], Plus[ReplaceAll["Ikebukuro", $CellContext`stationCoordinates], {0.01`, 0.008`}]], Inset[Style["Nakameguro", 8, Bold], Plus[ReplaceAll["Naka-meguro", $CellContext`stationCoordinates], {-0.025`, 0}]], Inset[Style["Kitasenju", 8, Bold], Plus[ReplaceAll["Kita-senju", $CellContext`stationCoordinates], {-0.02`, 0.005`}]], Inset[Style["Nakano", 8, Bold], Plus[ReplaceAll["Nakano", $CellContext`stationCoordinates], {-0.005`, 0.007`}]], Inset[Style["Nishifunabashi", 8, Bold], Plus[ReplaceAll["Nishi-funabashi", $CellContext`stationCoordinates], {-0.025`, 0.008`}]], Inset[Style["Yoyogiuehara", 8, Bold], Plus[ReplaceAll["Yoyogi-uehara", $CellContext`stationCoordinates], {-0.028`, 0}]], Inset[Style["Ayase", 8, Bold], Plus[ReplaceAll["Ayase", $CellContext`stationCoordinates], {0.015`, 0}]], Inset[Style["Wakoshi", 8, Bold], Plus[ReplaceAll["Wakoshi", $CellContext`stationCoordinates], {0.02`, 0.001`}]], Inset[Style["Shinkiba", 8, Bold], Plus[ReplaceAll["Shin-kiba", $CellContext`stationCoordinates], {0.02`, 0}]], Inset[Style["Oshiage", 8, Bold], Plus[ReplaceAll["Oshiage", $CellContext`stationCoordinates], {0.018`, 0`}]], Inset[Style["Meguro", 8, Bold], Plus[ReplaceAll["Meguro", $CellContext`stationCoordinates], {-0.018`, 0.001`}]], Inset[Style["Akabaneiwabuchi", 8, Bold], Plus[ReplaceAll["Akabane-iwabuchi", $CellContext`stationCoordinates], {-0.035`, 0`}]]], SelectWithContents -> True, Selectable -> False]},\[IndentingNewLine]ImageSize->400];\[IndentingNewLine](* map *)\[IndentingNewLine]bg2D=GeoGraphics[GeoRange->Reverse@plotrange2D,\[IndentingNewLine]PlotRangePadding->None,GeoBackground->"StreetMapNoLabels",ImageSize->400];\[IndentingNewLine]Overlay[{ImageResize[bg2D,{800,490}],g2D}];\[IndentingNewLine]Rasterize@%
生成三维图:
(* the elevation above sea level *)\[IndentingNewLine]data=GeoElevationData[GeoRange->Reverse@plotrange2D,GeoResolution->Quantity[1000,"Feet"],UnitSystem->"Metric"];\[IndentingNewLine]dataQM=QuantityMagnitude[Reverse@data];\[IndentingNewLine]{e1h,e2h}=(dataQM//MinMax)/h;\[IndentingNewLine]{tmp1,tmp2}=(MinMax/@Transpose@Flatten[line9StationCoordinates3DESLh,1])[[3]];\[IndentingNewLine]plotrange3DESLh={{x1,x2},{y1,y2},{Min[e1h,tmp1],Max[e2h,tmp2]}};\[IndentingNewLine]\[IndentingNewLine]{gx,gy}=dataQM//Dimensions;\[IndentingNewLine]rescale[x_,y_]:={Rescale[y,{1,gy},{x1,x2}],Rescale[x,{1,gx},{y1,y2}]}\[IndentingNewLine]dataQMrescale=Table[Join[rescale[i,j],{dataQM[[i,j]]}],{i,1,gx},{j,1,gy}];\[IndentingNewLine]\[IndentingNewLine]g=Graphics3D[{line9cols[[#]],Opacity[1],Tube[line9StationCoordinates3DESLh[[#]],.002]}&/@Range[Length@line9Names],\[IndentingNewLine]PlotRange->plotrange3DESLh, \[IndentingNewLine]Boxed->False,Axes->False,Ticks->False,ViewPoint->{-2.17,-2.78,-1.22},ViewVertical->{-0.1,-0.29,0.95},\[IndentingNewLine]ImageSize->400];\[IndentingNewLine]bg3D=ListPlot3D[Flatten[dataQMrescale,1]/.{x_,y_,z_}->{x,y,z/h},AspectRatio->(Divide@@Dimensions[data]),\[IndentingNewLine]Boxed->False,Mesh->None,Axes->False,Background->None,\[IndentingNewLine]PlotRange->plotrange3DESLh,\[IndentingNewLine]ColorFunction->(ColorData["HypsometricTints"][#3*h]&),ColorFunctionScaling->False,\[IndentingNewLine]ImageSize->400];\[IndentingNewLine]\[IndentingNewLine]Show[g,bg3D,ViewPoint->{0.75,-3.62,0.32},ViewVertical->{-0.04,0.37,0.92}]\[IndentingNewLine]Show[g,bg3D,ViewPoint->{-2.17,-2.78,-1.22},ViewVertical->{-0.1,-0.29,0.95}]\[IndentingNewLine]
时间表
每条线路首站时刻表网址如下:
baseURL="https://www.tokyometro.jp/lang_en/station/";\[IndentingNewLine](* Ginza Line *)\
[IndentingNewLine]Asakusa2ShibuyaURL=baseURL<>"asakusa/timetable/ginza/a/index.html";\
[IndentingNewLine]Shibuya2AsakusaURL=baseURL<>"shibuya/timetable/ginza/b/index.html";\
[IndentingNewLine](* Marunouchi Line *)\
[IndentingNewLine]Ikebukuro2OgikuboURL=baseURL<>"ikebukuro/timetable/marunouchi/a/index.html";\
[IndentingNewLine]Ogikubo2IkebukuroURL=baseURL<>"ogikubo/timetable/marunouchi/b/index.html";\
[IndentingNewLine](* Hibiya Line *)\[IndentingNewLine]KitaSenju2NakaMeguroURL=baseURL<>"kita-
senju/timetable/hibiya/a/index.html";\[IndentingNewLine]NakaMeguro2KitaSenjuURL=baseURL<>"naka-
meguro/timetable/hibiya/b/index.html";\[IndentingNewLine](* Tozai Line *)\
[IndentingNewLine]Nakano2NishiFunabashiURL=baseURL<>"nakano/timetable/tozai/a/index.html";\
[IndentingNewLine]NishiFunabashi2NakanoURL=baseURL<>"nishi-
funabashi/timetable/tozai/b/index.html";\[IndentingNewLine](* Chiyoda Line *)\
[IndentingNewLine]Ayase2YoyogiUeharaURL=baseURL<>"ayase/timetable/chiyoda/a/index.html";\
[IndentingNewLine]YoyogiUehara2AyaseURL=baseURL<>"yoyogi-
uehara/timetable/chiyoda/b/index.html";\[IndentingNewLine](* Yurakucho Line *)\
[IndentingNewLine]Wakoshi2ShinKibaURL=baseURL<>"wakoshi/timetable/yurakucho/a/index.html";\
[IndentingNewLine]ShinKiba2WakoshiURL=baseURL<>"shin-kiba/timetable/yurakucho/b/index.html";\
[IndentingNewLine](* Hanzomon Line *)\
[IndentingNewLine]Shibuya2OshiageURL=baseURL<>"shibuya/timetable/hanzomon/a/index.html";\
[IndentingNewLine]Oshiage2ShibuyaURL=baseURL<>"oshiage/timetable/hanzomon/b/index.html";\
[IndentingNewLine](* Namboku Line *)\
[IndentingNewLine]Meguro2AkabaneIwabuchiURL=baseURL<>"meguro/timetable/namboku/a/index.html";\
[IndentingNewLine]AkabaneIwabuchi2MeguroURL=baseURL<>"akabane-
iwabuchi/timetable/namboku/b/index.html";\[IndentingNewLine](* Fukutoshin Line *)\
[IndentingNewLine]Wakoshi2ShibuyaURL=baseURL<>"wakoshi/timetable/yurakucho/a/index.html";\
[IndentingNewLine]Shibuya2WakoshiURL=baseURL<>"shibuya/timetable/fukutoshin/b/index.html";\
[IndentingNewLine]\[IndentingNewLine]ttURLs=\[IndentingNewLine]
{{Asakusa2ShibuyaURL,Shibuya2AsakusaURL},\[IndentingNewLine]
{Ikebukuro2OgikuboURL,Ogikubo2IkebukuroURL},\[IndentingNewLine]
{KitaSenju2NakaMeguroURL,NakaMeguro2KitaSenjuURL},\[IndentingNewLine]
{Nakano2NishiFunabashiURL,NishiFunabashi2NakanoURL},\[IndentingNewLine]
{Ayase2YoyogiUeharaURL,YoyogiUehara2AyaseURL},\[IndentingNewLine]
{Wakoshi2ShinKibaURL,ShinKiba2WakoshiURL},\[IndentingNewLine]
{Shibuya2OshiageURL,Oshiage2ShibuyaURL},\[IndentingNewLine]
{Meguro2AkabaneIwabuchiURL,AkabaneIwabuchi2MeguroURL},\[IndentingNewLine]
{Wakoshi2ShibuyaURL,Shibuya2WakoshiURL}};
从第一班地铁到早上 8 点,获取每班地铁的信息。通过使用 WebExcute[] 的 Web 驱动程序在 Web 浏览器中执行命令来获取信息。
gettimetable[url_]:=Module[{session,text,word,result,cnt},\[IndentingNewLine]cnt=0;word={"InvalidElement"};\
[IndentingNewLine]session=StartWebSession[Visible->False];\[IndentingNewLine]While[word=={"InvalidElement"}&&cnt<3,\
[IndentingNewLine]cnt++;\[IndentingNewLine]WebExecute[session,"OpenWebPage"->url];\[IndentingNewLine]Pause[1];\
[IndentingNewLine]text=WebExecute["ElementText"->"XPath"->"//*
[@id=\"v2_contents\"]/div/div/div[3]/div/table/tbody"];\[IndentingNewLine]word=StringSplit[text[[1]]];\
[IndentingNewLine]];\[IndentingNewLine]If[cnt==3,result=$Failed;Echo["retry over: "<>url],\
[IndentingNewLine]result=SequenceSplit[word,{"Timetable"}];\[IndentingNewLine]];\
[IndentingNewLine]DeleteObject[session];\[IndentingNewLine]result\[IndentingNewLine]]\[IndentingNewLine]\
[IndentingNewLine]getttlist[url_]:=Module[{hls,tables,tables567,ttlist},\
[IndentingNewLine]hls=Import[url,"Hyperlinks"];\
[IndentingNewLine]tables=Select[hls,StringContainsQ[#,"https://www.tokyometro.jp/lang_en/station/timetable.html"]&];\
[IndentingNewLine]tables567=Select[tables,StringContainsQ[#,"h=5"|"h=6"|"h=7"]&];\
[IndentingNewLine]ttlist=gettimetable/@tables567;\[IndentingNewLine]ttlist\[IndentingNewLine]]
获取银座线运营信息,需要一些时间。
(*\[IndentingNewLine]ttlistAsakusa2Shibuya=getttlist[ttURLs[[1,1]]];\
[IndentingNewLine]ttlistShibuya2Asakusa=getttlist[ttURLs[[1,2]]];\
[IndentingNewLine]*)
九条线的运营信息如下:
地铁
获取每30秒地铁的 3D 位置:
range=Drop[Range[0,23],{2,5}];\[IndentingNewLine]timestring[h_String]:=(h<>":"
<>#)&/@(StringPadLeft[#,2,"0"]&/@(ToString/@Range[0,59]))\
[IndentingNewLine]timeobject[h_Integer]:=TagBox[StyleBox[RowBox[{"TimeObject",
"[", RowBox[{RowBox[{"{", RowBox[{"h", ",", "#", ",", "0"}], "}"}], ",",
"\"Instant\"", ",", "9.`"}], "]"}], ShowSpecialCharacters -> False,
ShowStringCharacters -> True, NumberMarks -> True], FullForm]&/@Range[0,59]
timestr=timestring/@(StringPadLeft[#,2,"0"]&/@(ToString/@range));
timeobj=timeobject/@range;
MapThread[(gettime[#1]=#2)&,{Flatten@timestr,Flatten@timeobj}];\
[IndentingNewLine]\[IndentingNewLine]gettimeloc[item_]:=Module[{stationname},\
[IndentingNewLine](* for example "Meiji-jingumae
*)\[IndentingNewLine]stationname=StringReplace[item[[1]],RegularExpression["
<.+>"]->""];\[IndentingNewLine]Which[\
[IndentingNewLine]!MemberQ[stationNames,stationname],Nothing,(* not applicable
*)\[IndentingNewLine]Length@item==4,{{gettime@item[[4]],stationname}},\
[IndentingNewLine]Length@item==7,{{gettime@item[[4]],stationname},
{gettime@item[[7]],stationname}},\[IndentingNewLine]True,Echo["gettimeloc error"
<>item];$Failed\[IndentingNewLine]]\[IndentingNewLine]]
\[IndentingNewLine]splititem[item_]:=Module[{len},\
[IndentingNewLine]len=Length[item];\[IndentingNewLine]Which[\
[IndentingNewLine]Length@item==4,{item},(*Depart*)\
[IndentingNewLine]Length@item==7,{item},(*Arrive&Depart*)\
[IndentingNewLine]Mod[Length@item-
4,7]==0,Join[{item[[;;4]]},Partition[item[[5;;]],UpTo[7]]],\
[IndentingNewLine]True,Echo["splititem error"<>item];$Failed\
[IndentingNewLine]]\[IndentingNewLine]]\[IndentingNewLine]
(* list of train positions every 30 seconds *)\
[IndentingNewLine]process[list_]:=Module[{cnt,result,i,times},\
[IndentingNewLine]result={};\
[IndentingNewLine]For[cnt=1,cnt<length[list],cnt++,\< p="">
[IndentingNewLine]AppendTo[result,list[[cnt]]];\
[IndentingNewLine]If[list[[cnt,1]]===list[[cnt+1,1]],\[IndentingNewLine]None,\
[IndentingNewLine]times=(list[[cnt+1,1]]-list[[cnt,1]])/TemplateBox[{"0.5`",
"\"min\"", "minutes", "\"Minutes\""}, "Quantity"];\
[IndentingNewLine]For[i=1,i<times,i++,\[indentingnewline]appendto[result,< p="">
{list[[cnt,1]]+TemplateBox[{"0.5`", "\"min\"", "minutes", "\"Minutes\""},
"Quantity"]*i,(* 時刻 *)\[IndentingNewLine]If[list[[cnt,2]]===list[[cnt+1,2]],\
[IndentingNewLine]list[[cnt,2]],\[IndentingNewLine]list[[cnt,2]]+i*
(list[[cnt+1,2]]-list[[cnt,2]])/times]}]]]\[IndentingNewLine]];\
[IndentingNewLine]AppendTo[result,list[[-1]]];\
[IndentingNewLine]result//DeleteDuplicates \[IndentingNewLine]]
\[IndentingNewLine](* divide the area between adjacent stations into smaller sections. I use Silvia's useful function
https://community.wolfram.com/groups/-/m/t/2126761 *)\[IndentingNewLine]FindDivisionsExact[range:{_,_},n_Integer?(#>=2&)]:=Rescale[Range[n]//N//Rescale,
{0,1},range]\[IndentingNewLine]FindDivisionsExact[n_Integer?(#>=2&)]:=FindDivisionsExact[{0,1},n]\[IndentingNewLine]\[IndentingNewLine](* station->{x,y,z/h}@line
*)\
[IndentingNewLine]line9StationCoordinates3DESLhDetailed=DeleteDuplicates[Flatten[FindDivisionsExact[#,23]&/@Partition[#,2,1],1]]&/@line9StationCoordinates3DESLh;\
[IndentingNewLine]\[IndentingNewLine](* for 3D *)\[IndentingNewLine]gettimetableDetail23DESLh[ttlist_,lineno_]:=Module[{gtl,f,p,sc},\[IndentingNewLine]gtl=
(gettimeloc/@splititem[#])[[1]]&/@ttlist;\[IndentingNewLine]f=Flatten[gtl,1]/.{}[[1]]->Nothing;\[IndentingNewLine]p=process[f];\[IndentingNewLine]sc=p/.
(line9StationCoordinates3DESLhN[[lineno]]);\[IndentingNewLine]{#[[1]],Nearest[line9StationCoordinates3DESLhDetailed[[lineno]],#[[2]],1][[1]]}&/@sc\
[IndentingNewLine]]\[IndentingNewLine]\[IndentingNewLine]getcur3D[lineno_,ab_]:=Module[{strno,endno,trainCoordinates,ff,gb,cur},\[IndentingNewLine]strno=0;\
[IndentingNewLine]endno=360;\[IndentingNewLine]trainCoordinates=gettimetableDetail23DESLh[#,lineno]&/@ttlists[[lineno,ab]];\
[IndentingNewLine]ff=Flatten[trainCoordinates,1];\[IndentingNewLine]ff=Select[ff,(#[[1]]<=TemplateBox[{RowBox[{RowBox[{"\"05:00:00\"",
StyleBox[RowBox[{"\"GMT+\"", "\:f360", StyleBox["9", NumberMarks -> False, StripOnInput -> False]}], FontColor -> GrayLevel[0.5`]]}]}], RowBox[{"TimeObject", "
[", RowBox[{RowBox[{"{", RowBox[{"5", ",", "0", ",", "0"}], "}"}], ",", "\"Instant\"", ",", "9.`"}], "]"}]}, "TimeObject", Editable ->
False]+TemplateBox[{"0.5`", "\"min\"", "minutes", "\"Minutes\""}, "Quantity"]*endno)&];\[IndentingNewLine]gb=GroupBy[ff,First];\
[IndentingNewLine]cur=gb[TemplateBox[{RowBox[{RowBox[{"\"05:00:00\"", StyleBox[RowBox[{"\"GMT+\"", "\:f360", StyleBox["9", NumberMarks -> False, StripOnInput -
> False]}], FontColor -> GrayLevel[0.5`]]}]}], RowBox[{"TimeObject", "[", RowBox[{RowBox[{"{", RowBox[{"5", ",", "0", ",", "0"}], "}"}], ",", "\"Instant\"", ",",
"9.`"}], "]"}]}, "TimeObject", Editable -> False]+TemplateBox[{"0.5`", "\"min\"", "minutes", "\"Minutes\""}, "Quantity"]*#]&/@Range[strno,endno];\
[IndentingNewLine]cur=cur/.Missing[__]->{};\[IndentingNewLine]cur\[IndentingNewLine]]
curs3D=Quiet[{getcur3D[#,1],getcur3D[#,2]}&/@Range[Length@line9Names]];
每 30 秒获取一次地铁的 2D 位置。在 2D 中,我区分了线路两个方向的地铁。
curs2D=Quiet[{getcur2D[#,1],getcur2D[#,2]}&/@Range[Length@line9Names]];
可视化地铁
可视化从首班地铁到早上 8 点高峰时间的操作的 3D 图形图像。
可视化二维图形图像:
创建图像、2D、3D 和时钟的拼贴画:
(* collage 2D, 3D and clock *)\[IndentingNewLine]frames=ParallelMap[ImageCollage[{\
[IndentingNewLine]ImageResize[Rasterize[Overlay[{frames2D[[#]],clocks[[#]]},Alignment-
>{Right,Top}],ImageResolution->300],600],\
[IndentingNewLine]ImageResize[Rasterize[frames3D[[#]],ImageResolution->300],600]}]&,\
[IndentingNewLine]Range[Length@frames2D]\[IndentingNewLine]];
将帧列表显示为动态动画:
AnimatedImage[frames,FrameRate->15,AnimationRunning->False]
将帧列表导出为动画 GIF 图像:
Export["TokyoMetro.gif",frames,"DisplayDurations"->1/15,AnimationRepetitions->1];