diff --git a/.github/workflows/deploy_ecs_production_stationapi.yml b/.github/workflows/deploy_ecs_production_stationapi.yml deleted file mode 100644 index 332d4941..00000000 --- a/.github/workflows/deploy_ecs_production_stationapi.yml +++ /dev/null @@ -1,76 +0,0 @@ -name: Deploy StationAPI to Production Environment on Amazon ECS - -on: - workflow_dispatch: - push: - branches: - - master - paths: - - ".sqlx/**" - - "data/**" - - "docker/**" - - "scripts/**" - - "stationapi/**" - - "Cargo.lock" - - "Cargo.toml" - -env: - AWS_REGION: ${{ secrets.AWS_REGION }} - ECR_REPOSITORY: ${{ secrets.ECR_REPOSITORY }} - ECS_SERVICE: ${{ secrets.ECS_SERVICE }} - ECS_CLUSTER: ${{ secrets.ECS_CLUSTER }} - ECS_TASK_DEFINITION: ${{ secrets.ECS_TASK_DEFINITION }} - CONTAINER_NAME: ${{ secrets.ECS_CONTAINER_NAME }} - -jobs: - deploy: - name: Deploy StationAPI Production - runs-on: self-hosted - environment: production - - steps: - - name: Checkout - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - with: - submodules: recursive - - - name: Configure AWS credentials - uses: aws-actions/configure-aws-credentials@7474bc4690e29a8392af63c5b98e7449536d5c3a # v4 - with: - aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} - aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - aws-region: ${{ env.AWS_REGION }} - - - name: Login to Amazon ECR - id: login-ecr - uses: aws-actions/amazon-ecr-login@fa648b43de3d4d023bcb3f89ed6940096949c419 # v2 - - - name: Build, tag, and push image to Amazon ECR - id: build-image - env: - ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} - IMAGE_TAG: ${{ github.sha }} - run: | - docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG -f ./docker/api/Dockerfile . - docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG - echo "image=$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG" >> $GITHUB_OUTPUT - - - name: Download task definition - run: | - aws ecs describe-task-definition --task-definition ${{ env.ECS_TASK_DEFINITION }} --query taskDefinition > task-definition.json - - - name: Fill in the new image ID in the Amazon ECS task definition - id: task-def - uses: aws-actions/amazon-ecs-render-task-definition@6853cfae8c3a7d978fbf68b5a55453395541dfbb # v1 - with: - task-definition: task-definition.json - container-name: ${{ env.CONTAINER_NAME }} - image: ${{ steps.build-image.outputs.image }} - - - name: Deploy Amazon ECS task definition - uses: aws-actions/amazon-ecs-deploy-task-definition@a310a830f5c14e583e35d84e4e1ec7dd177c3c9c # v2 - with: - task-definition: ${{ steps.task-def.outputs.task-definition }} - service: ${{ env.ECS_SERVICE }} - cluster: ${{ env.ECS_CLUSTER }} - wait-for-service-stability: true diff --git a/.github/workflows/deploy_ecs_staging_stationapi.yml b/.github/workflows/deploy_ecs_staging_stationapi.yml deleted file mode 100644 index a1e76f29..00000000 --- a/.github/workflows/deploy_ecs_staging_stationapi.yml +++ /dev/null @@ -1,76 +0,0 @@ -name: Deploy StationAPI to Staging Environment on Amazon ECS - -on: - workflow_dispatch: - push: - branches: - - dev - paths: - - ".sqlx/**" - - "data/**" - - "docker/**" - - "scripts/**" - - "stationapi/**" - - "Cargo.lock" - - "Cargo.toml" - -env: - AWS_REGION: ${{ secrets.AWS_REGION }} - ECR_REPOSITORY: ${{ secrets.ECR_REPOSITORY }} - ECS_SERVICE: ${{ secrets.ECS_SERVICE }} - ECS_CLUSTER: ${{ secrets.ECS_CLUSTER }} - ECS_TASK_DEFINITION: ${{ secrets.ECS_TASK_DEFINITION }} - CONTAINER_NAME: ${{ secrets.ECS_CONTAINER_NAME }} - -jobs: - deploy: - name: Deploy StationAPI Staging - runs-on: self-hosted - environment: staging - - steps: - - name: Checkout - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - with: - submodules: recursive - - - name: Configure AWS credentials - uses: aws-actions/configure-aws-credentials@7474bc4690e29a8392af63c5b98e7449536d5c3a # v4 - with: - aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} - aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - aws-region: ${{ env.AWS_REGION }} - - - name: Login to Amazon ECR - id: login-ecr - uses: aws-actions/amazon-ecr-login@fa648b43de3d4d023bcb3f89ed6940096949c419 # v2 - - - name: Build, tag, and push image to Amazon ECR - id: build-image - env: - ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} - IMAGE_TAG: ${{ github.sha }} - run: | - docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG -f ./docker/api/Dockerfile . - docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG - echo "image=$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG" >> $GITHUB_OUTPUT - - - name: Download task definition - run: | - aws ecs describe-task-definition --task-definition ${{ env.ECS_TASK_DEFINITION }} --query taskDefinition > task-definition.json - - - name: Fill in the new image ID in the Amazon ECS task definition - id: task-def - uses: aws-actions/amazon-ecs-render-task-definition@6853cfae8c3a7d978fbf68b5a55453395541dfbb # v1 - with: - task-definition: task-definition.json - container-name: ${{ env.CONTAINER_NAME }} - image: ${{ steps.build-image.outputs.image }} - - - name: Deploy Amazon ECS task definition - uses: aws-actions/amazon-ecs-deploy-task-definition@a310a830f5c14e583e35d84e4e1ec7dd177c3c9c # v2 - with: - task-definition: ${{ steps.task-def.outputs.task-definition }} - service: ${{ env.ECS_SERVICE }} - cluster: ${{ env.ECS_CLUSTER }} - wait-for-service-stability: true diff --git a/.gitignore b/.gitignore index 63ad20a2..eb8ea9f0 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,5 @@ server.key api_descriptor.pb tmp.sql .vscode/ -data/ToeiBus-GTFS/ \ No newline at end of file +data/ToeiBus-GTFS/ +scripts/.osm_cache/ \ No newline at end of file diff --git a/.sqlx/query-9c6aff223f1912290cdda35d4cd8c9f3d26fc0efece17de6390f06ea9935241f.json b/.sqlx/query-26948acea9cc4f77097d6cc9ce3be83aa7bd8d442b32b781de7016663e362378.json similarity index 97% rename from .sqlx/query-9c6aff223f1912290cdda35d4cd8c9f3d26fc0efece17de6390f06ea9935241f.json rename to .sqlx/query-26948acea9cc4f77097d6cc9ce3be83aa7bd8d442b32b781de7016663e362378.json index b0f8b243..e1de3aa5 100644 --- a/.sqlx/query-9c6aff223f1912290cdda35d4cd8c9f3d26fc0efece17de6390f06ea9935241f.json +++ b/.sqlx/query-26948acea9cc4f77097d6cc9ce3be83aa7bd8d442b32b781de7016663e362378.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "WITH\n from_cte AS (\n SELECT\n s.station_cd,\n s.line_cd\n FROM\n stations AS s\n WHERE\n s.station_g_cd = $1\n AND s.e_status = 0\n ),\n to_cte AS (\n SELECT\n s.station_cd,\n s.line_cd\n FROM\n stations AS s\n WHERE\n s.station_g_cd = $2\n AND s.e_status = 0\n ),\n sst_cte_c1 AS (\n SELECT\n sst.line_group_cd\n FROM\n station_station_types AS sst\n JOIN from_cte ON sst.station_cd = from_cte.station_cd\n WHERE\n sst.pass <> 1\n ),\n sst_cte_c2 AS (\n SELECT\n sst.line_group_cd\n FROM\n station_station_types AS sst\n JOIN to_cte ON sst.station_cd = to_cte.station_cd\n WHERE\n sst.pass <> 1\n ),\n sst_cte AS (\n SELECT\n sst.id,\n sst.station_cd,\n sst.type_cd,\n sst.line_group_cd,\n sst.pass\n FROM\n station_station_types AS sst\n JOIN sst_cte_c1 ON sst.line_group_cd = sst_cte_c1.line_group_cd\n JOIN sst_cte_c2 ON sst.line_group_cd = sst_cte_c2.line_group_cd\n )\n SELECT\n sta.station_cd,\n sta.station_g_cd,\n sta.station_name,\n sta.station_name_k,\n sta.station_name_r,\n sta.station_name_rn,\n sta.station_name_zh,\n sta.station_name_ko,\n sta.station_number1,\n sta.station_number2,\n sta.station_number3,\n sta.station_number4,\n sta.three_letter_code,\n sta.line_cd,\n sta.pref_cd,\n sta.post,\n sta.address,\n sta.lon,\n sta.lat,\n sta.open_ymd,\n sta.close_ymd,\n sta.e_status,\n sta.e_sort,\n lin.company_cd,\n COALESCE(NULLIF(COALESCE(a.line_name, lin.line_name), ''), NULL) AS line_name,\n COALESCE(NULLIF(COALESCE(a.line_name_k, lin.line_name_k), ''), NULL) AS line_name_k,\n COALESCE(NULLIF(COALESCE(a.line_name_h, lin.line_name_h), ''), NULL) AS line_name_h,\n COALESCE(NULLIF(COALESCE(a.line_name_r, lin.line_name_r), ''), NULL) AS line_name_r,\n COALESCE(NULLIF(COALESCE(a.line_name_zh, lin.line_name_zh), ''), NULL) AS line_name_zh,\n COALESCE(NULLIF(COALESCE(a.line_name_ko, lin.line_name_ko), ''), NULL) AS line_name_ko,\n COALESCE(NULLIF(COALESCE(a.line_color_c, lin.line_color_c), ''), NULL) AS line_color_c,\n lin.line_type,\n lin.line_symbol1,\n lin.line_symbol2,\n lin.line_symbol3,\n lin.line_symbol4,\n lin.line_symbol1_color,\n lin.line_symbol2_color,\n lin.line_symbol3_color,\n lin.line_symbol4_color,\n lin.line_symbol1_shape,\n lin.line_symbol2_shape,\n lin.line_symbol3_shape,\n lin.line_symbol4_shape,\n COALESCE(lin.average_distance, 0.0)::DOUBLE PRECISION AS average_distance,\n tt.id AS type_id,\n sst.id AS sst_id,\n sst.type_cd,\n sst.line_group_cd,\n sst.pass,\n tt.type_name,\n tt.type_name_k,\n tt.type_name_r,\n tt.type_name_zh,\n tt.type_name_ko,\n tt.color,\n tt.direction,\n tt.kind,\n sta.transport_type\n FROM\n stations AS sta\n LEFT JOIN sst_cte AS sst ON sst.station_cd = sta.station_cd\n JOIN types AS tt ON tt.type_cd = sst.type_cd\n JOIN lines AS lin ON lin.line_cd = sta.line_cd AND lin.e_status = 0\n LEFT JOIN line_aliases AS la ON la.station_cd = sta.station_cd\n LEFT JOIN aliases AS a ON a.id = la.alias_cd\n WHERE\n sta.e_status = 0\n AND ($3::int IS NULL OR sta.line_cd = $3)\n ORDER BY sst.id", + "query": "WITH\n from_cte AS (\n SELECT\n s.station_cd,\n s.line_cd\n FROM\n stations AS s\n WHERE\n s.station_g_cd = $1\n AND s.e_status = 0\n ),\n to_cte AS (\n SELECT\n s.station_cd,\n s.line_cd\n FROM\n stations AS s\n WHERE\n s.station_g_cd = $2\n AND s.e_status = 0\n ),\n sst_cte_c1 AS (\n SELECT\n sst.line_group_cd\n FROM\n station_station_types AS sst\n JOIN from_cte ON sst.station_cd = from_cte.station_cd\n WHERE\n sst.pass <> 1\n ),\n sst_cte_c2 AS (\n SELECT\n sst.line_group_cd\n FROM\n station_station_types AS sst\n JOIN to_cte ON sst.station_cd = to_cte.station_cd\n WHERE\n sst.pass <> 1\n ),\n sst_cte AS (\n SELECT\n sst.id,\n sst.station_cd,\n sst.type_cd,\n sst.line_group_cd,\n sst.pass\n FROM\n station_station_types AS sst\n JOIN sst_cte_c1 ON sst.line_group_cd = sst_cte_c1.line_group_cd\n JOIN sst_cte_c2 ON sst.line_group_cd = sst_cte_c2.line_group_cd\n )\n SELECT\n sta.station_cd,\n sta.station_g_cd,\n sta.station_name,\n sta.station_name_k,\n sta.station_name_r,\n sta.station_name_rn,\n sta.station_name_zh,\n sta.station_name_ko,\n sta.station_number1,\n sta.station_number2,\n sta.station_number3,\n sta.station_number4,\n sta.three_letter_code,\n sta.line_cd,\n sta.pref_cd,\n sta.post,\n sta.address,\n sta.lon,\n sta.lat,\n sta.open_ymd,\n sta.close_ymd,\n sta.e_status,\n sta.e_sort,\n lin.company_cd,\n COALESCE(NULLIF(COALESCE(a.line_name, lin.line_name), ''), NULL) AS line_name,\n COALESCE(NULLIF(COALESCE(a.line_name_k, lin.line_name_k), ''), NULL) AS line_name_k,\n COALESCE(NULLIF(COALESCE(a.line_name_h, lin.line_name_h), ''), NULL) AS line_name_h,\n COALESCE(NULLIF(COALESCE(a.line_name_r, lin.line_name_r), ''), NULL) AS line_name_r,\n COALESCE(NULLIF(COALESCE(a.line_name_zh, lin.line_name_zh), ''), NULL) AS line_name_zh,\n COALESCE(NULLIF(COALESCE(a.line_name_ko, lin.line_name_ko), ''), NULL) AS line_name_ko,\n COALESCE(NULLIF(COALESCE(a.line_color_c, lin.line_color_c), ''), NULL) AS line_color_c,\n lin.line_type,\n lin.line_symbol1,\n lin.line_symbol2,\n lin.line_symbol3,\n lin.line_symbol4,\n lin.line_symbol1_color,\n lin.line_symbol2_color,\n lin.line_symbol3_color,\n lin.line_symbol4_color,\n lin.line_symbol1_shape,\n lin.line_symbol2_shape,\n lin.line_symbol3_shape,\n lin.line_symbol4_shape,\n COALESCE(lin.average_distance, 0.0)::DOUBLE PRECISION AS average_distance,\n tt.id AS type_id,\n sst.id AS sst_id,\n sst.type_cd,\n sst.line_group_cd,\n sst.pass,\n tt.type_name,\n tt.type_name_k,\n tt.type_name_r,\n tt.type_name_zh,\n tt.type_name_ko,\n tt.color,\n tt.direction,\n tt.kind,\n sta.transport_type\n FROM\n stations AS sta\n LEFT JOIN sst_cte AS sst ON sst.station_cd = sta.station_cd\n JOIN types AS tt ON tt.type_cd = sst.type_cd\n JOIN lines AS lin ON lin.line_cd = sta.line_cd AND lin.e_status = 0\n LEFT JOIN line_aliases AS la ON la.station_cd = sta.station_cd\n LEFT JOIN aliases AS a ON a.id = la.alias_cd\n WHERE\n sta.e_status = 0\n AND (array_length($3::int[], 1) IS NULL OR sta.line_cd = ANY($3))\n ORDER BY sst.id", "describe": { "columns": [ { @@ -303,7 +303,7 @@ "Left": [ "Int4", "Int4", - "Int4" + "Int4Array" ] }, "nullable": [ @@ -368,5 +368,5 @@ false ] }, - "hash": "9c6aff223f1912290cdda35d4cd8c9f3d26fc0efece17de6390f06ea9935241f" + "hash": "26948acea9cc4f77097d6cc9ce3be83aa7bd8d442b32b781de7016663e362378" } diff --git a/.sqlx/query-90906c9a7d97f432f66f1722a6a51731194922c4cb16f8809ae1e2e711d5a0da.json b/.sqlx/query-425870f89d0a0ae2c79e80ef7a468c5ef805d7a3f98b56e1b6ad93a1554683b7.json similarity index 83% rename from .sqlx/query-90906c9a7d97f432f66f1722a6a51731194922c4cb16f8809ae1e2e711d5a0da.json rename to .sqlx/query-425870f89d0a0ae2c79e80ef7a468c5ef805d7a3f98b56e1b6ad93a1554683b7.json index d9b3af42..217842e9 100644 --- a/.sqlx/query-90906c9a7d97f432f66f1722a6a51731194922c4cb16f8809ae1e2e711d5a0da.json +++ b/.sqlx/query-425870f89d0a0ae2c79e80ef7a468c5ef805d7a3f98b56e1b6ad93a1554683b7.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "SELECT s.station_cd,\n s.station_g_cd,\n s.station_name,\n s.station_name_k,\n s.station_name_r,\n s.station_name_rn,\n s.station_name_zh,\n s.station_name_ko,\n s.station_number1,\n s.station_number2,\n s.station_number3,\n s.station_number4,\n s.three_letter_code,\n s.line_cd,\n s.pref_cd,\n s.post,\n s.address,\n s.lon,\n s.lat,\n s.open_ymd,\n s.close_ymd,\n s.e_status,\n s.e_sort,\n l.company_cd,\n l.line_type,\n l.line_symbol1,\n l.line_symbol2,\n l.line_symbol3,\n l.line_symbol4,\n l.line_symbol1_color,\n l.line_symbol2_color,\n l.line_symbol3_color,\n l.line_symbol4_color,\n l.line_symbol1_shape,\n l.line_symbol2_shape,\n l.line_symbol3_shape,\n l.line_symbol4_shape,\n COALESCE(l.average_distance, 0.0)::DOUBLE PRECISION AS average_distance,\n COALESCE(NULLIF(COALESCE(a.line_name, l.line_name), ''), NULL) AS line_name,\n COALESCE(NULLIF(COALESCE(a.line_name_k, l.line_name_k), ''), NULL) AS line_name_k,\n COALESCE(NULLIF(COALESCE(a.line_name_h, l.line_name_h), ''), NULL) AS line_name_h,\n COALESCE(NULLIF(COALESCE(a.line_name_r, l.line_name_r), ''), NULL) AS line_name_r,\n COALESCE(NULLIF(COALESCE(a.line_name_zh, l.line_name_zh), ''), NULL) AS line_name_zh,\n COALESCE(NULLIF(COALESCE(a.line_name_ko, l.line_name_ko), ''), NULL) AS line_name_ko,\n COALESCE(NULLIF(COALESCE(a.line_color_c, l.line_color_c), ''), NULL) AS line_color_c,\n sst.id AS sst_id,\n sst.type_cd,\n sst.line_group_cd,\n sst.pass,\n t.id AS type_id,\n t.type_name,\n t.type_name_k,\n t.type_name_r,\n t.type_name_zh,\n t.type_name_ko,\n t.color,\n t.direction,\n t.kind,\n s.transport_type\n FROM\n stations AS s\n JOIN lines AS l ON l.line_cd = s.line_cd\n LEFT JOIN station_station_types AS sst ON sst.station_cd = s.station_cd\n LEFT JOIN types AS t ON t.type_cd = sst.type_cd\n LEFT JOIN line_aliases AS la ON la.station_cd = s.station_cd\n LEFT JOIN aliases AS a ON a.id = la.alias_cd\n WHERE\n s.station_g_cd = $1\n AND s.line_cd = l.line_cd\n AND s.e_status = 0\n AND l.e_status = 0", + "query": "SELECT s.station_cd,\n s.station_g_cd,\n s.station_name,\n s.station_name_k,\n s.station_name_r,\n s.station_name_rn,\n s.station_name_zh,\n s.station_name_ko,\n s.station_number1,\n s.station_number2,\n s.station_number3,\n s.station_number4,\n s.three_letter_code,\n s.line_cd,\n s.pref_cd,\n s.post,\n s.address,\n s.lon,\n s.lat,\n s.open_ymd,\n s.close_ymd,\n s.e_status,\n s.e_sort,\n l.company_cd,\n l.line_type,\n l.line_symbol1,\n l.line_symbol2,\n l.line_symbol3,\n l.line_symbol4,\n l.line_symbol1_color,\n l.line_symbol2_color,\n l.line_symbol3_color,\n l.line_symbol4_color,\n l.line_symbol1_shape,\n l.line_symbol2_shape,\n l.line_symbol3_shape,\n l.line_symbol4_shape,\n COALESCE(l.average_distance, 0.0)::DOUBLE PRECISION AS average_distance,\n COALESCE(NULLIF(COALESCE(a.line_name, l.line_name), ''), NULL) AS line_name,\n COALESCE(NULLIF(COALESCE(a.line_name_k, l.line_name_k), ''), NULL) AS line_name_k,\n COALESCE(NULLIF(COALESCE(a.line_name_h, l.line_name_h), ''), NULL) AS line_name_h,\n COALESCE(NULLIF(COALESCE(a.line_name_r, l.line_name_r), ''), NULL) AS line_name_r,\n COALESCE(NULLIF(COALESCE(a.line_name_zh, l.line_name_zh), ''), NULL) AS line_name_zh,\n COALESCE(NULLIF(COALESCE(a.line_name_ko, l.line_name_ko), ''), NULL) AS line_name_ko,\n COALESCE(NULLIF(COALESCE(a.line_color_c, l.line_color_c), ''), NULL) AS line_color_c,\n sst.id AS \"sst_id?\",\n sst.type_cd AS \"type_cd?\",\n sst.line_group_cd AS \"line_group_cd?\",\n sst.pass AS \"pass?\",\n t.id AS \"type_id?\",\n t.type_name AS \"type_name?\",\n t.type_name_k AS \"type_name_k?\",\n t.type_name_r AS \"type_name_r?\",\n t.type_name_zh AS \"type_name_zh?\",\n t.type_name_ko AS \"type_name_ko?\",\n t.color AS \"color?\",\n t.direction AS \"direction?\",\n t.kind AS \"kind?\",\n s.transport_type\n FROM\n stations AS s\n JOIN lines AS l ON l.line_cd = s.line_cd\n LEFT JOIN station_station_types AS sst ON sst.station_cd = s.station_cd\n LEFT JOIN types AS t ON t.type_cd = sst.type_cd\n LEFT JOIN line_aliases AS la ON la.station_cd = s.station_cd\n LEFT JOIN aliases AS a ON a.id = la.alias_cd\n WHERE\n s.station_g_cd = $1\n AND s.line_cd = l.line_cd\n AND s.e_status = 0\n AND l.e_status = 0", "describe": { "columns": [ { @@ -230,67 +230,67 @@ }, { "ordinal": 45, - "name": "sst_id", + "name": "sst_id?", "type_info": "Int4" }, { "ordinal": 46, - "name": "type_cd", + "name": "type_cd?", "type_info": "Int4" }, { "ordinal": 47, - "name": "line_group_cd", + "name": "line_group_cd?", "type_info": "Int4" }, { "ordinal": 48, - "name": "pass", + "name": "pass?", "type_info": "Int4" }, { "ordinal": 49, - "name": "type_id", + "name": "type_id?", "type_info": "Int4" }, { "ordinal": 50, - "name": "type_name", + "name": "type_name?", "type_info": "Text" }, { "ordinal": 51, - "name": "type_name_k", + "name": "type_name_k?", "type_info": "Text" }, { "ordinal": 52, - "name": "type_name_r", + "name": "type_name_r?", "type_info": "Text" }, { "ordinal": 53, - "name": "type_name_zh", + "name": "type_name_zh?", "type_info": "Text" }, { "ordinal": 54, - "name": "type_name_ko", + "name": "type_name_ko?", "type_info": "Text" }, { "ordinal": 55, - "name": "color", + "name": "color?", "type_info": "Text" }, { "ordinal": 56, - "name": "direction", + "name": "direction?", "type_info": "Int4" }, { "ordinal": 57, - "name": "kind", + "name": "kind?", "type_info": "Int4" }, { @@ -366,5 +366,5 @@ false ] }, - "hash": "90906c9a7d97f432f66f1722a6a51731194922c4cb16f8809ae1e2e711d5a0da" + "hash": "425870f89d0a0ae2c79e80ef7a468c5ef805d7a3f98b56e1b6ad93a1554683b7" } diff --git a/.sqlx/query-792ccb86508366f1a36b6d43a6f9a5dc2535b80b9df16fbd2d308221b545813b.json b/.sqlx/query-798b96a32fa32b2c306de99d300447ce83af5aece9ead36f3a31de63dd96b97a.json similarity index 61% rename from .sqlx/query-792ccb86508366f1a36b6d43a6f9a5dc2535b80b9df16fbd2d308221b545813b.json rename to .sqlx/query-798b96a32fa32b2c306de99d300447ce83af5aece9ead36f3a31de63dd96b97a.json index cd3ab0a5..5925146d 100644 --- a/.sqlx/query-792ccb86508366f1a36b6d43a6f9a5dc2535b80b9df16fbd2d308221b545813b.json +++ b/.sqlx/query-798b96a32fa32b2c306de99d300447ce83af5aece9ead36f3a31de63dd96b97a.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "WITH\n from_cte AS (\n SELECT\n s.station_cd,\n s.line_cd\n FROM\n stations AS s\n WHERE\n s.station_g_cd = $1\n ),\n to_cte AS (\n SELECT\n s.station_cd,\n s.line_cd\n FROM\n stations AS s\n WHERE\n s.station_g_cd = $2\n ),\n common_lines AS (\n SELECT DISTINCT s1.line_cd\n FROM stations s1\n WHERE s1.station_g_cd = $3\n AND s1.e_status = 0\n AND ($5::int IS NULL OR s1.line_cd = $5)\n AND EXISTS (\n SELECT 1\n FROM stations s2\n WHERE s2.station_g_cd = $4\n AND s2.e_status = 0\n AND s2.line_cd = s1.line_cd\n )\n ),\n sst_cte_c1 AS (\n SELECT\n sst.line_group_cd\n FROM\n station_station_types AS sst\n JOIN from_cte ON sst.station_cd = from_cte.station_cd\n WHERE\n sst.pass <> 1\n ),\n sst_cte_c2 AS (\n SELECT\n sst.line_group_cd\n FROM\n station_station_types AS sst\n JOIN to_cte ON sst.station_cd = to_cte.station_cd\n WHERE\n sst.pass <> 1\n ),\n sst_cte AS (\n SELECT\n sst.id,\n sst.station_cd,\n sst.type_cd,\n sst.line_group_cd,\n sst.pass\n FROM\n station_station_types AS sst\n JOIN sst_cte_c1 ON sst.line_group_cd = sst_cte_c1.line_group_cd\n JOIN sst_cte_c2 ON sst.line_group_cd = sst_cte_c2.line_group_cd\n )\n SELECT\n sta.station_cd,\n sta.station_g_cd,\n sta.station_name,\n sta.station_name_k,\n sta.station_name_r,\n sta.station_name_rn,\n sta.station_name_zh,\n sta.station_name_ko,\n sta.station_number1,\n sta.station_number2,\n sta.station_number3,\n sta.station_number4,\n sta.three_letter_code,\n sta.line_cd,\n sta.pref_cd,\n sta.post,\n sta.address,\n sta.lon,\n sta.lat,\n sta.open_ymd,\n sta.close_ymd,\n sta.e_status,\n sta.e_sort,\n lin.company_cd,\n COALESCE(NULLIF(COALESCE(a.line_name, lin.line_name), ''), NULL) AS line_name,\n COALESCE(NULLIF(COALESCE(a.line_name_k, lin.line_name_k), ''), NULL) AS line_name_k,\n COALESCE(NULLIF(COALESCE(a.line_name_h, lin.line_name_h), ''), NULL) AS line_name_h,\n COALESCE(NULLIF(COALESCE(a.line_name_r, lin.line_name_r), ''), NULL) AS line_name_r,\n COALESCE(NULLIF(COALESCE(a.line_name_zh, lin.line_name_zh), ''), NULL) AS line_name_zh,\n COALESCE(NULLIF(COALESCE(a.line_name_ko, lin.line_name_ko), ''), NULL) AS line_name_ko,\n COALESCE(NULLIF(COALESCE(a.line_color_c, lin.line_color_c), ''), NULL) AS line_color_c,\n lin.line_type,\n lin.line_symbol1,\n lin.line_symbol2,\n lin.line_symbol3,\n lin.line_symbol4,\n lin.line_symbol1_color,\n lin.line_symbol2_color,\n lin.line_symbol3_color,\n lin.line_symbol4_color,\n lin.line_symbol1_shape,\n lin.line_symbol2_shape,\n lin.line_symbol3_shape,\n lin.line_symbol4_shape,\n COALESCE(lin.average_distance, 0.0)::DOUBLE PRECISION AS average_distance,\n COALESCE(sst.line_group_cd, NULL)::int AS line_group_cd, -- has_train_types用\n NULL::int AS type_id,\n NULL::int AS sst_id,\n NULL::int AS type_cd,\n NULL::int AS pass,\n NULL::text AS type_name,\n NULL::text AS type_name_k,\n NULL::text AS type_name_r,\n NULL::text AS type_name_zh,\n NULL::text AS type_name_ko,\n NULL::text AS color,\n NULL::int AS direction,\n NULL::int AS kind,\n sta.transport_type\n FROM\n stations AS sta\n\t\t\t\tJOIN common_lines AS cl ON sta.line_cd = cl.line_cd\n\t\t\t\tJOIN lines AS lin ON lin.line_cd = cl.line_cd\n LEFT JOIN sst_cte AS sst ON sst.station_cd = sta.station_cd\n LEFT JOIN types AS tt ON tt.type_cd = sst.type_cd\n LEFT JOIN line_aliases AS la ON la.station_cd = sta.station_cd\n LEFT JOIN aliases AS a ON a.id = la.alias_cd\n WHERE\n sst.line_group_cd IS NULL\n AND lin.e_status = 0\n AND sta.e_status = 0\n ORDER BY sta.e_sort, sta.station_cd", + "query": "WITH\n from_cte AS (\n SELECT\n s.station_cd,\n s.line_cd\n FROM\n stations AS s\n WHERE\n s.station_g_cd = $1\n ),\n to_cte AS (\n SELECT\n s.station_cd,\n s.line_cd\n FROM\n stations AS s\n WHERE\n s.station_g_cd = $2\n ),\n common_lines AS (\n SELECT DISTINCT s1.line_cd\n FROM stations s1\n WHERE s1.station_g_cd = $3\n AND s1.e_status = 0\n AND (array_length($5::int[], 1) IS NULL OR s1.line_cd = ANY($5))\n AND EXISTS (\n SELECT 1\n FROM stations s2\n WHERE s2.station_g_cd = $4\n AND s2.e_status = 0\n AND s2.line_cd = s1.line_cd\n )\n ),\n sst_cte_c1 AS (\n SELECT\n sst.line_group_cd\n FROM\n station_station_types AS sst\n JOIN from_cte ON sst.station_cd = from_cte.station_cd\n WHERE\n sst.pass <> 1\n ),\n sst_cte_c2 AS (\n SELECT\n sst.line_group_cd\n FROM\n station_station_types AS sst\n JOIN to_cte ON sst.station_cd = to_cte.station_cd\n WHERE\n sst.pass <> 1\n ),\n sst_cte AS (\n SELECT\n sst.id,\n sst.station_cd,\n sst.type_cd,\n sst.line_group_cd,\n sst.pass\n FROM\n station_station_types AS sst\n JOIN sst_cte_c1 ON sst.line_group_cd = sst_cte_c1.line_group_cd\n JOIN sst_cte_c2 ON sst.line_group_cd = sst_cte_c2.line_group_cd\n )\n SELECT\n sta.station_cd,\n sta.station_g_cd,\n sta.station_name,\n sta.station_name_k,\n sta.station_name_r,\n sta.station_name_rn,\n sta.station_name_zh,\n sta.station_name_ko,\n sta.station_number1,\n sta.station_number2,\n sta.station_number3,\n sta.station_number4,\n sta.three_letter_code,\n sta.line_cd,\n sta.pref_cd,\n sta.post,\n sta.address,\n sta.lon,\n sta.lat,\n sta.open_ymd,\n sta.close_ymd,\n sta.e_status,\n sta.e_sort,\n lin.company_cd,\n COALESCE(NULLIF(COALESCE(a.line_name, lin.line_name), ''), NULL) AS line_name,\n COALESCE(NULLIF(COALESCE(a.line_name_k, lin.line_name_k), ''), NULL) AS line_name_k,\n COALESCE(NULLIF(COALESCE(a.line_name_h, lin.line_name_h), ''), NULL) AS line_name_h,\n COALESCE(NULLIF(COALESCE(a.line_name_r, lin.line_name_r), ''), NULL) AS line_name_r,\n COALESCE(NULLIF(COALESCE(a.line_name_zh, lin.line_name_zh), ''), NULL) AS line_name_zh,\n COALESCE(NULLIF(COALESCE(a.line_name_ko, lin.line_name_ko), ''), NULL) AS line_name_ko,\n COALESCE(NULLIF(COALESCE(a.line_color_c, lin.line_color_c), ''), NULL) AS line_color_c,\n lin.line_type,\n lin.line_symbol1,\n lin.line_symbol2,\n lin.line_symbol3,\n lin.line_symbol4,\n lin.line_symbol1_color,\n lin.line_symbol2_color,\n lin.line_symbol3_color,\n lin.line_symbol4_color,\n lin.line_symbol1_shape,\n lin.line_symbol2_shape,\n lin.line_symbol3_shape,\n lin.line_symbol4_shape,\n COALESCE(lin.average_distance, 0.0)::DOUBLE PRECISION AS average_distance,\n COALESCE(sst.line_group_cd, NULL)::int AS line_group_cd, -- has_train_types用\n NULL::int AS type_id,\n NULL::int AS sst_id,\n NULL::int AS type_cd,\n NULL::int AS pass,\n NULL::text AS type_name,\n NULL::text AS type_name_k,\n NULL::text AS type_name_r,\n NULL::text AS type_name_zh,\n NULL::text AS type_name_ko,\n NULL::text AS color,\n NULL::int AS direction,\n NULL::int AS kind,\n sta.transport_type\n FROM\n stations AS sta\n\t\t\t\tJOIN common_lines AS cl ON sta.line_cd = cl.line_cd\n\t\t\t\tJOIN lines AS lin ON lin.line_cd = cl.line_cd\n LEFT JOIN sst_cte AS sst ON sst.station_cd = sta.station_cd\n LEFT JOIN types AS tt ON tt.type_cd = sst.type_cd\n LEFT JOIN line_aliases AS la ON la.station_cd = sta.station_cd\n LEFT JOIN aliases AS a ON a.id = la.alias_cd\n WHERE\n sst.line_group_cd IS NULL\n AND lin.e_status = 0\n AND sta.e_status = 0\n ORDER BY sta.e_sort, sta.station_cd", "describe": { "columns": [ { @@ -305,7 +305,7 @@ "Int4", "Int4", "Int4", - "Int4" + "Int4Array" ] }, "nullable": [ @@ -370,5 +370,5 @@ false ] }, - "hash": "792ccb86508366f1a36b6d43a6f9a5dc2535b80b9df16fbd2d308221b545813b" + "hash": "798b96a32fa32b2c306de99d300447ce83af5aece9ead36f3a31de63dd96b97a" } diff --git a/.sqlx/query-2217a8a08cc485bd86fde1e2312d80eeb5957224af02af9c634ef262e5d6a0e0.json b/.sqlx/query-cce67d0ec979a71c4e7de242d6c38589c009ae80ee0bc865f5e98a81699c18ee.json similarity index 84% rename from .sqlx/query-2217a8a08cc485bd86fde1e2312d80eeb5957224af02af9c634ef262e5d6a0e0.json rename to .sqlx/query-cce67d0ec979a71c4e7de242d6c38589c009ae80ee0bc865f5e98a81699c18ee.json index 44f81734..40717a40 100644 --- a/.sqlx/query-2217a8a08cc485bd86fde1e2312d80eeb5957224af02af9c634ef262e5d6a0e0.json +++ b/.sqlx/query-cce67d0ec979a71c4e7de242d6c38589c009ae80ee0bc865f5e98a81699c18ee.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "SELECT s.station_cd,\n s.station_g_cd,\n s.station_name,\n s.station_name_k,\n s.station_name_r,\n s.station_name_rn,\n s.station_name_zh,\n s.station_name_ko,\n s.station_number1,\n s.station_number2,\n s.station_number3,\n s.station_number4,\n s.three_letter_code,\n s.line_cd,\n s.pref_cd,\n s.post,\n s.address,\n s.lon,\n s.lat,\n s.open_ymd,\n s.close_ymd,\n s.e_status,\n s.e_sort,\n l.company_cd,\n COALESCE(NULLIF(COALESCE(a.line_name, l.line_name), ''), NULL) AS line_name,\n COALESCE(NULLIF(COALESCE(a.line_name_k, l.line_name_k), ''), NULL) AS line_name_k,\n COALESCE(NULLIF(COALESCE(a.line_name_h, l.line_name_h), ''), NULL) AS line_name_h,\n COALESCE(NULLIF(COALESCE(a.line_name_r, l.line_name_r), ''), NULL) AS line_name_r,\n COALESCE(NULLIF(COALESCE(a.line_name_zh, l.line_name_zh), ''), NULL) AS line_name_zh,\n COALESCE(NULLIF(COALESCE(a.line_name_ko, l.line_name_ko), ''), NULL) AS line_name_ko,\n COALESCE(NULLIF(COALESCE(a.line_color_c, l.line_color_c), ''), NULL) AS line_color_c,\n l.line_type,\n l.line_symbol1,\n l.line_symbol2,\n l.line_symbol3,\n l.line_symbol4,\n l.line_symbol1_color,\n l.line_symbol2_color,\n l.line_symbol3_color,\n l.line_symbol4_color,\n l.line_symbol1_shape,\n l.line_symbol2_shape,\n l.line_symbol3_shape,\n l.line_symbol4_shape,\n COALESCE(l.average_distance, 0.0)::DOUBLE PRECISION AS average_distance,\n t.id AS type_id,\n sst.id AS sst_id,\n sst.type_cd,\n sst.line_group_cd,\n sst.pass,\n t.type_name,\n t.type_name_k,\n t.type_name_r,\n t.type_name_zh,\n t.type_name_ko,\n t.color,\n t.direction,\n t.kind,\n s.transport_type\n FROM stations AS s\n JOIN lines AS l ON l.line_cd = s.line_cd\n LEFT JOIN station_station_types AS sst ON sst.station_cd = s.station_cd\n LEFT JOIN types AS t ON t.type_cd = sst.type_cd\n LEFT JOIN line_aliases AS la ON la.station_cd = s.station_cd\n LEFT JOIN aliases AS a ON a.id = la.alias_cd\n WHERE s.station_cd = $1\n AND s.e_status = 0\n AND l.e_status = 0\n LIMIT 1", + "query": "SELECT s.station_cd,\n s.station_g_cd,\n s.station_name,\n s.station_name_k,\n s.station_name_r,\n s.station_name_rn,\n s.station_name_zh,\n s.station_name_ko,\n s.station_number1,\n s.station_number2,\n s.station_number3,\n s.station_number4,\n s.three_letter_code,\n s.line_cd,\n s.pref_cd,\n s.post,\n s.address,\n s.lon,\n s.lat,\n s.open_ymd,\n s.close_ymd,\n s.e_status,\n s.e_sort,\n l.company_cd,\n COALESCE(NULLIF(COALESCE(a.line_name, l.line_name), ''), NULL) AS line_name,\n COALESCE(NULLIF(COALESCE(a.line_name_k, l.line_name_k), ''), NULL) AS line_name_k,\n COALESCE(NULLIF(COALESCE(a.line_name_h, l.line_name_h), ''), NULL) AS line_name_h,\n COALESCE(NULLIF(COALESCE(a.line_name_r, l.line_name_r), ''), NULL) AS line_name_r,\n COALESCE(NULLIF(COALESCE(a.line_name_zh, l.line_name_zh), ''), NULL) AS line_name_zh,\n COALESCE(NULLIF(COALESCE(a.line_name_ko, l.line_name_ko), ''), NULL) AS line_name_ko,\n COALESCE(NULLIF(COALESCE(a.line_color_c, l.line_color_c), ''), NULL) AS line_color_c,\n l.line_type,\n l.line_symbol1,\n l.line_symbol2,\n l.line_symbol3,\n l.line_symbol4,\n l.line_symbol1_color,\n l.line_symbol2_color,\n l.line_symbol3_color,\n l.line_symbol4_color,\n l.line_symbol1_shape,\n l.line_symbol2_shape,\n l.line_symbol3_shape,\n l.line_symbol4_shape,\n COALESCE(l.average_distance, 0.0)::DOUBLE PRECISION AS average_distance,\n t.id AS \"type_id?\",\n sst.id AS \"sst_id?\",\n sst.type_cd AS \"type_cd?\",\n sst.line_group_cd AS \"line_group_cd?\",\n sst.pass AS \"pass?\",\n t.type_name AS \"type_name?\",\n t.type_name_k AS \"type_name_k?\",\n t.type_name_r AS \"type_name_r?\",\n t.type_name_zh AS \"type_name_zh?\",\n t.type_name_ko AS \"type_name_ko?\",\n t.color AS \"color?\",\n t.direction AS \"direction?\",\n t.kind AS \"kind?\",\n s.transport_type\n FROM stations AS s\n JOIN lines AS l ON l.line_cd = s.line_cd\n LEFT JOIN station_station_types AS sst ON sst.station_cd = s.station_cd\n LEFT JOIN types AS t ON t.type_cd = sst.type_cd\n LEFT JOIN line_aliases AS la ON la.station_cd = s.station_cd\n LEFT JOIN aliases AS a ON a.id = la.alias_cd\n WHERE s.station_cd = $1\n AND s.e_status = 0\n AND l.e_status = 0\n LIMIT 1", "describe": { "columns": [ { @@ -230,67 +230,67 @@ }, { "ordinal": 45, - "name": "type_id", + "name": "type_id?", "type_info": "Int4" }, { "ordinal": 46, - "name": "sst_id", + "name": "sst_id?", "type_info": "Int4" }, { "ordinal": 47, - "name": "type_cd", + "name": "type_cd?", "type_info": "Int4" }, { "ordinal": 48, - "name": "line_group_cd", + "name": "line_group_cd?", "type_info": "Int4" }, { "ordinal": 49, - "name": "pass", + "name": "pass?", "type_info": "Int4" }, { "ordinal": 50, - "name": "type_name", + "name": "type_name?", "type_info": "Text" }, { "ordinal": 51, - "name": "type_name_k", + "name": "type_name_k?", "type_info": "Text" }, { "ordinal": 52, - "name": "type_name_r", + "name": "type_name_r?", "type_info": "Text" }, { "ordinal": 53, - "name": "type_name_zh", + "name": "type_name_zh?", "type_info": "Text" }, { "ordinal": 54, - "name": "type_name_ko", + "name": "type_name_ko?", "type_info": "Text" }, { "ordinal": 55, - "name": "color", + "name": "color?", "type_info": "Text" }, { "ordinal": 56, - "name": "direction", + "name": "direction?", "type_info": "Int4" }, { "ordinal": 57, - "name": "kind", + "name": "kind?", "type_info": "Int4" }, { @@ -366,5 +366,5 @@ false ] }, - "hash": "2217a8a08cc485bd86fde1e2312d80eeb5957224af02af9c634ef262e5d6a0e0" + "hash": "cce67d0ec979a71c4e7de242d6c38589c009ae80ee0bc865f5e98a81699c18ee" } diff --git a/README.md b/README.md index c3d7f728..4b3fab2c 100644 --- a/README.md +++ b/README.md @@ -51,19 +51,6 @@ This project follows the [all-contributors](https://github.com/all-contributors/ Do you like this project? Join our Discord community! [https://discord.gg/tsemdME9Nz](https://discord.gg/tsemdME9Nz) -## Monitoring - -A Prometheus + Grafana environment for visualizing gRPC metrics is included. - -```bash -docker compose up -d api prometheus grafana -``` - -- **Grafana**: http://localhost:3001 (login: `admin` / `admin`) -- **Prometheus**: http://localhost:9090 - -Grafana comes with a pre-provisioned "StationAPI gRPC Metrics" dashboard, where you can monitor request rates, error rates, latency percentiles, and more. - ## Development ### Running Tests diff --git a/compose.yml b/compose.yml index bb9dfddd..fe6f8b58 100644 --- a/compose.yml +++ b/compose.yml @@ -42,33 +42,4 @@ services: ports: - 5432:5432 volumes: - - ./docker/postgres:/docker-entrypoint-initdb.d:ro - - prometheus: - image: prom/prometheus:${PROMETHEUS_VERSION:-v3.2.1} - volumes: - - ./docker/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro - - prometheus_data:/prometheus - ports: - - 9090:9090 - restart: always - - grafana: - image: grafana/grafana:${GRAFANA_VERSION:-11.5.2} - depends_on: - - prometheus - volumes: - - ./docker/grafana/provisioning:/etc/grafana/provisioning:ro - - ./docker/grafana/dashboards:/var/lib/grafana/dashboards:ro - - grafana_data:/var/lib/grafana - environment: - GF_SECURITY_ADMIN_USER: admin - GF_SECURITY_ADMIN_PASSWORD: admin - GF_USERS_ALLOW_SIGN_UP: "false" - ports: - - 3001:3000 - restart: always - -volumes: - prometheus_data: - grafana_data: \ No newline at end of file + - ./docker/postgres:/docker-entrypoint-initdb.d:ro \ No newline at end of file diff --git a/data/2!lines.csv b/data/2!lines.csv index c828060d..77efdbd5 100644 --- a/data/2!lines.csv +++ b/data/2!lines.csv @@ -1,625 +1,625 @@ line_cd,company_cd,line_name,line_name_k,line_name_h,line_name_r,line_name_rn,line_name_zh,line_name_ko,line_color_c,line_type,line_symbol1,line_symbol2,line_symbol3,line_symbol4,line_symbol1_color,line_symbol2_color,line_symbol3_color,line_symbol4_color,line_symbol1_shape,line_symbol2_shape,line_symbol3_shape,line_symbol4_shape,e_status,e_sort,average_distance 1001,3,中央新幹線,チュウオウシンカンセン,中央新幹線,Chuo Shinkansen,Chuo Shinkansen,中央新干线,주오 신칸센,#000000,1,,,,,,,,,NOOP,,,,1,1001,0 -1002,3,東海道新幹線,トウカイドウシンカンセン,東海道新幹線,Tokaido Shinkansen,Tokaido Shinkansen,东海道新干线,도카이도 신칸센,#0000FF,1,,,,,,,,,NOOP,,,,0,1002,31785.47337 -1003,4,山陽新幹線,サンヨウシンカンセン,山陽新幹線,Sanyo Shinkansen,Sanyo Shinkansen,山阳新干线,산요 신칸센,#0000FF,1,,,,,,,,,NOOP,,,,0,1003,30007.31309 -1004,2,東北新幹線,トウホクシンカンセン,東北新幹線,Tōhoku Shinkansen,Tohoku Shinkansen,东北新干线,도호쿠 신칸센,#008000,1,,,,,,,,,NOOP,,,,0,1004,31081.32408 -1005,2,上越新幹線,ジョウエツシンカンセン,上越新幹線,Joetsu Shinkansen,Joetsu Shinkansen,上越新干线,조에쓰 신칸센,#008000,1,,,,,,,,,NOOP,,,,0,1005,27555.49409 -1006,2,上越新幹線(ガーラ湯沢支線),ジョウエツシンカンセン,上越新幹線(ガーラ湯沢支線),Joetsu Shinkansen,Joetsu Shinkansen,上越新干线,조에쓰 신칸센,#008000,1,,,,,,,,,NOOP,,,,0,1006,1978.00847 -1007,2,山形新幹線,ヤマガタシンカンセン,山形新幹線,Yamagata Shinkansen,Yamagata Shinkansen,山形新干线,야마가타 신칸센,#FFA030,1,,,,,,,,,NOOP,,,,0,1007,22518.03451 -1008,2,秋田新幹線,アキタシンカンセン,秋田新幹線,Akita Shinkansen,Akita Shinkansen,秋田新干线,아키타 신칸센,#FF0080,1,,,,,,,,,NOOP,,,,0,1008,28353.89185 -1009,2,北陸新幹線,ホクリクシンカンセン,北陸新幹線,Hokuriku Shinkansen,Hokuriku Shinkansen,北陆新干线,호쿠리쿠 신칸센,#008000,1,,,,,,,,,NOOP,,,,0,1009,24612.49726 -1010,6,九州新幹線,キュウシュウシンカンセン,九州新幹線,Kyushu Shinkansen,Kyushu Shinkansen,九州新干线,규슈 신칸센,#FF0000,1,,,,,,,,,NOOP,,,,0,1010,23348.37170 -1011,1,北海道新幹線,ホッカイドウシンカンセン,北海道新幹線,Hokkaido Shinkansen,Hokkaido Shinkansen,北海道新干线,홋카이도 신칸센,#6E5CA5,1,,,,,,,,,NOOP,,,,0,1011,43413.98277 -1012,6,西九州新幹線,ニシキュウシュウシンカンセン,西九州新幹線,Nishi-Kyushu Shinkansen,Nishi-Kyushu Shinkansen,西九州新干线,니시큐슈 신칸센,#E10017,1,,,,,,,,,NOOP,,,,0,1012,16125.84235 -11101,1,函館本線,ハコダテホンセン,函館本線,Hakodate Main Line,Hakodate Main Line,函馆本线,하코다테 본선,#0072BC,2,H,N,,,#0072BC,#0072BC,,,ROUND,ROUND,,,0,11101,4486.97724 -11102,1,函館本線,ハコダテホンセン,函館本線,Hakodate Main Line,Hakodate Main Line,函馆本线,하코다테 본선,#ED1C23,2,S,H,,,#ED1C23,#0072BC,,,ROUND,ROUND,,,0,11102,7673.18680 -11103,1,函館本線,ハコダテホンセン,函館本線,Hakodate Main Line,Hakodate Main Line,函馆本线,하코다테 본선,#F7931D,2,A,H,,S,#F7931D,#0072BC,#F7931D,#ED1C23,ROUND,ROUND,MONOCHROME_ROUND,ROUND,0,11103,4642.70163 +1002,3,東海道新幹線,トウカイドウシンカンセン,東海道新幹線,Tokaido Shinkansen,Tokaido Shinkansen,东海道新干线,도카이도 신칸센,#0000FF,1,,,,,,,,,NOOP,,,,0,1002,31664.84112 +1003,4,山陽新幹線,サンヨウシンカンセン,山陽新幹線,Sanyo Shinkansen,Sanyo Shinkansen,山阳新干线,산요 신칸센,#0000FF,1,,,,,,,,,NOOP,,,,0,1003,30686.38868 +1004,2,東北新幹線,トウホクシンカンセン,東北新幹線,Tōhoku Shinkansen,Tohoku Shinkansen,东北新干线,도호쿠 신칸센,#008000,1,,,,,,,,,NOOP,,,,0,1004,30711.08884 +1005,2,上越新幹線,ジョウエツシンカンセン,上越新幹線,Joetsu Shinkansen,Joetsu Shinkansen,上越新干线,조에쓰 신칸센,#008000,1,,,,,,,,,NOOP,,,,0,1005,27350.8261 +1006,2,上越新幹線(ガーラ湯沢支線),ジョウエツシンカンセン,上越新幹線(ガーラ湯沢支線),Joetsu Shinkansen,Joetsu Shinkansen,上越新干线,조에쓰 신칸센,#008000,1,,,,,,,,,NOOP,,,,0,1006,1883.81759 +1007,2,山形新幹線,ヤマガタシンカンセン,山形新幹線,Yamagata Shinkansen,Yamagata Shinkansen,山形新干线,야마가타 신칸센,#FFA030,1,,,,,,,,,NOOP,,,,0,1007,14868.12368 +1008,2,秋田新幹線,アキタシンカンセン,秋田新幹線,Akita Shinkansen,Akita Shinkansen,秋田新干线,아키타 신칸센,#FF0080,1,,,,,,,,,NOOP,,,,0,1008,25377.10815 +1009,2,北陸新幹線,ホクリクシンカンセン,北陸新幹線,Hokuriku Shinkansen,Hokuriku Shinkansen,北陆新干线,호쿠리쿠 신칸센,#008000,1,,,,,,,,,NOOP,,,,0,1009,25170.74968 +1010,6,九州新幹線,キュウシュウシンカンセン,九州新幹線,Kyushu Shinkansen,Kyushu Shinkansen,九州新干线,규슈 신칸센,#FF0000,1,,,,,,,,,NOOP,,,,0,1010,23348.86657 +1011,1,北海道新幹線,ホッカイドウシンカンセン,北海道新幹線,Hokkaido Shinkansen,Hokkaido Shinkansen,北海道新干线,홋카이도 신칸센,#6E5CA5,1,,,,,,,,,NOOP,,,,0,1011,49638.47771 +1012,6,西九州新幹線,ニシキュウシュウシンカンセン,西九州新幹線,Nishi-Kyushu Shinkansen,Nishi-Kyushu Shinkansen,西九州新干线,니시큐슈 신칸센,#E10017,1,,,,,,,,,NOOP,,,,0,1012,16460.66246 +11101,1,函館本線,ハコダテホンセン,函館本線,Hakodate Main Line,Hakodate Main Line,函馆本线,하코다테 본선,#0072BC,2,H,N,,,#0072BC,#0072BC,,,ROUND,ROUND,,,0,11101,5751.21755 +11102,1,函館本線,ハコダテホンセン,函館本線,Hakodate Main Line,Hakodate Main Line,函馆本线,하코다테 본선,#ED1C23,2,S,H,,,#ED1C23,#0072BC,,,ROUND,ROUND,,,0,11102,8706.85948 +11103,1,函館本線,ハコダテホンセン,函館本線,Hakodate Main Line,Hakodate Main Line,函馆本线,하코다테 본선,#F7931D,2,A,H,,S,#F7931D,#0072BC,#F7931D,#ED1C23,ROUND,ROUND,MONOCHROME_ROUND,ROUND,0,11103,4242.70521 11104,1,室蘭本線,ムロランホンセン,室蘭本線,Muroran Main Line,Muroran Main Line,室兰本线,무로란 본선,#0072BC,2,H,M,,,#0072BC,#0072BC,,,ROUND,ROUND,,,0,11104,4663.48446 -11105,1,室蘭本線,ムロランホンセン,室蘭本線,Muroran Main Line,Muroran Main Line,室兰本线,무로란 본선,#808080,2,H,K,A,,#0072BC,#8CC63E,#F7931D,,ROUND,ROUND,ROUND,,0,11105,6482.48941 -11106,1,根室本線,ネムロホンセン,根室本線,Nemuro Main Line,Nemuro Main Line,根室本线,네무로 본선,#F6989D,2,T,K,A,,#F6989D,#8CC63E,#F7931D,,ROUND,ROUND,ROUND,,0,11106,7534.34160 -11107,1,根室本線,ネムロホンセン,根室本線,Nemuro Main Line,Nemuro Main Line,根室本线,네무로 본선,#8CC63E,2,K,,,,#8CC63E,,,,ROUND,,,,0,11107,6015.23016 -11108,1,花咲線,ハナサキセン,根室本線,Hanasaki Line,Hanasaki Line,花咲线,하나사키선,#808080,2,K,B,,,#8CC63E,#EF59A1,,,ROUND,ROUND,,,0,11108,6803.30201 -11109,1,千歳線,チトセセン,千歳線,Chitose Line,Chitose Line,千岁线,지토세선,#00B2EB,2,H,AP,,,#0072BC,#00B2EB,#00B2EB,,ROUND,ROUND,MONOCHROME_ROUND,,0,11109,4446.95761 -11110,1,石勝線,セキショウセン,石勝線,Sekisho Main Line,Sekisho Main Line,石胜线,세키쇼선,#8CC63E,2,K,H,Y,,#8CC63E,#0072BC,#8CC63E,,ROUND,ROUND,ROUND,,0,11110,10056.36395 -11111,1,日高本線,ヒダカホンセン,日高本線,Hidaka Main Line,Hidaka Main Line,日高本线,히다카 본선,#808080,2,H,,,,#0072BC,,,,ROUND,,,,0,11111,5224.43576 -11112,1,札沼線,サッショウセン,札沼線,Sassho Line,Sassho Line,札沼线,삿쇼선,#00A54F,2,G,S,,,#00A54F,#ED1C23,#00A54F,,ROUND,ROUND,MONOCHROME_ROUND,,0,11112,2909.57229 +11105,1,室蘭本線,ムロランホンセン,室蘭本線,Muroran Main Line,Muroran Main Line,室兰本线,무로란 본선,#808080,2,H,K,A,,#0072BC,#8CC63E,#F7931D,,ROUND,ROUND,ROUND,,0,11105,5799.95676 +11106,1,根室本線,ネムロホンセン,根室本線,Nemuro Main Line,Nemuro Main Line,根室本线,네무로 본선,#F6989D,2,T,K,A,,#F6989D,#8CC63E,#F7931D,,ROUND,ROUND,ROUND,,0,11106,7771.24051 +11107,1,根室本線,ネムロホンセン,根室本線,Nemuro Main Line,Nemuro Main Line,根室本线,네무로 본선,#8CC63E,2,K,,,,#8CC63E,,,,ROUND,,,,0,11107,7120.01641 +11108,1,花咲線,ハナサキセン,根室本線,Hanasaki Line,Hanasaki Line,花咲线,하나사키선,#808080,2,K,B,,,#8CC63E,#EF59A1,,,ROUND,ROUND,,,0,11108,8394.29526 +11109,1,千歳線,チトセセン,千歳線,Chitose Line,Chitose Line,千岁线,지토세선,#00B2EB,2,H,AP,,,#0072BC,#00B2EB,#00B2EB,,ROUND,ROUND,MONOCHROME_ROUND,,0,11109,4658.0034 +11110,1,石勝線,セキショウセン,石勝線,Sekisho Main Line,Sekisho Main Line,石胜线,세키쇼선,#8CC63E,2,K,H,Y,,#8CC63E,#0072BC,#8CC63E,,ROUND,ROUND,ROUND,,0,11110,21622.86655 +11111,1,日高本線,ヒダカホンセン,日高本線,Hidaka Main Line,Hidaka Main Line,日高本线,히다카 본선,#808080,2,H,,,,#0072BC,,,,ROUND,,,,0,11111,10690.53366 +11112,1,札沼線,サッショウセン,札沼線,Sassho Line,Sassho Line,札沼线,삿쇼선,#00A54F,2,G,S,,,#00A54F,#ED1C23,#00A54F,,ROUND,ROUND,MONOCHROME_ROUND,,0,11112,2132.35164 11113,1,留萌本線,ルモイホンセン,留萌本線,Rumoi Main Line,Rumoi Main Line,留萌本线,루모이 본선,#808080,2,,,,,,,,,,,,,2,11113,3301.27079 11114,1,富良野線,フラノセン,富良野線,Furano Line,Furano Line,富良野线,후라노선,#AA5EA6,2,F,A,T,,#AA5EA6,#F7931D,#F6989D,,ROUND,ROUND,ROUND,,0,11114,3534.04987 -11115,1,宗谷本線,ソウヤホンセン,宗谷本線,Soya Main Line,Soya Main Line,宗谷本线,소야 본선,#954A35,2,W,A,,,#954A35,#F7931D,,,ROUND,ROUND,,,0,11115,5129.20468 -11116,1,石北本線,セキホクホンセン,石北本線,Sekihoku Main Line,Sekihoku Main Line,石北本线,세키호쿠 본선,#F7931D,2,A,,,,#F7931D,,,,ROUND,,,,0,11116,6032.56729 -11117,1,釧網本線,センモウホンセン,釧網本線,Senmo Main Line,Senmo Main Line,钏网本线,센모 본선,#EF59A1,2,B,A,K,,#EF59A1,#F7931D,#8CC63E,,ROUND,ROUND,ROUND,,0,11117,6635.35746 -11118,1,海峡線,カイキョウセン,海峡線,Kaikyo Line,Kaikyo Line,海峡线,가이쿄선,#808080,2,,,,,,,,,,,,,0,11118,19521.34739 +11115,1,宗谷本線,ソウヤホンセン,宗谷本線,Soya Main Line,Soya Main Line,宗谷本线,소야 본선,#954A35,2,W,A,,,#954A35,#F7931D,,,ROUND,ROUND,,,0,11115,7559.48998 +11116,1,石北本線,セキホクホンセン,石北本線,Sekihoku Main Line,Sekihoku Main Line,石北本线,세키호쿠 본선,#F7931D,2,A,,,,#F7931D,,,,ROUND,,,,0,11116,7365.37104 +11117,1,釧網本線,センモウホンセン,釧網本線,Senmo Main Line,Senmo Main Line,钏网本线,센모 본선,#EF59A1,2,B,A,K,,#EF59A1,#F7931D,#8CC63E,,ROUND,ROUND,ROUND,,0,11117,7458.97654 +11118,1,海峡線,カイキョウセン,海峡線,Kaikyo Line,Kaikyo Line,海峡线,가이쿄선,#808080,2,,,,,,,,,,,,,0,11118,41415.71645 11119,1,江差線,エサシセン,江差線,Esashi Line,Esashi Line,江差线,에사시선,#808080,2,,,,,,,,,,,,,2,11119,4927.03676 11201,2,東北本線,トウホクホンセン,東北本線,Tohoku Main Line,Tohoku Main Line,东北本线,도호쿠 본선,#3CB371,2,,,,,,,,,,,,,2,11201,0 -11202,2,奥羽本線,オウウホンセン,奥羽本線,Ou Main Line,Ou Main Line,奥羽本线,오우 본선,#FF6600,2,,,,,,,,,,,,,0,11202,5627.56661 +11202,2,奥羽本線,オウウホンセン,奥羽本線,Ou Main Line,Ou Main Line,奥羽本线,오우 본선,#FF6600,2,,,,,,,,,,,,,0,11202,5078.81003 11231,2,東北本線,トウホクホンセン,東北本線,Tohoku Main Line,Tohoku Main Line,东北本线,도호쿠 본선,#3CB371,2,,,,,,,,,,,,,0,11202,4941.34332 -11203,2,はまなすベイライン大湊線,ハマナスベイラインオオミナトセン,大湊線,Ominato Line,Ominato Line,大凑线,오미나토선,#F1AA28,2,,,,,,,,,,,,,0,11203,6449.30132 -11204,2,五能線,ゴノウセン,五能線,Gono Line,Gono Line,五能线,고노선,#0000FF,2,,,,,,,,,,,,,0,11204,3709.89110 -11205,2,津軽線,ツガルセン,津軽線,Tsugaru Line,Tsugaru Line,津轻线,쓰가루선,#00B2E5,2,,,,,,,,,,,,,0,11205,3457.20444 -11206,2,八戸線,ハチノヘセン,八戸線,Hachinohe Line,Hachinohe Line,八户线,하치노헤선,#FF0000,2,,,,,,,,,,,,,0,11206,2807.70422 +11203,2,はまなすベイライン大湊線,ハマナスベイラインオオミナトセン,大湊線,Ominato Line,Ominato Line,大凑线,오미나토선,#F1AA28,2,,,,,,,,,,,,,0,11203,5783.7144 +11204,2,五能線,ゴノウセン,五能線,Gono Line,Gono Line,五能线,고노선,#0000FF,2,,,,,,,,,,,,,0,11204,3709.8911 +11205,2,津軽線,ツガルセン,津軽線,Tsugaru Line,Tsugaru Line,津轻线,쓰가루선,#00B2E5,2,,,,,,,,,,,,,0,11205,3231.67465 +11206,2,八戸線,ハチノヘセン,八戸線,Hachinohe Line,Hachinohe Line,八户线,하치노헤선,#FF0000,2,,,,,,,,,,,,,0,11206,2775.18494 11207,2,岩泉線,イワイズミセン,岩泉線,Iwaizumi Line,Iwaizumi Line,岩泉线,이와이즈미선,#808080,2,,,,,,,,,,,,,2,11207,5029.38286 -11208,2,ドラゴンレール大船渡線,ドラゴンレールオオフナトセン,大船渡線,Ofunato Line,Ofunato Line,大船渡线,오후나토선,#FF6600,2,,,,,,,,,,,,,0,11208,4346.82605 -11209,2,銀河ドリームライン釜石線,ギンガドリームラインカマイシセン,釜石線,Kamaishi Line,Kamaishi Line,釜石线,가마이시선,#3399FF,2,,,,,,,,,,,,,0,11209,4012.09424 -11210,2,北上線,キタカミセン,北上線,Kitakami Line,Kitakami Line,北上线,기타카미선,#9966FF,2,,,,,,,,,,,,,0,11210,3875.20255 -11211,2,田沢湖線,タザワコセン,田沢湖線,Tazawako Line,Tazawako Line,田泽湖线,다자와코선,#CC00CC,2,,,,,,,,,,,,,0,11211,4988.80604 -11212,2,十和田八幡平四季彩ライン,トワダハチマンタイシキサイライン,花輪線,Hanawa Line,Hanawa Line,花轮线,하나와선,#FF0000,2,,,,,,,,,,,,,0,11212,4265.91703 -11213,2,山田線,ヤマダセン,山田線,Yamada Line,Yamada Line,山田线,야마다선,#A52A2A,2,,,,,,,,,,,,,0,11213,5043.98631 -11214,2,羽越本線,ウエツホンセン,羽越本線,Uetsu Main Line,Uetsu Main Line,羽越本线,우에쓰 본선,#16C0E9,2,,,,,,,,,,,,,0,11214,5032.06651 -11215,2,男鹿線,オガセン,男鹿線,Oga Line,Oga Line,男鹿线,오가선,#008000,2,,,,,,,,,,,,,0,11215,3519.26651 -11216,2,山形線,ヤマガタセン,奥羽本線,Ou Main Line,Ou Main Line,奥羽本线,오우 본선,#FF6600,2,,,,,,,,,,,,,0,11216,4615.24950 -11217,2,仙山線,センザンセン,仙山線,Senzan Line,Senzan Line,仙山线,센잔선,#77DD00,2,,,,,,,,,,,,,0,11217,3304.49330 -11218,2,フルーツライン左沢線,フルーツラインアテラザワセン,左沢線,Aterazawa Line,Aterazawa Line,左泽线,아테라자와선,#87CEEB,2,,,,,,,,,,,,,0,11218,2597.45608 -11219,2,米坂線,ヨネサカセン,米坂線,Yonesaka Line,Yonesaka Line,米坂线,요네사카선,#9E7EB9,2,,,,,,,,,,,,,0,11219,4815.13053 -11220,2,奥の細道最上川ライン,オクノホソミチモガミガワライン,陸羽西線,Riku-West Line,Riku-West Line,陆羽西线,리쿠우사이선,#32CD32,2,,,,,,,,,,,,,0,11220,4973.93483 -11221,2,奥の細道湯けむりライン,オクノホソミチユケムリライン,陸羽東線,Riku-East Line,Riku-East Line,陆羽东线,리쿠우토선,#888888,2,,,,,,,,,,,,,0,11221,3831.41657 -11222,2,仙石線,センセキセン,仙石線,Senseki Line,Senseki Line,仙石线,센세키선,#00AAEE,2,,,,,,,,,,,,,0,11222,1739.37821 -11223,2,石巻線,イシノマキセン,石巻線,Ishinomaki Line,Ishinomaki Line,石卷线,이시노마키선,#FF8888,2,,,,,,,,,,,,,0,11223,3665.15389 -11224,2,気仙沼線,ケセンヌマセン,気仙沼線,Kesennuma Line,Kesennuma Line,气仙沼线,게센누마선,#6600CC,2,,,,,,,,,,,,,0,11224,3483.16135 -11225,2,磐越西線,バンエツサイセン,磐越西線,Ban-etsu-West Line,Ban-etsu-West Line,磐越西线,반에쓰사이선,#CB7B35,2,,,,,,,,,,,,,0,11225,4388.96889 +11208,2,ドラゴンレール大船渡線,ドラゴンレールオオフナトセン,大船渡線,Ofunato Line,Ofunato Line,大船渡线,오후나토선,#FF6600,2,,,,,,,,,,,,,0,11208,4676.41919 +11209,2,銀河ドリームライン釜石線,ギンガドリームラインカマイシセン,釜石線,Kamaishi Line,Kamaishi Line,釜石线,가마이시선,#3399FF,2,,,,,,,,,,,,,0,11209,3833.74466 +11210,2,北上線,キタカミセン,北上線,Kitakami Line,Kitakami Line,北上线,기타카미선,#9966FF,2,,,,,,,,,,,,,0,11210,4298.02779 +11211,2,田沢湖線,タザワコセン,田沢湖線,Tazawako Line,Tazawako Line,田泽湖线,다자와코선,#CC00CC,2,,,,,,,,,,,,,0,11211,4404.27879 +11212,2,十和田八幡平四季彩ライン,トワダハチマンタイシキサイライン,花輪線,Hanawa Line,Hanawa Line,花轮线,하나와선,#FF0000,2,,,,,,,,,,,,,0,11212,4057.91742 +11213,2,山田線,ヤマダセン,山田線,Yamada Line,Yamada Line,山田线,야마다선,#A52A2A,2,,,,,,,,,,,,,0,11213,7119.63504 +11214,2,羽越本線,ウエツホンセン,羽越本線,Uetsu Main Line,Uetsu Main Line,羽越本线,우에쓰 본선,#16C0E9,2,,,,,,,,,,,,,0,11214,4527.50896 +11215,2,男鹿線,オガセン,男鹿線,Oga Line,Oga Line,男鹿线,오가선,#008000,2,,,,,,,,,,,,,0,11215,3258.95101 +11216,2,山形線,ヤマガタセン,奥羽本線,Ou Main Line,Ou Main Line,奥羽本线,오우 본선,#FF6600,2,,,,,,,,,,,,,0,11216,4347.80555 +11217,2,仙山線,センザンセン,仙山線,Senzan Line,Senzan Line,仙山线,센잔선,#77DD00,2,,,,,,,,,,,,,0,11217,3260.49073 +11218,2,フルーツライン左沢線,フルーツラインアテラザワセン,左沢線,Aterazawa Line,Aterazawa Line,左泽线,아테라자와선,#87CEEB,2,,,,,,,,,,,,,0,11218,2342.45187 +11219,2,米坂線,ヨネサカセン,米坂線,Yonesaka Line,Yonesaka Line,米坂线,요네사카선,#9E7EB9,2,,,,,,,,,,,,,0,11219,4748.5509 +11220,2,奥の細道最上川ライン,オクノホソミチモガミガワライン,陸羽西線,Riku-West Line,Riku-West Line,陆羽西线,리쿠우사이선,#32CD32,2,,,,,,,,,,,,,0,11220,4722.99873 +11221,2,奥の細道湯けむりライン,オクノホソミチユケムリライン,陸羽東線,Riku-East Line,Riku-East Line,陆羽东线,리쿠우토선,#888888,2,,,,,,,,,,,,,0,11221,3579.42511 +11222,2,仙石線,センセキセン,仙石線,Senseki Line,Senseki Line,仙石线,센세키선,#00AAEE,2,,,,,,,,,,,,,0,11222,1540.61707 +11223,2,石巻線,イシノマキセン,石巻線,Ishinomaki Line,Ishinomaki Line,石卷线,이시노마키선,#FF8888,2,,,,,,,,,,,,,0,11223,3387.61695 +11224,2,気仙沼線,ケセンヌマセン,気仙沼線,Kesennuma Line,Kesennuma Line,气仙沼线,게센누마선,#6600CC,2,,,,,,,,,,,,,0,11224,3455.74637 +11225,2,磐越西線,バンエツサイセン,磐越西線,Ban-etsu-West Line,Ban-etsu-West Line,磐越西线,반에쓰사이선,#CB7B35,2,,,,,,,,,,,,,0,11225,4271.66886 11226,2,森と水とロマンの鉄道,モリトミズトロマンノテツドウ,磐越西線,Ban-etsu-West Line,Ban-etsu-West Line,磐越西线,반에쓰사이선,#CB7B35,2,,,,,,,,,,,,,0,11226,4093.05313 -11227,2,只見線,タダミセン,只見線,Tadami Line,Tadami Line,只见线,다다미선,#008DD1,2,,,,,,,,,,,,,0,11227,3740.68905 -11228,2,ゆうゆうあぶくまライン,ユウユウアブクマライン,磐越東線,Ban-etsu-East Line,Ban-etsu-East Line,磐越东线,반에쓰토선,#C71585,2,,,,,,,,,,,,,0,11228,5755.65909 -11229,2,常磐線,ジョウバンセン,常磐線,Joban Line,Joban Line,常磐线,조반선,#007AC0,2,JJ,,,,#00B261,,,,SQUARE,,,,0,11229,5575.65688 -11230,2,常磐線,ジョウバンセン,常磐線,Joban Line,Joban Line,常磐线,조반선,#007AC0,2,,,,,,,,,,,,,0,11230,4856.25321 -11301,2,東海道線,トウカイドウセン,東海道本線,Tokaido Line,Tokaido Line,东海道线,도카이도선,#F68B1E,2,JT,,,,#F68B1E,,,,SQUARE,,,,0,11301,5744.02831 -11302,2,山手線,ヤマノテセン,山手線,Yamanote Line,Yamanote Line,山手线,야마노테선,#80C241,2,JY,,,,#80C241,,,,SQUARE,,,,0,11302,1340.15751 +11227,2,只見線,タダミセン,只見線,Tadami Line,Tadami Line,只见线,다다미선,#008DD1,2,,,,,,,,,,,,,0,11227,3796.92669 +11228,2,ゆうゆうあぶくまライン,ユウユウアブクマライン,磐越東線,Ban-etsu-East Line,Ban-etsu-East Line,磐越东线,반에쓰토선,#C71585,2,,,,,,,,,,,,,0,11228,5641.37369 +11229,2,常磐線,ジョウバンセン,常磐線,Joban Line,Joban Line,常磐线,조반선,#007AC0,2,JJ,,,,#00B261,,,,SQUARE,,,,0,11229,5041.85031 +11230,2,常磐線,ジョウバンセン,常磐線,Joban Line,Joban Line,常磐线,조반선,#007AC0,2,,,,,,,,,,,,,0,11230,4422.90225 +11301,2,東海道線,トウカイドウセン,東海道本線,Tokaido Line,Tokaido Line,东海道线,도카이도선,#F68B1E,2,JT,,,,#F68B1E,,,,SQUARE,,,,0,11301,5164.31735 +11302,2,山手線,ヤマノテセン,山手線,Yamanote Line,Yamanote Line,山手线,야마노테선,#80C241,2,JY,,,,#80C241,,,,SQUARE,,,,0,11302,1093.73663 11303,2,南武線,ナンブセン,南武線,Nambu Line,Nambu Line,南武线,난부선,#FFD400,2,JN,,,,#FFD400,,,,SQUARE,,,,0,11303,1476.10425 -11304,2,鶴見線,ツルミセン,鶴見線,Tsurumi Line,Tsurumi Line,鹤见线,쓰루미선,#FFD400,2,JI,,,,#FFD400,,,,SQUARE,,,,0,11304,989.17926 -11305,2,武蔵野線,ムサシノセン,武蔵野線,Musashino Line,Musashino Line,武藏野线,무사시노선,#F15A22,2,JM,,,,#F15A22,,,,SQUARE,,,,0,11305,3257.44731 -11306,2,横浜線,ヨコハマセン,横浜線,Yokohama Line,Yokohama Line,横滨线,요코하마선,#80C241,2,JH,,,,#80C241,,,,SQUARE,,,,0,11306,2435.42939 -11307,2,根岸線,ネギシセン,根岸線,Negishi Line,Negishi Line,根岸线,네기시선,#00B2E5,2,JK,,,,#00B2E5,,,,SQUARE,,,,0,11307,2026.68320 -11308,2,横須賀線,ヨコスカセン,横須賀線,Yokosuka Line,Yokosuka Line,横须贺线,요코스카선,#0067C0,2,JO,,,,#0067C0,,,,SQUARE,,,,0,11308,4991.75349 -11309,2,相模線,サガミセン,相模線,Sagami Line,Sagami Line,相模线,사가미선,#009793,2,,,,,,,,,,,,,0,11309,2120.87426 -11311,2,中央本線,チュウオウホンセン,中央本線,Chuo Line,Chuo Line,中央本线,주오 본선,#007AC0,2,JC,CO,,,#F15A22,#007AC0,,,SQUARE,SQUARE,,,0,11311,4980.49892 -11312,2,中央線(快速),チュウオウセン,中央線(快速),Chuo Line,Chuo Line,中央线,츄오선,#F15A22,2,JC,JB,,,#F15A22,,,,SQUARE,,,,0,11312,1912.79534 -11313,2,中央・総武線,チュウオウ・ソウブセン,中央・総武緩行線,Chuo-Sobu Line,Chuo-Sobu Line,中央・总武线,주오·소부선,#FFD400,2,JB,,,,#FFD400,,,,SQUARE,,,,0,11313,1787.22558 -11314,2,総武本線,ソウブホンセン,総武本線,Sobu Main Line,Sobu Main Line,总武本线,소부 본선,#0067C0,2,JO,,,,#0067C0,,,,SQUARE,,,,0,11314,4429.40110 -11315,2,青梅線,オウメセン,青梅線,Ome Line,Ome Line,青梅线,오메선,#F15A22,2,JC,,,,#F15A22,,,,SQUARE,,,,0,11315,1662.57632 -11316,2,五日市線,イツカイチセン,五日市線,Itsukaichi Line,Itsukaichi Line,五日市线,이쓰카이치선,#F15A22,2,JC,,,,#F15A22,,,,SQUARE,,,,0,11316,2074.97313 -11317,2,八高線,ハチコウセン,八高線,Hachiko Line,Hachiko Line,八高线,하치코선,#A8A39D,2,,,,,,,,,,,,,0,11317,4205.95635 -11318,2,八高線,ハチコウセン,八高線,Hachiko Line,Hachiko Line,八高线,하치코선,#A8A39D,2,,,,,,,,,,,,,0,11318,4584.08167 -11319,2,宇都宮線,ウツノミヤセン,東北本線,Utsunomiya Line,Utsunomiya Line,宇都宫线,우쓰노미야선,#F68B1E,2,JU,,,,#F68B1E,,,,SQUARE,,,,0,11319,5545.35430 -11320,2,常磐快速線,ジョウバンカイソクセン,常磐線,Joban Rapid Line,Joban Rapid Line,常磐快速线,조반 쾌속선,#00B261,2,JJ,JL,,,#00B261,#A2A9B1,,,SQUARE,SQUARE,,,0,11320,2378.87911 -11321,2,埼京線,サイキョウセン,埼京線,Saikyo Line,Saikyo Line,埼京线,사이쿄선,#00B48D,2,JA,,,,#00B48D,,,,SQUARE,,,,0,11321,2673.04874 -11322,2,川越線,カワゴエセン,川越線,Kawagoe Line,Kawagoe Line,川越线,가와고에선,#00B48D,2,JA,,,,#00B48D,,,,SQUARE,,,,0,11322,3734.47187 -11323,2,高崎線,タカサキセン,高崎線,Takasaki Line,Takasaki Line,高崎线,다카사키선,#F68B1E,2,JU,,,,#F68B1E,,,,SQUARE,,,,0,11323,4962.69548 -11324,2,外房線,ソトボウセン,外房線,Sotobo Line,Sotobo Line,外房线,소토보선,#DB4028,2,,,,,,,,,,,,,0,11324,3919.43568 -11325,2,内房線,ウチボウセン,内房線,Uchibo Line,Uchibo Line,内房线,우치보선,#00B9F1,2,,,,,,,,,,,,,0,11325,4276.52807 +11304,2,鶴見線,ツルミセン,鶴見線,Tsurumi Line,Tsurumi Line,鹤见线,쓰루미선,#FFD400,2,JI,,,,#FFD400,,,,SQUARE,,,,0,11304,938.19048 +11305,2,武蔵野線,ムサシノセン,武蔵野線,Musashino Line,Musashino Line,武藏野线,무사시노선,#F15A22,2,JM,,,,#F15A22,,,,SQUARE,,,,0,11305,2846.26108 +11306,2,横浜線,ヨコハマセン,横浜線,Yokohama Line,Yokohama Line,横滨线,요코하마선,#80C241,2,JH,,,,#80C241,,,,SQUARE,,,,0,11306,2198.034 +11307,2,根岸線,ネギシセン,根岸線,Negishi Line,Negishi Line,根岸线,네기시선,#00B2E5,2,JK,,,,#00B2E5,,,,SQUARE,,,,0,11307,1900.95746 +11308,2,横須賀線,ヨコスカセン,横須賀線,Yokosuka Line,Yokosuka Line,横须贺线,요코스카선,#0067C0,2,JO,,,,#0067C0,,,,SQUARE,,,,0,11308,4353.0478 +11309,2,相模線,サガミセン,相模線,Sagami Line,Sagami Line,相模线,사가미선,#009793,2,,,,,,,,,,,,,0,11309,1898.70754 +11311,2,中央本線,チュウオウホンセン,中央本線,Chuo Line,Chuo Line,中央本线,주오 본선,#007AC0,2,JC,CO,,,#F15A22,#007AC0,,,SQUARE,SQUARE,,,0,11311,5007.67526 +11312,2,中央線(快速),チュウオウセン,中央線(快速),Chuo Line,Chuo Line,中央线,츄오선,#F15A22,2,JC,JB,,,#F15A22,,,,SQUARE,,,,0,11312,1691.40943 +11313,2,中央・総武線,チュウオウ・ソウブセン,中央・総武緩行線,Chuo-Sobu Line,Chuo-Sobu Line,中央・总武线,주오·소부선,#FFD400,2,JB,,,,#FFD400,,,,SQUARE,,,,0,11313,1565.82827 +11314,2,総武本線,ソウブホンセン,総武本線,Sobu Main Line,Sobu Main Line,总武本线,소부 본선,#0067C0,2,JO,,,,#0067C0,,,,SQUARE,,,,0,11314,3955.34259 +11315,2,青梅線,オウメセン,青梅線,Ome Line,Ome Line,青梅线,오메선,#F15A22,2,JC,,,,#F15A22,,,,SQUARE,,,,0,11315,1493.49082 +11316,2,五日市線,イツカイチセン,五日市線,Itsukaichi Line,Itsukaichi Line,五日市线,이쓰카이치선,#F15A22,2,JC,,,,#F15A22,,,,SQUARE,,,,0,11316,1820.96922 +11317,2,八高線,ハチコウセン,八高線,Hachiko Line,Hachiko Line,八高线,하치코선,#A8A39D,2,,,,,,,,,,,,,0,11317,3830.46342 +11318,2,八高線,ハチコウセン,八高線,Hachiko Line,Hachiko Line,八高线,하치코선,#A8A39D,2,,,,,,,,,,,,,0,11318,4296.49117 +11319,2,宇都宮線,ウツノミヤセン,東北本線,Utsunomiya Line,Utsunomiya Line,宇都宫线,우쓰노미야선,#F68B1E,2,JU,,,,#F68B1E,,,,SQUARE,,,,0,11319,4937.52562 +11320,2,常磐快速線,ジョウバンカイソクセン,常磐線,Joban Rapid Line,Joban Rapid Line,常磐快速线,조반 쾌속선,#00B261,2,JJ,JL,,,#00B261,#A2A9B1,,,SQUARE,SQUARE,,,0,11320,2164.62731 +11321,2,埼京線,サイキョウセン,埼京線,Saikyo Line,Saikyo Line,埼京线,사이쿄선,#00B48D,2,JA,,,,#00B48D,,,,SQUARE,,,,0,11321,2025.61314 +11322,2,川越線,カワゴエセン,川越線,Kawagoe Line,Kawagoe Line,川越线,가와고에선,#00B48D,2,JA,,,,#00B48D,,,,SQUARE,,,,0,11322,3030.1817 +11323,2,高崎線,タカサキセン,高崎線,Takasaki Line,Takasaki Line,高崎线,다카사키선,#F68B1E,2,JU,,,,#F68B1E,,,,SQUARE,,,,0,11323,4385.72588 +11324,2,外房線,ソトボウセン,外房線,Sotobo Line,Sotobo Line,外房线,소토보선,#DB4028,2,,,,,,,,,,,,,0,11324,3514.60159 +11325,2,内房線,ウチボウセン,内房線,Uchibo Line,Uchibo Line,内房线,우치보선,#00B9F1,2,,,,,,,,,,,,,0,11325,3926.9682 11326,2,京葉線,ケイヨウセン,京葉線,Keiyo Line,Keiyo Line,京叶线,게이요선,#C9242F,2,JE,JM,,,#C9242F,#F15A22,,,SQUARE,SQUARE,,,0,11326,2857.30509 -11327,2,成田線,ナリタセン,成田線,Narita Line,Narita Line,成田线,나리타선,#00B261,2,JO,,,,#007AC0,,,,SQUARE,,,,0,11327,7886.44300 +11327,2,成田線,ナリタセン,成田線,Narita Line,Narita Line,成田线,나리타선,#00B261,2,JO,,,,#007AC0,,,,SQUARE,,,,0,11327,7886.443 11328,2,成田エクスプレス,ナリタエクスプレス,成田エクスプレス,Narita Express,Narita Express,成田特快,나리타 익스프레스,#F61E21,2,,,,,,,,,,,,,3,11328,13509.35879 -11329,2,鹿島線,カシマセン,鹿島線,Kashima Line,Kashima Line,鹿岛线,가시마선,#C56E2E,2,,,,,,,,,,,,,0,11329,3571.26198 -11330,2,久留里線,クルリセン,久留里線,Kururi Line,Kururi Line,久留里线,구루리선,#00B5AD,2,,,,,,,,,,,,,0,11330,2615.56689 -11331,2,東金線,トウガネセン,東金線,Togane Line,Togane Line,东金线,도가네선,#F15A22,2,,,,,,,,,,,,,0,11331,3864.11395 -11332,2,京浜東北線,ケイヒントウホクセン,京浜東北線,Keihin-Tohoku Line,Keihin-Tohoku Line,京滨东北线,게이힌 도호쿠선,#00B2E5,2,JK,,,,#00B2E5,,,,SQUARE,,,,0,11332,1993.48548 -11333,2,湘南新宿ライン,ショウナンシンジュクライン,湘南新宿ライン,Shonan-Shinjuku Line,Shonan-Shinjuku Line,湘南新宿线,쇼난 신주쿠 라인,#F68B1E,2,JS,,,,#E31F26,,,,SQUARE,,,,0,11333,6391.30087 -11343,2,上野東京ライン,ウエノトウキョウライン,上野東京ライン,Ueno-Tokyo Line,Ueno-Tokyo Line,上野东京线,우에노 도쿄 라인,#F68B1E,2,JU,,,,#F68B1E,,,,SQUARE,,,,0,11333,4295.94181 -11334,2,烏山線,カラスヤマセン,烏山線,Karasuyama Line,Karasuyama Line,乌山线,가라스야마선,#008000,2,,,,,,,,,,,,,0,11334,2884.70545 -11335,2,吾妻線,アガツマセン,吾妻線,Agatsuma Line,Agatsuma Line,吾妻线,아가쓰마선,#0F5474,2,,,,,,,,,,,,,0,11335,3429.07012 -11337,2,信越本線,シンエツホンセン,信越本線,Shin’etsu Main Line,Shin’etsu Main Line,信越本线,신에쓰 본선,#9ACD32,2,,,,,,,,,,,,,0,11337,4560.41527 -11338,2,水郡線,スイグンセン,水郡線,Suigun Line,Suigun Line,水郡线,스이군선,#008000,2,,,,,,,,,,,,,0,11338,3667.00130 -11339,2,水戸線,ミトセン,水戸線,Mito Line,Mito Line,水户线,미토선,#3333FF,2,,,,,,,,,,,,,0,11339,3731.72288 -11340,2,日光線,ニッコウセン,日光線,Nikko Line,Nikko Line,日光线,닛코선,#880022,2,,,,,,,,,,,,,0,11340,7486.35541 +11329,2,鹿島線,カシマセン,鹿島線,Kashima Line,Kashima Line,鹿岛线,가시마선,#C56E2E,2,,,,,,,,,,,,,0,11329,3447.19874 +11330,2,久留里線,クルリセン,久留里線,Kururi Line,Kururi Line,久留里线,구루리선,#00B5AD,2,,,,,,,,,,,,,0,11330,2414.17796 +11331,2,東金線,トウガネセン,東金線,Togane Line,Togane Line,东金线,도가네선,#F15A22,2,,,,,,,,,,,,,0,11331,3550.70015 +11332,2,京浜東北線,ケイヒントウホクセン,京浜東北線,Keihin-Tohoku Line,Keihin-Tohoku Line,京滨东北线,게이힌 도호쿠선,#00B2E5,2,JK,,,,#00B2E5,,,,SQUARE,,,,0,11332,1664.92567 +11333,2,湘南新宿ライン,ショウナンシンジュクライン,湘南新宿ライン,Shonan-Shinjuku Line,Shonan-Shinjuku Line,湘南新宿线,쇼난 신주쿠 라인,#F68B1E,2,JS,,,,#E31F26,,,,SQUARE,,,,0,11333,5629.19034 +11343,2,上野東京ライン,ウエノトウキョウライン,上野東京ライン,Ueno-Tokyo Line,Ueno-Tokyo Line,上野东京线,우에노 도쿄 라인,#F68B1E,2,JU,,,,#F68B1E,,,,SQUARE,,,,0,11333,3743.43366 +11334,2,烏山線,カラスヤマセン,烏山線,Karasuyama Line,Karasuyama Line,乌山线,가라스야마선,#008000,2,,,,,,,,,,,,,0,11334,2829.27266 +11335,2,吾妻線,アガツマセン,吾妻線,Agatsuma Line,Agatsuma Line,吾妻线,아가쓰마선,#0F5474,2,,,,,,,,,,,,,0,11335,3177.68477 +11337,2,信越本線,シンエツホンセン,信越本線,Shin’etsu Main Line,Shin’etsu Main Line,信越本线,신에쓰 본선,#9ACD32,2,,,,,,,,,,,,,0,11337,4071.18638 +11338,2,水郡線,スイグンセン,水郡線,Suigun Line,Suigun Line,水郡线,스이군선,#008000,2,,,,,,,,,,,,,0,11338,3667.0013 +11339,2,水戸線,ミトセン,水戸線,Mito Line,Mito Line,水户线,미토선,#3333FF,2,,,,,,,,,,,,,0,11339,3317.11634 +11340,2,日光線,ニッコウセン,日光線,Nikko Line,Nikko Line,日光线,닛코선,#880022,2,,,,,,,,,,,,,0,11340,6702.69079 11341,2,両毛線,リョウモウセン,両毛線,Ryomo Line,Ryomo Line,两毛线,료모선,#FFD400,2,,,,,,,,,,,,,0,11341,4866.83608 -11342,2,上越線,ジョウエツセン,上越線,Joetsu Line,Joetsu Line,上越线,조에쓰선,#00B3E6,2,,,,,,,,,,,,,0,11342,4871.49620 -11344,2,常磐線,ジョウバンセン,常磐線(緩行線),Joban Line,Joban Line,常磐线,조반선,#A2A9B1,2,JL,,,,#A2A9B1,,,,SQUARE,,,,0,11345,2535.69465 -11345,100,ディズニーリゾートライン,ディズニーリゾートライン,ディズニーリゾートライン,Disney Resort Line,Disney Resort Line,迪士尼度假区线,디즈니 리조트 라인,#004499,5,,,,,,,,,,,,,0,11343,1087.75721 -11401,2,小海線,コウミセン,小海線,Koumi Line,Koumi Line,小海线,고우미선,#008000,2,,,,,,,,,,,,,0,11401,2573.34299 -11402,3,身延線,ミノブセン,身延線,Minobu Line,Minobu Line,身延线,미노부선,#6F2D98,2,CC,,,,#6F2D98,,,,HALF_SQUARE_WITHOUT_ROUND,,,,0,11402,2438.67983 -11403,2,信越本線,シンエツホンセン,信越本線,Shin’etsu Main Line,Shin’etsu Main Line,信越本线,신에쓰 본선,#00B3E6,2,SE,,,,#00B3E6,,,,SQUARE,,,,0,11403,2632.98923 -11404,2,信越本線,シンエツホンセン,信越本線,Shin’etsu Main Line,Shin’etsu Main Line,信越本线,신에쓰 본선,#00B3E6,2,,,,,,,,,,,,,0,11404,3690.56278 +11342,2,上越線,ジョウエツセン,上越線,Joetsu Line,Joetsu Line,上越线,조에쓰선,#00B3E6,2,,,,,,,,,,,,,0,11342,4871.4962 +11344,2,常磐線,ジョウバンセン,常磐線(緩行線),Joban Line,Joban Line,常磐线,조반선,#A2A9B1,2,JL,,,,#A2A9B1,,,,SQUARE,,,,0,11345,2263.86009 +11345,100,ディズニーリゾートライン,ディズニーリゾートライン,ディズニーリゾートライン,Disney Resort Line,Disney Resort Line,迪士尼度假区线,디즈니 리조트 라인,#004499,5,,,,,,,,,,,,,0,11343,1389.03537 +11401,2,小海線,コウミセン,小海線,Koumi Line,Koumi Line,小海线,고우미선,#008000,2,,,,,,,,,,,,,0,11401,2560.68727 +11402,3,身延線,ミノブセン,身延線,Minobu Line,Minobu Line,身延线,미노부선,#6F2D98,2,CC,,,,#6F2D98,,,,HALF_SQUARE_WITHOUT_ROUND,,,,0,11402,2271.65832 +11403,2,信越本線,シンエツホンセン,信越本線,Shin’etsu Main Line,Shin’etsu Main Line,信越本线,신에쓰 본선,#00B3E6,2,SE,,,,#00B3E6,,,,SQUARE,,,,0,11403,2304.32432 +11404,2,信越本線,シンエツホンセン,信越本線,Shin’etsu Main Line,Shin’etsu Main Line,信越本线,신에쓰 본선,#00B3E6,2,,,,,,,,,,,,,0,11404,3296.32902 11405,4,北陸本線,ホクリクホンセン,北陸本線,Hokuriku Main Line,Hokuriku Main Line,北陆本线,호쿠리쿠 본선,#FFD400,2,,,,,,,,,,,,,2,11405,0 -11406,2,白新線,ハクシンセン,白新線,Hakushin Line,Hakushin Line,白新线,하쿠신선,#F387B7,2,,,,,,,,,,,,,0,11406,3269.33853 +11406,2,白新線,ハクシンセン,白新線,Hakushin Line,Hakushin Line,白新线,하쿠신선,#F387B7,2,,,,,,,,,,,,,0,11406,2999.90473 11407,2,飯山線,イイヤマセン,飯山線,Iiyama Line,Iiyama Line,饭山线,이야마선,#7BC24B,2,,,,,,,,,,,,,0,11407,3491.78175 -11408,2,越後線,エチゴセン,越後線,Echigo Line,Echigo Line,越后线,에치고선,#40934D,2,,,,,,,,,,,,,0,11408,2914.84705 -11409,2,北アルプス線,キタアルプスセン,大糸線,Oito Line,Oito Line,大糸线,오이토선,#9370DB,2,,,,,,,,,,,,,0,11409,2763.85070 -11410,2,弥彦線,ヤヒコセン,弥彦線,Yahiko Line,Yahiko Line,弥彦线,야히코선,#922790,2,,,,,,,,,,,,,0,11410,2565.99081 -11411,3,中央本線,チュウオウホンセン,中央本線,Chuo Line,Chuo Line,中央线,주오선,#307097,2,CF,,,,#307097,,,,HALF_SQUARE_WITHOUT_ROUND,,,,0,11411,4767.38469 -11412,2,篠ノ井線,シノノイセン,篠ノ井線,Shinonoi Line,Shinonoi Line,篠之井线,시노노이선,#F15A22,2,SN,,,,#F15A22,,,,SQUARE,,,,0,11412,5025.32797 -11413,3,飯田線,イイダセン,飯田線,Iida Line,Iida Line,饭田线,이다선,#6CA2D6,2,CD,,,,#6CA2D6,,,,HALF_SQUARE_WITHOUT_ROUND,,,,0,11413,2448.69667 -11414,3,飯田線,イイダセン,飯田線,Iida Line,Iida Line,饭田线,이다선,#6CA2D6,2,CD,,,,#6CA2D6,,,,HALF_SQUARE_WITHOUT_ROUND,,,,0,11414,1923.12799 -11415,4,北陸本線,ホクリクホンセン,北陸本線,Hokuriku Main Line,Hokuriku Main Line,北陆本线,호쿠리쿠 본선,#D60000,2,A,B,,,#0072BC,#00ACD1,,,REVERSED_SQUARE_WEST,REVERSED_SQUARE_WEST,,,0,11415,4605.36735 -11416,3,高山本線,タカヤマホンセン,高山本線,Takayama Line,Takayama Line,高山线,다카야마선,#9E1311,2,CG,,,,#9E1311,,,,HALF_SQUARE_WITHOUT_ROUND,,,,0,11416,5103.14080 -11417,4,城端線,ジョウハナセン,城端線,Johana Line,Johana Line,城端线,조하나선,#846AA8,2,,,,,,,,,,,,,0,11417,2692.70049 -11418,4,氷見線,ヒミセン,氷見線,Himi Line,Himi Line,冰见线,히미선,#A646A6,2,,,,,,,,,,,,,0,11418,2619.04272 +11408,2,越後線,エチゴセン,越後線,Echigo Line,Echigo Line,越后线,에치고선,#40934D,2,,,,,,,,,,,,,0,11408,2582.39854 +11409,2,北アルプス線,キタアルプスセン,大糸線,Oito Line,Oito Line,大糸线,오이토선,#9370DB,2,,,,,,,,,,,,,0,11409,2603.83354 +11410,2,弥彦線,ヤヒコセン,弥彦線,Yahiko Line,Yahiko Line,弥彦线,야히코선,#922790,2,,,,,,,,,,,,,0,11410,2414.18702 +11411,3,中央本線,チュウオウホンセン,中央本線,Chuo Line,Chuo Line,中央线,주오선,#307097,2,CF,,,,#307097,,,,HALF_SQUARE_WITHOUT_ROUND,,,,0,11411,4390.25074 +11412,2,篠ノ井線,シノノイセン,篠ノ井線,Shinonoi Line,Shinonoi Line,篠之井线,시노노이선,#F15A22,2,SN,,,,#F15A22,,,,SQUARE,,,,0,11412,4698.86967 +11413,3,飯田線,イイダセン,飯田線,Iida Line,Iida Line,饭田线,이다선,#6CA2D6,2,CD,,,,#6CA2D6,,,,HALF_SQUARE_WITHOUT_ROUND,,,,0,11413,2262.93207 +11414,3,飯田線,イイダセン,飯田線,Iida Line,Iida Line,饭田线,이다선,#6CA2D6,2,CD,,,,#6CA2D6,,,,HALF_SQUARE_WITHOUT_ROUND,,,,0,11414,1794.88663 +11415,4,北陸本線,ホクリクホンセン,北陸本線,Hokuriku Main Line,Hokuriku Main Line,北陆本线,호쿠리쿠 본선,#D60000,2,A,B,,,#0072BC,#00ACD1,,,REVERSED_SQUARE_WEST,REVERSED_SQUARE_WEST,,,0,11415,4185.95216 +11416,3,高山本線,タカヤマホンセン,高山本線,Takayama Line,Takayama Line,高山线,다카야마선,#9E1311,2,CG,,,,#9E1311,,,,HALF_SQUARE_WITHOUT_ROUND,,,,0,11416,5090.65477 +11417,4,城端線,ジョウハナセン,城端線,Johana Line,Johana Line,城端线,조하나선,#846AA8,2,,,,,,,,,,,,,0,11417,2260.30908 +11418,4,氷見線,ヒミセン,氷見線,Himi Line,Himi Line,冰见线,히미선,#A646A6,2,,,,,,,,,,,,,0,11418,2309.26031 11419,4,七尾線,ナナオセン,七尾線,Nanao Line,Nanao Line,七尾线,나나오선,#1DA5BD,2,,,,,,,,,,,,,0,11419,3502.62168 11420,4,敦賀港線,ツルガコウセン,北陸本線,Tsurugaminato Line,Tsurugaminato Line,敦贺港线,츠루가미나토선,#FFCC00,2,,,,,,,,,,,,,2,11420,2396.90408 -11421,4,九頭竜線,クズリュウセン,越美北線,Kuzuryu Line,Kuzuryu Line,九头龙线,구즈류선,#3C9922,2,,,,,,,,,,,,,0,11421,2643.27015 -11422,4,小浜線,オバマセン,小浜線,Obama Line,Obama Line,小滨线,오바마선,#0072BC,2,,,,,,,,,,,,,0,11422,3860.72801 -11501,3,東海道本線,トウカイドウホンセン,東海道本線,Tokaido Line,Tokaido Line,东海道线,도카이도선,#F47921,2,CA,,,,#F47921,,,,HALF_SQUARE_WITHOUT_ROUND,,,,0,11501,5234.74872 -11502,3,東海道本線,トウカイドウホンセン,東海道本線,Tokaido Line,Tokaido Line,东海道线,도카이도선,#F47921,2,CA,,,,#F47921,,,,HALF_SQUARE_WITHOUT_ROUND,,,,0,11502,4316.48787 +11421,4,九頭竜線,クズリュウセン,越美北線,Kuzuryu Line,Kuzuryu Line,九头龙线,구즈류선,#3C9922,2,,,,,,,,,,,,,0,11421,2465.1632 +11422,4,小浜線,オバマセン,小浜線,Obama Line,Obama Line,小滨线,오바마선,#0072BC,2,,,,,,,,,,,,,0,11422,3616.65186 +11501,3,東海道本線,トウカイドウホンセン,東海道本線,Tokaido Line,Tokaido Line,东海道线,도카이도선,#F47921,2,CA,,,,#F47921,,,,HALF_SQUARE_WITHOUT_ROUND,,,,0,11501,4441.12478 +11502,3,東海道本線,トウカイドウホンセン,東海道本線,Tokaido Line,Tokaido Line,东海道线,도카이도선,#F47921,2,CA,,,,#F47921,,,,HALF_SQUARE_WITHOUT_ROUND,,,,0,11502,3454.94389 11503,3,東海道本線,トウカイドウホンセン,東海道本線,Tokaido Line,Tokaido Line,东海道线,도카이도선,#F47921,2,CA,,,,#F47921,,,,HALF_SQUARE_WITHOUT_ROUND,,,,0,11503,5008.52863 -11504,2,伊東線,イトウセン,伊東線,Ito Line,Ito Line,伊东线,이토선,#F68B1E,2,JT,,,,#F68B1E,,,,SQUARE,,,,0,11504,3595.69108 -11505,3,御殿場線,ゴテンバセン,御殿場線,Gotemba Line,Gotemba Line,御殿场线,고텐바선,#447442,2,CB,,,,#447442,,,,HALF_SQUARE_WITHOUT_ROUND,,,,0,11505,3569.47340 -11506,3,武豊線,タケトヨセン,武豊線,Taketoyo Line,Taketoyo Line,武丰线,다케토요선,#83502F,2,CE,,,,#83502F,,,,HALF_SQUARE_WITHOUT_ROUND,,,,0,11506,2405.46128 -11507,3,太多線,タイタセン,太多線,Taita Line,Taita Line,太多线,다이타선,#C7B944,2,CI,,,,#C7B944,,,,HALF_SQUARE_WITHOUT_ROUND,,,,0,11507,2726.01350 -11508,3,関西本線,カンサイホンセン,関西本線,Kansai Line,Kansai Line,关西线,간사이선,#0FB68F,2,CJ,,,,#0FB68F,,,,HALF_SQUARE_WITHOUT_ROUND,,,,0,11508,3882.23804 -11509,4,関西本線,カンサイホンセン,関西本線,Kansai Main Line,Kansai Main Line,关西本线,간사이 본선,#0FB68F,2,,,,,,,,,,,,,0,11509,5813.80513 -11510,3,紀勢本線,キセイホンセン,紀勢本線,Kisei Line,Kisei Line,纪势线,기세이선,#F80039,2,,,,,,,,,,,,,0,11510,4501.37525 -11511,4,草津線,クサツセン,草津線,Kusatsu Line,Kusatsu Line,草津线,구사쓰선,#CBCF10,2,C,,,,#CBCF10,,,,REVERSED_SQUARE_WEST,,,,0,11511,4069.24438 -11512,3,参宮線,サングウセン,参宮線,Sangu Line,Sangu Line,参宫线,산구선,#4D2E8C,2,,,,,,,,,,,,,0,11512,3083.14590 -11513,3,名松線,メイショウセン,名松線,Meisho Line,Meisho Line,名松线,메이쇼선,#E9E343,2,,,,,,,,,,,,,0,11513,3227.46408 -11601,4,琵琶湖線,ビワコセン,東海道本線,Biwako Line,Biwako Line,琵琶湖线,비와코선,#0072BC,2,A,,,,#0072BC,,,,REVERSED_SQUARE_WEST,,,,0,11601,4028.65201 -11602,4,JR京都線,ジェーアールキョウトセン,東海道本線,Kyoto Line,Kyoto Line,京都线,교토선,#0072BC,2,A,,,,#0072BC,,,,REVERSED_SQUARE_WEST,,,,0,11602,3869.28769 -11603,4,JR神戸線,ジェーアールコウベセン,東海道本線,Kobe Line,Kobe Line,神户线,고베선,#0072BC,2,A,,,,#0072BC,,,,REVERSED_SQUARE_WEST,,,,0,11603,2711.44664 -11605,4,湖西線,コセイセン,湖西線,Kosei Line,Kosei Line,湖西线,고세이선,#576290,2,B,,,,#00ACD1,,,,REVERSED_SQUARE_WEST,,,,0,11605,4214.12406 -11607,4,大和路線,ヤマトジセン,関西本線,Yamatoji Line,Yamatoji Line,大和路线,야마토지선,#009933,2,Q,,,,#009933,,,,REVERSED_SQUARE_WEST,,,,0,11607,2780.43249 -11608,4,JR神戸線,ジェーアールコウベセン,山陽本線,Kobe Line,Kobe Line,神户线,고베선,#0072BC,2,A,,,,#0072BC,,,,REVERSED_SQUARE_WEST,,,,0,11608,3164.34054 -11609,4,山陽本線,サンヨウホンセン,山陽本線,San’yo Main Line,San’yo Main Line,山阳本线,산요 본선,#0072BC,2,A,S,,,#0072BC,#C1D612,,,REVERSED_SQUARE_WEST,REVERSED_SQUARE_WEST,,,0,11609,5630.49753 +11504,2,伊東線,イトウセン,伊東線,Ito Line,Ito Line,伊东线,이토선,#F68B1E,2,JT,,,,#F68B1E,,,,SQUARE,,,,0,11504,3293.87447 +11505,3,御殿場線,ゴテンバセン,御殿場線,Gotemba Line,Gotemba Line,御殿场线,고텐바선,#447442,2,CB,,,,#447442,,,,HALF_SQUARE_WITHOUT_ROUND,,,,0,11505,3314.26909 +11506,3,武豊線,タケトヨセン,武豊線,Taketoyo Line,Taketoyo Line,武丰线,다케토요선,#83502F,2,CE,,,,#83502F,,,,HALF_SQUARE_WITHOUT_ROUND,,,,0,11506,2143.85534 +11507,3,太多線,タイタセン,太多線,Taita Line,Taita Line,太多线,다이타선,#C7B944,2,CI,,,,#C7B944,,,,HALF_SQUARE_WITHOUT_ROUND,,,,0,11507,2485.52984 +11508,3,関西本線,カンサイホンセン,関西本線,Kansai Line,Kansai Line,关西线,간사이선,#0FB68F,2,CJ,,,,#0FB68F,,,,HALF_SQUARE_WITHOUT_ROUND,,,,0,11508,3521.88653 +11509,4,関西本線,カンサイホンセン,関西本線,Kansai Main Line,Kansai Main Line,关西本线,간사이 본선,#0FB68F,2,,,,,,,,,,,,,0,11509,5496.62858 +11510,3,紀勢本線,キセイホンセン,紀勢本線,Kisei Line,Kisei Line,纪势线,기세이선,#F80039,2,,,,,,,,,,,,,0,11510,4447.92245 +11511,4,草津線,クサツセン,草津線,Kusatsu Line,Kusatsu Line,草津线,구사쓰선,#CBCF10,2,C,,,,#CBCF10,,,,REVERSED_SQUARE_WEST,,,,0,11511,3617.10434 +11512,3,参宮線,サングウセン,参宮線,Sangu Line,Sangu Line,参宫线,산구선,#4D2E8C,2,,,,,,,,,,,,,0,11512,3162.76386 +11513,3,名松線,メイショウセン,名松線,Meisho Line,Meisho Line,名松线,메이쇼선,#E9E343,2,,,,,,,,,,,,,0,11513,3061.97516 +11601,4,琵琶湖線,ビワコセン,東海道本線,Biwako Line,Biwako Line,琵琶湖线,비와코선,#0072BC,2,A,,,,#0072BC,,,,REVERSED_SQUARE_WEST,,,,0,11601,3579.96107 +11602,4,JR京都線,ジェーアールキョウトセン,東海道本線,Kyoto Line,Kyoto Line,京都线,교토선,#0072BC,2,A,,,,#0072BC,,,,REVERSED_SQUARE_WEST,,,,0,11602,2641.99124 +11603,4,JR神戸線,ジェーアールコウベセン,東海道本線,Kobe Line,Kobe Line,神户线,고베선,#0072BC,2,A,,,,#0072BC,,,,REVERSED_SQUARE_WEST,,,,0,11603,2043.28501 +11605,4,湖西線,コセイセン,湖西線,Kosei Line,Kosei Line,湖西线,고세이선,#576290,2,B,,,,#00ACD1,,,,REVERSED_SQUARE_WEST,,,,0,11605,3797.95505 +11607,4,大和路線,ヤマトジセン,関西本線,Yamatoji Line,Yamatoji Line,大和路线,야마토지선,#009933,2,Q,,,,#009933,,,,REVERSED_SQUARE_WEST,,,,0,11607,2531.18147 +11608,4,JR神戸線,ジェーアールコウベセン,山陽本線,Kobe Line,Kobe Line,神户线,고베선,#0072BC,2,A,,,,#0072BC,,,,REVERSED_SQUARE_WEST,,,,0,11608,2474.54823 +11609,4,山陽本線,サンヨウホンセン,山陽本線,San’yo Main Line,San’yo Main Line,山阳本线,산요 본선,#0072BC,2,A,S,,,#0072BC,#C1D612,,,REVERSED_SQUARE_WEST,REVERSED_SQUARE_WEST,,,0,11609,4947.12435 11610,4,山陽本線,サンヨウホンセン,山陽本線,San’yo Main Line,San’yo Main Line,山阳本线,산요 본선,#0072BC,2,W,X,,,#F5A200,#00A0E9,,,REVERSED_SQUARE_WEST,REVERSED_SQUARE_WEST,,,0,11610,5100.06466 -11611,4,山陽本線,サンヨウホンセン,山陽本線,San’yo Main Line,San’yo Main Line,山阳本线,산요 본선,#0072BC,2,G,R,,,#60AD3B,#CB342E,,,REVERSED_SQUARE_WEST,REVERSED_SQUARE_WEST,,,0,11611,4223.01203 +11611,4,山陽本線,サンヨウホンセン,山陽本線,San’yo Main Line,San’yo Main Line,山阳本线,산요 본선,#0072BC,2,G,R,,,#60AD3B,#CB342E,,,REVERSED_SQUARE_WEST,REVERSED_SQUARE_WEST,,,0,11611,3949.01628 11612,4,山陽本線,サンヨウホンセン,山陽本線,San'yo Main Line,San'yo Main Line,山阳本线,산요 본선,#0072BC,2,JA,,,,#E24148,,,,HALF_SQUARE,,,,0,11612,5412.42792 -11613,4,山陽本線,サンヨウホンセン,山陽本線,San’yo Main Line,San’yo Main Line,山阳本线,산요 본선,#0072BC,2,,,,,,,,,,,,,0,11613,1735.93807 -11614,4,嵯峨野線,サガノセン,山陰本線,Sagano Line,Sagano Line,嵯峨野线,사가노선,#9370DB,2,E,,,,#9370DB,,,,REVERSED_SQUARE_WEST,,,,0,11614,2571.13740 -11615,4,山陰本線,サンインホンセン,山陰本線,San'in Main Line,San'in Main Line,山阴本线,산인 본선,#669933,2,E,,,,#669933,,,,REVERSED_SQUARE_WEST,,,,0,11615,5110.28997 -11616,4,山陰本線,サンインホンセン,山陰本線,San’in Main Line,San’in Main Line,山阴本线,산인 본선,#669933,2,A,,,,#669933,,,,REVERSED_SQUARE_WEST,,,,0,11616,4485.87069 -11617,4,学研都市線,ガッケントシセン,片町線,Gakkentoshi Line,Gakkentoshi Line,学研都市线,갓켄토시선,#9ACD32,2,H,,,,#FF1493,,,,REVERSED_SQUARE_WEST,,,,0,11617,2117.49832 -11618,4,奈良線,ナラセン,奈良線,Nara Line,Nara Line,奈良线,나라선,#A52A2A,2,D,,,,#A52A2A,,,,REVERSED_SQUARE_WEST,,,,0,11618,2278.43784 -11622,4,舞鶴線,マイヅルセン,舞鶴線,Maizuru Line,Maizuru Line,舞鹤线,마이즈루선,#7BA1C5,2,L,,,,#7BA1C5,,,,REVERSED_SQUARE_WEST,,,,0,11622,5287.92160 -11623,4,大阪環状線,オオサカカンジョウセン,大阪環状線,Osaka Loop Line,Osaka Loop Line,大阪环状线,오사카 순환선,#FF0000,2,O,,,,#FF0000,,,,REVERSED_SQUARE_WEST,,,,0,11623,1270.61353 -11624,4,JRゆめ咲線,ジェーアールユメサキセン,桜島線,Yumesaki Line,Yumesaki Line,梦咲线,유메사키선,#0A318E,2,P,,,,#0A318E,,,,REVERSED_SQUARE_WEST,,,,0,11624,1530.40987 -11625,4,JR東西線,ジェーアールトウザイセン,JR東西線,Tozai Line,Tozai Line,东西线,도자이선,#FF1493,2,H,,,,#FF1493,,,,REVERSED_SQUARE_WEST,,,,0,11625,1722.98291 -11626,4,阪和線,ハンワセン,阪和線,Hanwa Line,Hanwa Line,阪和线,한와선,#FF6600,2,R,,,,#FF9600,,,,REVERSED_SQUARE_WEST_DARK_TEXT,,,,0,11626,1996.18356 -11627,4,羽衣線,ハゴロモセン,阪和線,Hagoromo Line,Hagoromo Line,羽衣线,하고로모선,#FF6600,2,,,,,,,,,,,,,0,11627,1730.03390 -11628,4,関西空港線,カンサイクウコウセン,関西空港線,Kansai Airport Line,Kansai Airport Line,关西机场线,간사이 공항선,#0000FF,2,S,,,,#0000FF,,,,REVERSED_SQUARE_WEST,,,,0,11628,5478.53630 -11629,4,JR宝塚線,ジェーアールタカラヅカセン,福知山線,Takarazuka Line,Takarazuka Line,宝冢线,다카라즈카선,#FFCC00,2,G,A,,,#FFBA00,#0072BC,,,REVERSED_SQUARE_WEST_DARK_TEXT,REVERSED_SQUARE_WEST,,,0,11629,3366.23528 -11630,4,福知山線,フクチヤマセン,福知山線,Fukuchiyama Line,Fukuchiyama Line,福知山线,후쿠치야마선,#FFCC00,2,G,,,,#FFBA00,,,,REVERSED_SQUARE_WEST_DARK_TEXT,,,,0,11630,5172.98145 -11631,4,赤穂線,アコウセン,赤穂線,Ako Line,Ako Line,赤穗线,아코선,#F16369,2,N,A,,,#F16369,#0072BC,,,REVERSED_SQUARE_WEST,REVERSED_SQUARE_WEST,,,0,11631,3550.28228 -11632,4,加古川線,カコガワセン,加古川線,Kakogawa Line,Kakogawa Line,加古川线,가코가와선,#3CB371,2,I,,,,#3CB371,,,,REVERSED_SQUARE_WEST,,,,0,11632,2630.78157 -11633,4,姫新線,キシンセン,姫新線,Kishin Line,Kishin Line,姬新线,기신선,#FF4500,2,K,,,,#FF4500,,,,REVERSED_SQUARE_WEST,,,,0,11633,4229.87959 -11634,4,姫新線,キシンセン,姫新線,Kishin Line,Kishin Line,姬新线,기신선,#800080,2,K,,,,#800080,,,,REVERSED_SQUARE_WEST,,,,0,11634,4729.71930 -11635,4,播但線,バンタンセン,播但線,Bantan Line,Bantan Line,播但线,반탄선,#A52A2A,2,J,,,,#A52A2A,,,,REVERSED_SQUARE_WEST,,,,0,11635,4158.03372 -11636,4,和歌山線,ワカヤマセン,和歌山線,Wakayama Line,Wakayama Line,和歌山线,와카야마선,#192375,2,T,,,,#192375,,,,REVERSED_SQUARE_WEST,,,,0,11636,2682.82338 -11637,4,万葉まほろば線,マンヨウマホロバセン,桜井線,Manyo Mahoroba Line,Manyo Mahoroba Line,万叶Mahoroba线,사쿠라이선,#EC64AB,2,U,,,,#EC64AB,,,,REVERSED_SQUARE_WEST,,,,0,11637,2529.86423 -11639,4,きのくに線,キノクニセン,紀勢本線,Kinokuni Line,Kinokuni Line,纪国线,기노쿠니선,#FE8525,2,W,,,,#FE8525,,,,REVERSED_SQUARE_WEST,,,,0,11639,3793.36167 -11640,4,紀勢本線,キセイホンセン,紀勢本線,Kisei Main Line,Kisei Main Line,纪势本线,기세이 본선,#192375,2,,,,,,,,,,,,,0,11640,1654.08410 -11641,4,おおさか東線,オオサカヒガシセン,おおさか東線,Osaka Higashi Line,Osaka Higashi Line,大阪东线,오사카히가시선,#347293,2,F,,,,#347293,,,,REVERSED_SQUARE_WEST,,,,0,11641,1891.98197 -11701,4,山陰本線,サンインホンセン,山陰本線,San’in Main Line,San’in Main Line,山阴本线,산인 본선,#BAE541,2,,,,,,,,,,,,,0,11701,4537.68671 -11702,4,山陰本線,サンインホンセン,山陰本線,San’in Main Line,San’in Main Line,山阴本线,산인 본선,#BAE541,2,,,,,,,,,,,,,0,11702,4503.25270 +11613,4,山陽本線,サンヨウホンセン,山陽本線,San’yo Main Line,San’yo Main Line,山阳本线,산요 본선,#0072BC,2,,,,,,,,,,,,,0,11613,2142.977 +11614,4,嵯峨野線,サガノセン,山陰本線,Sagano Line,Sagano Line,嵯峨野线,사가노선,#9370DB,2,E,,,,#9370DB,,,,REVERSED_SQUARE_WEST,,,,0,11614,2226.44077 +11615,4,山陰本線,サンインホンセン,山陰本線,San'in Main Line,San'in Main Line,山阴本线,산인 본선,#669933,2,E,,,,#669933,,,,REVERSED_SQUARE_WEST,,,,0,11615,4894.43373 +11616,4,山陰本線,サンインホンセン,山陰本線,San’in Main Line,San’in Main Line,山阴本线,산인 본선,#669933,2,A,,,,#669933,,,,REVERSED_SQUARE_WEST,,,,0,11616,4389.45253 +11617,4,学研都市線,ガッケントシセン,片町線,Gakkentoshi Line,Gakkentoshi Line,学研都市线,갓켄토시선,#9ACD32,2,H,,,,#FF1493,,,,REVERSED_SQUARE_WEST,,,,0,11617,1900.74518 +11618,4,奈良線,ナラセン,奈良線,Nara Line,Nara Line,奈良线,나라선,#A52A2A,2,D,,,,#A52A2A,,,,REVERSED_SQUARE_WEST,,,,0,11618,2052.89697 +11622,4,舞鶴線,マイヅルセン,舞鶴線,Maizuru Line,Maizuru Line,舞鹤线,마이즈루선,#7BA1C5,2,L,,,,#7BA1C5,,,,REVERSED_SQUARE_WEST,,,,0,11622,5287.9216 +11623,4,大阪環状線,オオサカカンジョウセン,大阪環状線,Osaka Loop Line,Osaka Loop Line,大阪环状线,오사카 순환선,#FF0000,2,O,,,,#FF0000,,,,REVERSED_SQUARE_WEST,,,,0,11623,1128.80239 +11624,4,JRゆめ咲線,ジェーアールユメサキセン,桜島線,Yumesaki Line,Yumesaki Line,梦咲线,유메사키선,#0A318E,2,P,,,,#0A318E,,,,REVERSED_SQUARE_WEST,,,,0,11624,1373.1323 +11625,4,JR東西線,ジェーアールトウザイセン,JR東西線,Tozai Line,Tozai Line,东西线,도자이선,#FF1493,2,H,,,,#FF1493,,,,REVERSED_SQUARE_WEST,,,,0,11625,1505.55763 +11626,4,阪和線,ハンワセン,阪和線,Hanwa Line,Hanwa Line,阪和线,한와선,#FF6600,2,R,,,,#FF9600,,,,REVERSED_SQUARE_WEST_DARK_TEXT,,,,0,11626,1787.64739 +11627,4,羽衣線,ハゴロモセン,阪和線,Hagoromo Line,Hagoromo Line,羽衣线,하고로모선,#FF6600,2,,,,,,,,,,,,,0,11627,1504.3773 +11628,4,関西空港線,カンサイクウコウセン,関西空港線,Kansai Airport Line,Kansai Airport Line,关西机场线,간사이 공항선,#0000FF,2,S,,,,#0000FF,,,,REVERSED_SQUARE_WEST,,,,0,11628,5508.17333 +11629,4,JR宝塚線,ジェーアールタカラヅカセン,福知山線,Takarazuka Line,Takarazuka Line,宝冢线,다카라즈카선,#FFCC00,2,G,A,,,#FFBA00,#0072BC,,,REVERSED_SQUARE_WEST_DARK_TEXT,REVERSED_SQUARE_WEST,,,0,11629,2976.25397 +11630,4,福知山線,フクチヤマセン,福知山線,Fukuchiyama Line,Fukuchiyama Line,福知山线,후쿠치야마선,#FFCC00,2,G,,,,#FFBA00,,,,REVERSED_SQUARE_WEST_DARK_TEXT,,,,0,11630,5310.44885 +11631,4,赤穂線,アコウセン,赤穂線,Ako Line,Ako Line,赤穗线,아코선,#F16369,2,N,A,,,#F16369,#0072BC,,,REVERSED_SQUARE_WEST,REVERSED_SQUARE_WEST,,,0,11631,3334.25758 +11632,4,加古川線,カコガワセン,加古川線,Kakogawa Line,Kakogawa Line,加古川线,가코가와선,#3CB371,2,I,,,,#3CB371,,,,REVERSED_SQUARE_WEST,,,,0,11632,2371.85478 +11633,4,姫新線,キシンセン,姫新線,Kishin Line,Kishin Line,姬新线,기신선,#FF4500,2,K,,,,#FF4500,,,,REVERSED_SQUARE_WEST,,,,0,11633,4101.68686 +11634,4,姫新線,キシンセン,姫新線,Kishin Line,Kishin Line,姬新线,기신선,#800080,2,K,,,,#800080,,,,REVERSED_SQUARE_WEST,,,,0,11634,4608.22042 +11635,4,播但線,バンタンセン,播但線,Bantan Line,Bantan Line,播但线,반탄선,#A52A2A,2,J,,,,#A52A2A,,,,REVERSED_SQUARE_WEST,,,,0,11635,3834.08915 +11636,4,和歌山線,ワカヤマセン,和歌山線,Wakayama Line,Wakayama Line,和歌山线,와카야마선,#192375,2,T,,,,#192375,,,,REVERSED_SQUARE_WEST,,,,0,11636,2467.63838 +11637,4,万葉まほろば線,マンヨウマホロバセン,桜井線,Manyo Mahoroba Line,Manyo Mahoroba Line,万叶Mahoroba线,사쿠라이선,#EC64AB,2,U,,,,#EC64AB,,,,REVERSED_SQUARE_WEST,,,,0,11637,2220.88784 +11639,4,きのくに線,キノクニセン,紀勢本線,Kinokuni Line,Kinokuni Line,纪国线,기노쿠니선,#FE8525,2,W,,,,#FE8525,,,,REVERSED_SQUARE_WEST,,,,0,11639,3666.53002 +11640,4,紀勢本線,キセイホンセン,紀勢本線,Kisei Main Line,Kisei Main Line,纪势本线,기세이 본선,#192375,2,,,,,,,,,,,,,0,11640,1595.33951 +11641,4,おおさか東線,オオサカヒガシセン,おおさか東線,Osaka Higashi Line,Osaka Higashi Line,大阪东线,오사카히가시선,#347293,2,F,,,,#347293,,,,REVERSED_SQUARE_WEST,,,,0,11641,1703.58445 +11701,4,山陰本線,サンインホンセン,山陰本線,San’in Main Line,San’in Main Line,山阴本线,산인 본선,#BAE541,2,,,,,,,,,,,,,0,11701,4298.59562 +11702,4,山陰本線,サンインホンセン,山陰本線,San’in Main Line,San’in Main Line,山阴本线,산인 본선,#BAE541,2,,,,,,,,,,,,,0,11702,4464.27402 11703,4,伯備線,ハクビセン,伯備線,Hakubi Line,Hakubi Line,伯备线,하쿠비선,#FF4500,2,,,,,,,,,,,,,0,11703,5078.99477 11704,4,因美線,インビセン,因美線,Inbi Line,Inbi Line,因美线,인비선,#AA731C,2,B,,,,#AA731C,,,,REVERSED_SQUARE_WEST,,,,0,11704,4056.91816 -11705,4,境線,サカイセン,境線,Sakai Line,Sakai Line,境线,사카이선,#00FFFF,2,C,,,,#00FFFF,,,,REVERSED_SQUARE_WEST,,,,0,11705,1367.86457 -11706,4,木次線,キスキセン,木次線,Kisuki Line,Kisuki Line,木次线,기스키선,#339966,2,E,,,,#339966,,,,REVERSED_SQUARE_WEST,,,,0,11706,4384.35107 +11705,4,境線,サカイセン,境線,Sakai Line,Sakai Line,境线,사카이선,#00FFFF,2,C,,,,#00FFFF,,,,REVERSED_SQUARE_WEST,,,,0,11705,1210.29083 +11706,4,木次線,キスキセン,木次線,Kisuki Line,Kisuki Line,木次线,기스키선,#339966,2,E,,,,#339966,,,,REVERSED_SQUARE_WEST,,,,0,11706,4446.78062 11707,4,三江線,サンコウセン,三江線,Sanko Line,Sanko Line,三江线,산코선,#C9090B,2,,,,,,,,,,,,,2,11707,3143.03522 -11708,4,山口線,ヤマグチセン,山口線,Yamaguchi Line,Yamaguchi Line,山口线,야마구치선,#FF6600,2,,,,,,,,,,,,,0,11708,3575.02675 -11709,4,宇野線,ウノセン,宇野線,Uno Line,Uno Line,宇野线,우노선,#3333CC,2,M,,,,#63D2D3,,,,REVERSED_SQUARE_WEST_DARK_TEXT,,,,0,11709,2534.64705 -11710,4,瀬戸大橋線,セトオオハシセン,本四備讃線,Honshi-Bisan Line,Honshi-Bisan Line,本四备赞线,혼시비산선,#0072BC,2,M,Y,,,#0072BC,#FBAF18,,,REVERSED_SQUARE_WEST,ROUND,,,0,11710,6966.51080 -11713,4,吉備線,キビセン,吉備線,Kibi Line,Kibi Line,吉备线,기비선,#FFA500,2,,,,,,,,,,,,,0,11713,2401.50092 +11708,4,山口線,ヤマグチセン,山口線,Yamaguchi Line,Yamaguchi Line,山口线,야마구치선,#FF6600,2,,,,,,,,,,,,,0,11708,3423.51014 +11709,4,宇野線,ウノセン,宇野線,Uno Line,Uno Line,宇野线,우노선,#3333CC,2,M,,,,#63D2D3,,,,REVERSED_SQUARE_WEST_DARK_TEXT,,,,0,11709,2310.05384 +11710,4,瀬戸大橋線,セトオオハシセン,本四備讃線,Honshi-Bisan Line,Honshi-Bisan Line,本四备赞线,혼시비산선,#0072BC,2,M,Y,,,#0072BC,#FBAF18,,,REVERSED_SQUARE_WEST,ROUND,,,0,11710,6198.50829 +11713,4,吉備線,キビセン,吉備線,Kibi Line,Kibi Line,吉备线,기비선,#FFA500,2,,,,,,,,,,,,,0,11713,2236.12757 11714,4,芸備線,ゲイビセン,芸備線,Geibi Line,Geibi Line,艺备线,게이비선,#00CED1,2,P,,,,#00CED1,,,,REVERSED_SQUARE_WEST,,,,0,11714,3716.98172 -11715,4,津山線,ツヤマセン,津山線,Tsuyama Line,Tsuyama Line,津山线,쓰야마선,#FF69B4,2,T,,,,#FF69B4,,,,REVERSED_SQUARE_WEST,,,,0,11715,3653.68551 +11715,4,津山線,ツヤマセン,津山線,Tsuyama Line,Tsuyama Line,津山线,쓰야마선,#FF69B4,2,T,,,,#FF69B4,,,,REVERSED_SQUARE_WEST,,,,0,11715,3604.41501 11716,4,呉線,クレセン,呉線,Kure Line,Kure Line,吴线,구레선,#33C033,2,Y,,,,#33C033,,,,REVERSED_SQUARE_WEST,,,,0,11716,3129.18662 -11717,4,可部線,カベセン,可部線,Kabe Line,Kabe Line,可部线,가베선,#A020F0,2,B,,,,#A020F0,,,,REVERSED_SQUARE_WEST,,,,0,11717,1494.65860 +11717,4,可部線,カベセン,可部線,Kabe Line,Kabe Line,可部线,가베선,#A020F0,2,B,,,,#A020F0,,,,REVERSED_SQUARE_WEST,,,,0,11717,1201.80796 11720,4,福塩線,フクエンセン,福塩線,Fukuen Line,Fukuen Line,福盐线,후쿠엔선,#FF1493,2,Z,,,,#FF1493,,,,REVERSED_SQUARE_WEST,,,,0,11720,3006.43876 -11721,4,宇部線,ウベセン,宇部線,Ube Line,Ube Line,宇部线,우베선,#990066,2,,,,,,,,,,,,,0,11721,2171.30206 +11721,4,宇部線,ウベセン,宇部線,Ube Line,Ube Line,宇部线,우베선,#990066,2,,,,,,,,,,,,,0,11721,1923.31896 11722,4,美祢線,ミネセン,美祢線,Mine Line,Mine Line,美祢线,미네선,#CC0066,2,,,,,,,,,,,,,0,11722,3957.07753 11723,4,小野田線,オノダセン,小野田線,Onoda Line,Onoda Line,小野田线,오노다선,#666699,2,,,,,,,,,,,,,0,11723,1992.42011 -11724,4,岩徳線,ガントクセン,岩徳線,Gantoku Line,Gantoku Line,岩德线,간토쿠선,#008056,2,,,,,,,,,,,,,0,11724,3423.31950 -11801,5,土讃線,ドサンセン,土讃線,Dosan Line,Dosan Line,土赞线,도산선,#E25885,2,D,K,,,#DC4586,#DC4586,,,ROUND,ROUND,,,0,11801,3392.76689 -11802,5,高徳線,コウトクセン,高徳線,Kotoku Line,Kotoku Line,高德线,고토쿠선,#99CC00,2,T,,,,#87CA3B,,,,ROUND,,,,0,11802,2841.67295 -11803,5,よしの川ブルーライン,ヨシノガワブルーライン,徳島線,Tokushima Line,Tokushima Line,德岛线,도쿠시마선,#008080,2,B,,,,#366481,,,,ROUND,,,,0,11803,3237.61119 -11804,5,牟岐線,ムギセン,牟岐線,Mugi Line,Mugi Line,牟岐线,무기선,#00FFFF,2,M,,,,#2EBDB1,,,,ROUND,,,,0,11804,2998.99292 -11805,5,鳴門線,ナルトセン,鳴門線,Naruto Line,Naruto Line,鸣门线,나루토선,#993366,2,N,,,,#881F61,,,,ROUND,,,,0,11805,1526.55656 -11806,5,予讃線,ヨサンセン,予讃線,Yosan Line,Yosan Line,予赞线,요산선,#FF9900,2,Y,,,,#F5AC13,,,,ROUND,,,,0,11806,3752.79979 -11807,5,予讃・内子線,ヨサン・ウチコセン,予讃・内子線,Yosan/Uchiko Line,Yosan/Uchiko Line,予赞・内子线,요산선・우치코선,#FF9900,2,U,S,,,#F5AC13,#9AA7D7,,,ROUND,ROUND,,,0,11807,4037.48329 -11808,5,しまんとグリーンライン,シマントグリーンライン,予土線,Yodo Line,Yodo Line,予土线,요도선,#339966,2,G,,,,#339966,,,,ROUND,,,,0,11808,3857.84920 +11724,4,岩徳線,ガントクセン,岩徳線,Gantoku Line,Gantoku Line,岩德线,간토쿠선,#008056,2,,,,,,,,,,,,,0,11724,3423.3195 +11801,5,土讃線,ドサンセン,土讃線,Dosan Line,Dosan Line,土赞线,도산선,#E25885,2,D,K,,,#DC4586,#DC4586,,,ROUND,ROUND,,,0,11801,3235.86542 +11802,5,高徳線,コウトクセン,高徳線,Kotoku Line,Kotoku Line,高德线,고토쿠선,#99CC00,2,T,,,,#87CA3B,,,,ROUND,,,,0,11802,2606.83126 +11803,5,よしの川ブルーライン,ヨシノガワブルーライン,徳島線,Tokushima Line,Tokushima Line,德岛线,도쿠시마선,#008080,2,B,,,,#366481,,,,ROUND,,,,0,11803,2904.33283 +11804,5,牟岐線,ムギセン,牟岐線,Mugi Line,Mugi Line,牟岐线,무기선,#00FFFF,2,M,,,,#2EBDB1,,,,ROUND,,,,0,11804,2708.87394 +11805,5,鳴門線,ナルトセン,鳴門線,Naruto Line,Naruto Line,鸣门线,나루토선,#993366,2,N,,,,#881F61,,,,ROUND,,,,0,11805,1347.57908 +11806,5,予讃線,ヨサンセン,予讃線,Yosan Line,Yosan Line,予赞线,요산선,#FF9900,2,Y,,,,#F5AC13,,,,ROUND,,,,0,11806,3418.15462 +11807,5,予讃・内子線,ヨサン・ウチコセン,予讃・内子線,Yosan/Uchiko Line,Yosan/Uchiko Line,予赞・内子线,요산선・우치코선,#FF9900,2,U,S,,,#F5AC13,#9AA7D7,,,ROUND,ROUND,,,0,11807,3962.36461 +11808,5,しまんとグリーンライン,シマントグリーンライン,予土線,Yodo Line,Yodo Line,予土线,요도선,#339966,2,G,,,,#339966,,,,ROUND,,,,0,11808,3815.26923 11901,4,博多南線,ハカタミナミセン,博多南線,Hakata-Minami Line,Hakata-Minami Line,博多南线,하카타미나미선,#22B04F,2,,,,,,,,,,,,,0,11901,9376.75481 -11902,6,鹿児島本線,カゴシマホンセン,鹿児島本線,Kagoshima Main Line,Kagoshima Main Line,鹿儿岛本线,가고시마 본선,#E24148,2,JA,,,,#E24148,,,,HALF_SQUARE,,,,0,11902,2992.31361 -11903,6,鹿児島本線,カゴシマホンセン,鹿児島本線,Kagoshima Main Line,Kagoshima Main Line,鹿儿岛本线,가고시마 본선,#E24148,2,JB,,,,#E24148,,,,HALF_SQUARE,,,,0,11903,3695.50471 -11904,6,鹿児島本線,カゴシマホンセン,鹿児島本線,Kagoshima Main Line,Kagoshima Main Line,鹿儿岛本线,가고시마 본선,#E24148,2,,,,,,,,,,,,,0,11904,4031.46827 -11905,6,長崎本線,ナガサキホンセン,長崎本線,Nagasaki Main Line,Nagasaki Main Line,长崎本线,나가사키 본선,#E6B040,2,JH,,,,#E6B040,,,,HALF_SQUARE_DARK_TEXT,,,,0,11905,3767.17369 +11902,6,鹿児島本線,カゴシマホンセン,鹿児島本線,Kagoshima Main Line,Kagoshima Main Line,鹿儿岛本线,가고시마 본선,#E24148,2,JA,,,,#E24148,,,,HALF_SQUARE,,,,0,11902,2788.52108 +11903,6,鹿児島本線,カゴシマホンセン,鹿児島本線,Kagoshima Main Line,Kagoshima Main Line,鹿儿岛本线,가고시마 본선,#E24148,2,JB,,,,#E24148,,,,HALF_SQUARE,,,,0,11903,3037.07214 +11904,6,鹿児島本線,カゴシマホンセン,鹿児島本線,Kagoshima Main Line,Kagoshima Main Line,鹿儿岛本线,가고시마 본선,#E24148,2,,,,,,,,,,,,,0,11904,3693.15389 +11905,6,長崎本線,ナガサキホンセン,長崎本線,Nagasaki Main Line,Nagasaki Main Line,长崎本线,나가사키 본선,#E6B040,2,JH,,,,#E6B040,,,,HALF_SQUARE_DARK_TEXT,,,,0,11905,3539.30824 11906,6,日豊本線,ニッポウホンセン,日豊本線,Nippo Main Line,Nippo Main Line,日丰本线,닛포 본선,#4ABACD,2,JF,,,,#4ABACD,,,,HALF_SQUARE,,,,0,11906,3769.80768 -11907,6,日豊本線,ニッポウホンセン,日豊本線,Nippo Main Line,Nippo Main Line,日丰本线,닛포 본선,#4ABACD,2,,,,,,,,,,,,,0,11907,4997.00990 -11908,6,福北ゆたか線,フクホクユタカセン,篠栗線,Fukuhoku Yutaka Line,Fukuhoku Yutaka Line,福北丰线,후쿠호쿠유타카선,#FAAF18,2,JC,,,,#FAAF18,,,,HALF_SQUARE_DARK_TEXT,,,,0,11908,2669.79791 -11909,6,筑肥線,チクヒセン,筑肥線,Chikuhi Line,Chikuhi Line,筑肥线,지쿠히선,#8F3E97,2,JK,,,,#8F3E97,,,,HALF_SQUARE,,,,0,11909,2572.22650 -11910,6,若松線,ワカマツセン,筑豊本線,Wakamatsu Line,Wakamatsu Line,若松线,와카마쓰선,#0095D9,2,JE,,,,#0095D9,,,,HALF_SQUARE,,,,0,11910,2299.54201 -11911,6,福北ゆたか線,フクホクユタカセン,筑豊本線,Fukuhoku Yutaka Line,Fukuhoku Yutaka Line,福北丰线,후쿠호쿠유타카선,#FAAF18,2,JC,,,,#FAAF18,,,,HALF_SQUARE_DARK_TEXT,,,,0,11911,2512.13157 -11912,6,原田線,ハルダセン,筑豊本線,Haruda Line,Haruda Line,原田线,하루다선,#36B558,2,JG,,,,#36B558,,,,HALF_SQUARE,,,,0,11912,5482.14765 -11913,6,ゆふ高原線,ユフコウゲンセン,久大本線,Kyūdai Main Line,Kyūdai Main Line,久大本线,규다이 본선,#36B558,2,,,,,,,,,,,,,0,11913,4048.28062 -11914,6,日田彦山線,ヒタヒコサンセン,日田彦山線,Hitahikosan Line,Hitahikosan Line,日田彦山线,히타히코산선,#B96F30,2,JI,,,,#B96F30,,,,HALF_SQUARE,,,,0,11914,3187.45752 -11915,6,後藤寺線,ゴトウジセン,後藤寺線,Gotoji Line,Gotoji Line,后藤寺线,고토지선,#8F3E97,2,JJ,,,,#8F3E97,,,,HALF_SQUARE,,,,0,11915,2692.85237 -11916,6,海の中道線,ウミノナカミチセン,香椎線,Kashii Line,Kashii Line,香椎线,가시선,#3A268F,2,,,,,,,,,,,,,0,11916,2788.03218 -11917,6,香椎線,カシイセン,香椎線,Kashii Line,Kashii Line,香椎线,가시선,#0095D9,2,JD,,,,#0095D9,,,,HALF_SQUARE,,,,0,11917,1393.38916 -11918,6,佐世保線,サセボセン,佐世保線,Sasebo Line,Sasebo Line,佐世保线,사세보선,#36B558,2,,,,,,,,,,,,,0,11918,3896.53683 -11920,6,筑肥線,チクヒセン,筑肥線,Chikuhi Line,Chikuhi Line,筑肥线,지쿠히선,#8F3E97,2,,,,,,,,,,,,,0,11920,2763.37875 -11921,6,唐津線,カラツセン,唐津線,Karatsu Line,Karatsu Line,唐津线,가라쓰선,#0095D9,2,,,,,,,,,,,,,0,11921,3445.17758 -11922,6,大村線,オオムラセン,大村線,Omura Line,Omura Line,大村线,오무라선,#0095D9,2,,,,,,,,,,,,,0,11922,3989.69795 -11923,6,豊肥本線,ホウヒホンセン,豊肥本線,Hohi Main Line,Hohi Main Line,丰肥本线,호히 본선,#B96F30,2,,,,,,,,,,,,,0,11923,4073.66420 -11924,6,三角線(あまくさみすみ線),アマクサミスミセン,三角線,Misumi Line,Misumi Line,三角线,미스미선,#0095D9,2,,,,,,,,,,,,,0,11924,4324.57484 -11925,6,えびの高原線,エビノコウゲンセン,肥薩線,Hisatsu Line,Hisatsu Line,肥萨线,히사쓰선,#8F3E97,2,,,,,,,,,,,,,0,11925,4460.53213 -11926,6,肥薩線,ヒサツセン,肥薩線,Hisatsu Line,Hisatsu Line,肥萨线,히사쓰선,#8F3E97,2,,,,,,,,,,,,,0,11926,4130.97700 -11927,6,宮崎空港線,ミヤザキクウコウセン,宮崎空港線,Miyazaki Airport Line,Miyazaki Airport Line,宫崎机场线,미야자키쿠코선,#36B558,2,,,,,,,,,,,,,0,11927,2159.41819 +11907,6,日豊本線,ニッポウホンセン,日豊本線,Nippo Main Line,Nippo Main Line,日丰本线,닛포 본선,#4ABACD,2,,,,,,,,,,,,,0,11907,4783.87629 +11908,6,福北ゆたか線,フクホクユタカセン,篠栗線,Fukuhoku Yutaka Line,Fukuhoku Yutaka Line,福北丰线,후쿠호쿠유타카선,#FAAF18,2,JC,,,,#FAAF18,,,,HALF_SQUARE_DARK_TEXT,,,,0,11908,2397.33676 +11909,6,筑肥線,チクヒセン,筑肥線,Chikuhi Line,Chikuhi Line,筑肥线,지쿠히선,#8F3E97,2,JK,,,,#8F3E97,,,,HALF_SQUARE,,,,0,11909,2195.8741 +11910,6,若松線,ワカマツセン,筑豊本線,Wakamatsu Line,Wakamatsu Line,若松线,와카마쓰선,#0095D9,2,JE,,,,#0095D9,,,,HALF_SQUARE,,,,0,11910,2099.50323 +11911,6,福北ゆたか線,フクホクユタカセン,筑豊本線,Fukuhoku Yutaka Line,Fukuhoku Yutaka Line,福北丰线,후쿠호쿠유타카선,#FAAF18,2,JC,,,,#FAAF18,,,,HALF_SQUARE_DARK_TEXT,,,,0,11911,2280.68241 +11912,6,原田線,ハルダセン,筑豊本線,Haruda Line,Haruda Line,原田线,하루다선,#36B558,2,JG,,,,#36B558,,,,HALF_SQUARE,,,,0,11912,5133.01193 +11913,6,ゆふ高原線,ユフコウゲンセン,久大本線,Kyūdai Main Line,Kyūdai Main Line,久大本线,규다이 본선,#36B558,2,,,,,,,,,,,,,0,11913,3843.50595 +11914,6,日田彦山線,ヒタヒコサンセン,日田彦山線,Hitahikosan Line,Hitahikosan Line,日田彦山线,히타히코산선,#B96F30,2,JI,,,,#B96F30,,,,HALF_SQUARE,,,,0,11914,2853.35332 +11915,6,後藤寺線,ゴトウジセン,後藤寺線,Gotoji Line,Gotoji Line,后藤寺线,고토지선,#8F3E97,2,JJ,,,,#8F3E97,,,,HALF_SQUARE,,,,0,11915,2547.05013 +11916,6,海の中道線,ウミノナカミチセン,香椎線,Kashii Line,Kashii Line,香椎线,가시선,#3A268F,2,,,,,,,,,,,,,0,11916,2435.9513 +11917,6,香椎線,カシイセン,香椎線,Kashii Line,Kashii Line,香椎线,가시선,#0095D9,2,JD,,,,#0095D9,,,,HALF_SQUARE,,,,0,11917,1214.8027 +11918,6,佐世保線,サセボセン,佐世保線,Sasebo Line,Sasebo Line,佐世保线,사세보선,#36B558,2,,,,,,,,,,,,,0,11918,3720.00573 +11920,6,筑肥線,チクヒセン,筑肥線,Chikuhi Line,Chikuhi Line,筑肥线,지쿠히선,#8F3E97,2,,,,,,,,,,,,,0,11920,2637.30264 +11921,6,唐津線,カラツセン,唐津線,Karatsu Line,Karatsu Line,唐津线,가라쓰선,#0095D9,2,,,,,,,,,,,,,0,11921,3201.2036 +11922,6,大村線,オオムラセン,大村線,Omura Line,Omura Line,大村线,오무라선,#0095D9,2,,,,,,,,,,,,,0,11922,3363.01247 +11923,6,豊肥本線,ホウヒホンセン,豊肥本線,Hohi Main Line,Hohi Main Line,丰肥本线,호히 본선,#B96F30,2,,,,,,,,,,,,,0,11923,4060.20788 +11924,6,三角線(あまくさみすみ線),アマクサミスミセン,三角線,Misumi Line,Misumi Line,三角线,미스미선,#0095D9,2,,,,,,,,,,,,,0,11924,3270.08844 +11925,6,えびの高原線,エビノコウゲンセン,肥薩線,Hisatsu Line,Hisatsu Line,肥萨线,히사쓰선,#8F3E97,2,,,,,,,,,,,,,0,11925,4713.83221 +11926,6,肥薩線,ヒサツセン,肥薩線,Hisatsu Line,Hisatsu Line,肥萨线,히사쓰선,#8F3E97,2,,,,,,,,,,,,,0,11926,4078.25274 +11927,6,宮崎空港線,ミヤザキクウコウセン,宮崎空港線,Miyazaki Airport Line,Miyazaki Airport Line,宫崎机场线,미야자키쿠코선,#36B558,2,,,,,,,,,,,,,0,11927,1938.07464 11928,6,日南線,ニチナンセン,日南線,Nichinan Line,Nichinan Line,日南线,니치난선,#FAAF18,2,,,,,,,,,,,,,0,11928,3348.76242 -11929,6,えびの高原線,エビノコウゲンセン,吉都線,Kitto Line,Kitto Line,吉都线,깃토선,#36B558,2,,,,,,,,,,,,,0,11929,4132.62024 -11930,6,指宿枕崎線,イブスキマクラザキセン,指宿枕崎線,Ibusuki Makurazaki Line,Ibusuki Makurazaki Line,指宿枕崎线,이부스키마쿠라자키선,#FAAF18,2,,,,,,,,,,,,,0,11930,2698.39876 -21001,11,東武東上線,トウブトウジョウセン,東武東上線,Tobu Tojo Line,Tobu Tojo Line,东武东上线,도부 도조선,#004098,2,TJ,,,,#014099,,,,SQUARE,,,,0,21001,2285.38413 -21002,11,東武伊勢崎線,トウブイセサキセン,東武伊勢崎線,Tobu Isesaki Line,Tobu Isesaki Line,东武伊势崎线,도부 이세사키선,#ED1A3D,2,TI,TS,,,#B50033,#0067C0,,,SQUARE,SQUARE,,,0,21002,2370.85420 -21003,11,東武日光線,トウブニッコウセン,東武日光線,Tobu Nikko Line,Tobu Nikko Line,东武日光线,도부 닛코선,#FFA500,2,TN,TS,,,#F08200,#0067C0,,,SQUARE,SQUARE,,,0,21003,4182.26883 -21004,11,東武アーバンパークライン,トウブアーバンパークライン,東武野田線,Tobu Urban Park Line,Tobu Urban Park Line,东武都市公园线,도부 어반 파크 라인,#00BFFF,2,TD,,,,#00A1E9,,,,SQUARE,,,,0,21004,2049.82128 -21005,11,東武亀戸線,トウブカメイドセン,東武亀戸線,Tobu Kameido Line,Tobu Kameido Line,东武龟户线,도부 가메이도선,#004098,2,TS,,,,#0067C0,,,,SQUARE,,,,0,21005,953.96931 -21006,11,東武大師線,トウブダイシセン,東武大師線,Tobu Daishi Line,Tobu Daishi Line,东武大师线,도부 다이시선,#004098,2,TS,,,,#0067C0,,,,SQUARE,,,,0,21006,929.88695 -21007,11,東武越生線,トウブオゴセセン,東武越生線,Tobu Ogose Line,Tobu Ogose Line,东武越生线,도부 오고세선,#004098,2,TJ,,,,#014099,,,,SQUARE,,,,0,21007,1772.67675 +11929,6,えびの高原線,エビノコウゲンセン,吉都線,Kitto Line,Kitto Line,吉都线,깃토선,#36B558,2,,,,,,,,,,,,,0,11929,3795.96536 +11930,6,指宿枕崎線,イブスキマクラザキセン,指宿枕崎線,Ibusuki Makurazaki Line,Ibusuki Makurazaki Line,指宿枕崎线,이부스키마쿠라자키선,#FAAF18,2,,,,,,,,,,,,,0,11930,2445.33683 +21001,11,東武東上線,トウブトウジョウセン,東武東上線,Tobu Tojo Line,Tobu Tojo Line,东武东上线,도부 도조선,#004098,2,TJ,,,,#014099,,,,SQUARE,,,,0,21001,1943.6609 +21002,11,東武伊勢崎線,トウブイセサキセン,東武伊勢崎線,Tobu Isesaki Line,Tobu Isesaki Line,东武伊势崎线,도부 이세사키선,#ED1A3D,2,TI,TS,,,#B50033,#0067C0,,,SQUARE,SQUARE,,,0,21002,2370.8542 +21003,11,東武日光線,トウブニッコウセン,東武日光線,Tobu Nikko Line,Tobu Nikko Line,东武日光线,도부 닛코선,#FFA500,2,TN,TS,,,#F08200,#0067C0,,,SQUARE,SQUARE,,,0,21003,3736.18408 +21004,11,東武アーバンパークライン,トウブアーバンパークライン,東武野田線,Tobu Urban Park Line,Tobu Urban Park Line,东武都市公园线,도부 어반 파크 라인,#00BFFF,2,TD,,,,#00A1E9,,,,SQUARE,,,,0,21004,1817.1716 +21005,11,東武亀戸線,トウブカメイドセン,東武亀戸線,Tobu Kameido Line,Tobu Kameido Line,东武龟户线,도부 가메이도선,#004098,2,TS,,,,#0067C0,,,,SQUARE,,,,0,21005,854.1278 +21006,11,東武大師線,トウブダイシセン,東武大師線,Tobu Daishi Line,Tobu Daishi Line,东武大师线,도부 다이시선,#004098,2,TS,,,,#0067C0,,,,SQUARE,,,,0,21006,808.59735 +21007,11,東武越生線,トウブオゴセセン,東武越生線,Tobu Ogose Line,Tobu Ogose Line,东武越生线,도부 오고세선,#004098,2,TJ,,,,#014099,,,,SQUARE,,,,0,21007,1542.24657 21008,11,東武宇都宮線,トウブウツノミヤセン,東武宇都宮線,Tobu Utsunomiya Line,Tobu Utsunomiya Line,东武宇都宫线,도부 우쓰노미야선,#FFA500,2,TN,,,,#F08200,,,,SQUARE,,,,0,21008,2694.53691 -21009,11,東武鬼怒川線,トウブキヌガワセン,東武鬼怒川線,Tobu Kinugawa Line,Tobu Kinugawa Line,东武鬼怒川线,도부 기누가와선,#FFA500,2,TN,,,,#F08200,,,,SQUARE,,,,0,21009,2188.68638 -21010,11,東武佐野線,トウブサノセン,東武佐野線,Tobu Sano Line,Tobu Sano Line,东武佐野线,도부 사노선,#ED1A3D,2,TI,,,,#B50033,,,,SQUARE,,,,0,21010,2423.70982 -21011,11,東武桐生線,トウブキリュウセン,東武桐生線,Tobu Kiryu Line,Tobu Kiryu Line,东武桐生线,도부 기류선,#ED1A3D,2,TI,,,,#B50033,,,,SQUARE,,,,0,21011,3133.23948 +21009,11,東武鬼怒川線,トウブキヌガワセン,東武鬼怒川線,Tobu Kinugawa Line,Tobu Kinugawa Line,东武鬼怒川线,도부 기누가와선,#FFA500,2,TN,,,,#F08200,,,,SQUARE,,,,0,21009,1964.12 +21010,11,東武佐野線,トウブサノセン,東武佐野線,Tobu Sano Line,Tobu Sano Line,东武佐野线,도부 사노선,#ED1A3D,2,TI,,,,#B50033,,,,SQUARE,,,,0,21010,2389.76109 +21011,11,東武桐生線,トウブキリュウセン,東武桐生線,Tobu Kiryu Line,Tobu Kiryu Line,东武桐生线,도부 기류선,#ED1A3D,2,TI,,,,#B50033,,,,SQUARE,,,,0,21011,2835.1253 21012,11,東武小泉線,トウブコイズミセン,東武小泉線,Tobu Koizumi Line,Tobu Koizumi Line,东武小泉线,도부 고이즈미선,#ED1A3D,2,TI,,,,#B50033,,,,SQUARE,,,,0,21012,2725.22052 -22001,12,西武池袋線,セイブイケブクロセン,西武池袋線,Seibu Ikebukuro Line,Seibu Ikebukuro Line,西武池袋线,세이부 이케부쿠로선,#F17900,2,SI,,,,#F17900,,,,HALF_SQUARE_DARK_TEXT,,,,0,22001,2214.94250 -22002,12,西武秩父線,セイブチチブセン,西武秩父線,Seibu Chichibu Line,Seibu Chichibu Line,西武秩父线,세이부 지치부선,#F17900,2,SI,,,,#F17900,,,,HALF_SQUARE_DARK_TEXT,,,,0,22002,3248.87225 -22003,12,西武有楽町線,セイブユウラクチョウセン,西武有楽町線,Seibu Yurakucho Line,Seibu Yurakucho Line,西武有乐町线,세이부 유라쿠초선,#F17901,2,SI,,,,#F17900,,,,HALF_SQUARE_DARK_TEXT,,,,0,22003,1313.29598 -22004,12,西武豊島線,セイブトシマセン,西武豊島線,Seibu Toshima Line,Seibu Toshima Line,西武丰岛线,세이부 도시마선,#F17900,2,SI,,,,#F17900,,,,HALF_SQUARE_DARK_TEXT,,,,0,22004,850.20873 -22005,12,西武狭山線,セイブサヤマセン,西武狭山線,Seibu Sayama Line,Seibu Sayama Line,西武狭山线,세이부 사야마선,#F17900,2,SI,,,,#F17900,,,,HALF_SQUARE_DARK_TEXT,,,,0,22005,2234.29280 -22006,12,レオライナー,レオライナー,西武山口線,Seibu Yamaguchi Line,Seibu Yamaguchi Line,西武山口线,세이부 야마구치선,#FF69B4,5,SY,,,,#FF3333,,,,HALF_SQUARE_DARK_TEXT,,,,0,22006,1255.95633 -22007,12,西武新宿線,セイブシンジュクセン,西武新宿線,Seibu Shinjuku Line,Seibu Shinjuku Line,西武新宿线,세이부 신주쿠선,#00A6C0,2,SS,,,,#00A6C0,,,,HALF_SQUARE_DARK_TEXT,,,,0,22007,1915.74416 -22008,12,西武拝島線,セイブハイジマセン,西武拝島線,Seibu Haijima Line,Seibu Haijima Line,西武拜岛线,세이부 하이지마선,#00A6C0,2,SS,,,,#00A6C0,,,,HALF_SQUARE_DARK_TEXT,,,,0,22008,2199.01872 -22009,12,西武西武園線,セイブセイブエンセン,西武西武園線,Seibu Seibuen Line,Seibu Seibuen Line,西武西武园线,세이부 세이부엔선,#00A6C0,2,SK,,,,#00A6C0,,,,HALF_SQUARE_DARK_TEXT,,,,0,22009,2009.52616 -22010,12,西武国分寺線,セイブコクブンジセン,西武国分寺線,Seibu Kokubunji Line,Seibu Kokubunji Line,西武国分寺线,세이부 고쿠분지선,#00BB00,2,SK,,,,#00BB00,,,,HALF_SQUARE_DARK_TEXT,,,,0,22010,2137.00395 -22011,12,西武多摩湖線,セイブタマコセン,西武多摩湖線,Seibu Tamako Line,Seibu Tamako Line,西武多摩湖线,세이부 다마코선,#FFA500,2,ST,,,,#FFA500,,,,HALF_SQUARE_DARK_TEXT,,,,0,22011,1722.50453 -22012,12,西武多摩川線,セイブタマガワセン,西武多摩川線,Seibu Tamagawa Line,Seibu Tamagawa Line,西武多摩川线,세이부 다마가와선,#F17900,2,SW,,,,#F17900,,,,HALF_SQUARE_DARK_TEXT,,,,0,22012,1781.31149 -23001,13,京成本線,ケイセイホンセン,京成本線,Keisei Main Line,Keisei Main Line,京成本线,게이세이 본선,#005AAA,2,KS,,,,#005AAA,,,,KEISEI,,,,0,23001,1806.27730 -23002,13,京成押上線,ケイセイオシアゲセン,京成押上線,Keisei Oshiage Line,Keisei Oshiage Line,京成押上线,게이세이 오시아게선,#005AAA,2,KS,A,,,#005AAA,#E85298,,,KEISEI,ROUND,,,0,23002,1288.29466 -23003,13,京成金町線,ケイセイカナマチセン,京成金町線,Keisei Kanamachi Line,Keisei Kanamachi Line,京成金町线,게이세이 가나마치선,#005AAA,2,KS,,,,#005AAA,,,,KEISEI,,,,0,23003,1367.81222 -23004,13,京成千葉線,ケイセイチバセン,京成千葉線,Keisei Chiba Line,Keisei Chiba Line,京成千叶线,게이세이 지바선,#005AAA,2,KS,,,,#005AAA,,,,KEISEI,,,,0,23004,1546.71006 -23005,13,京成千原線,ケイセイチハラセン,京成千原線,Keisei Chihara Line,Keisei Chihara Line,京成千原线,게이세이 지하라선,#005AAA,2,KS,,,,#005AAA,,,,KEISEI,,,,0,23005,2284.23965 -23006,13,成田スカイアクセス線,ナリタスカイアクセスセン,京成成田空港線,Keisei Narita Airport Line,Keisei Narita Airport Line,京成成田机场线,게이세이 나리타 공항선,#FF6600,2,KS,HS,,,#005AAA,#3333FF,,,KEISEI,KEISEI,,,0,23006,7630.65081 -24001,14,京王線,ケイオウセン,京王線,Keio Line,Keio Line,京王线,게이오선,#CA0073,2,KO,,,,#CA0073,,,,KEIO,,,,0,24001,1348.13632 -24002,14,京王相模原線,ケイオウサガミハラセン,京王相模原線,Keio Sagamihara Line,Keio Sagamihara Line,京王相模原线,게이오 사가미하라선,#CA0073,2,KO,,,,#CA0073,,,,KEIO,,,,0,24002,2242.86934 -24003,14,京王高尾線,ケイオウタカオセン,京王高尾線,Keio Takao Line,Keio Takao Line,京王高尾线,게이오 다카오선,#CA0073,2,KO,,,,#CA0073,,,,KEIO,,,,0,24003,1555.72899 -24004,14,京王競馬場線,ケイオウケイバジョウセン,京王競馬場線,Keio Keibajo Line,Keio Keibajo Line,京王竞马场线,게이오 게이바조선,#CA0073,2,KO,,,,#CA0073,,,,KEIO,,,,0,24004,1065.33446 -24005,14,京王動物園線,ケイオウドウブツエンセン,京王動物園線,Keio Dobutsuen Line,Keio Dobutsuen Line,京王动物园线,게이오 도부쓰엔선,#CA0073,2,KO,,,,#CA0073,,,,KEIO,,,,0,24005,1890.56940 -24006,14,京王井の頭線,ケイオウイノガシラセン,京王井の頭線,Keio Inokashira Line,Keio Inokashira Line,京王井之头线,게이오 이노카시라선,#000088,2,IN,,,,#000088,,,,KEIO,,,,0,24006,911.15749 -24007,14,京王新線,ケイオウシンセン,京王新線,Keio New Line,Keio New Line,京王新线,게이오 신선,#CA0073,2,KO,,,,#CA0073,,,,KEIO,,,,0,24007,1270.12415 -25001,15,小田急線,オダキュウセン,小田急小田原線,Odakyu Line,Odakyu Line,小田急线,오다큐선,#2F79BC,2,OH,,,,#2F79BC,,,,ODAKYU,,,,0,25001,1978.68691 -25002,15,小田急江ノ島線,オダキュウエノシマセン,小田急江ノ島線,Odakyu Enoshima Line,Odakyu Enoshima Line,小田急江之岛线,오다큐 에노시마선,#2D8BD0,2,OE,OH,,,#2F79BC,#2F79BC,,,ODAKYU,ODAKYU,,,0,25002,1913.62722 -25003,15,小田急多摩線,オダキュウタマセン,小田急多摩線,Odakyu Tama Line,Odakyu Tama Line,小田急多摩线,오다큐 다마선,#2D8BD0,2,OT,OH,,,#2F79BC,#2F79BC,,,ODAKYU,ODAKYU,,,0,25003,1696.57325 -26001,16,東急東横線,トウキュウトウヨコセン,東急東横線,Tokyu Toyoko Line,Tokyu Toyoko Line,东急东横线,도큐 도요코선,#EE0011,2,TY,,,,#EE0011,,,,REVERSED_SQUARE,,,,0,26001,1355.21602 -26002,16,東急目黒線,トウキュウメグロセン,東急目黒線,Tokyu Meguro Line,Tokyu Meguro Line,东急目黑线,도큐 메구로선,#2C94B6,2,MG,,,,#2C94B6,,,,REVERSED_SQUARE,,,,0,26002,1114.41260 -26003,16,東急田園都市線,トウキュウデンエントシセン,東急田園都市線,Tokyu Den-en-toshi Line,Tokyu Den-en-toshi Line,东急田园都市线,도큐 덴엔토시선,#018D54,2,DT,,,,#018D54,,,,REVERSED_SQUARE,,,,0,26003,1355.04470 -26004,16,東急大井町線,トウキュウオオイマチセン,東急大井町線,Tokyu Oimachi Line,Tokyu Oimachi Line,东急大井町线,도큐 오이마치선,#FD9A3D,2,OM,,,,#FD9A3D,,,,REVERSED_SQUARE,,,,0,26004,824.41247 -26005,16,東急池上線,トウキュウイケガミセン,東急池上線,Tokyu Ikegami Line,Tokyu Ikegami Line,东急池上线,도큐 이케가미선,#DE65B0,2,IK,,,,#DE65B0,,,,REVERSED_SQUARE,,,,0,26005,869.15138 -26006,16,東急多摩川線,トウキュウタマガワセン,東急多摩川線,Tokyu Tamagawa Line,Tokyu Tamagawa Line,东急多摩川线,도큐 다마가와선,#A3016E,2,TM,,,,#A3016E,,,,REVERSED_SQUARE,,,,0,26006,1056.91649 +22001,12,西武池袋線,セイブイケブクロセン,西武池袋線,Seibu Ikebukuro Line,Seibu Ikebukuro Line,西武池袋线,세이부 이케부쿠로선,#F17900,2,SI,,,,#F17900,,,,HALF_SQUARE_DARK_TEXT,,,,0,22001,2041.41825 +22002,12,西武秩父線,セイブチチブセン,西武秩父線,Seibu Chichibu Line,Seibu Chichibu Line,西武秩父线,세이부 지치부선,#F17900,2,SI,,,,#F17900,,,,HALF_SQUARE_DARK_TEXT,,,,0,22002,3156.95666 +22003,12,西武有楽町線,セイブユウラクチョウセン,西武有楽町線,Seibu Yurakucho Line,Seibu Yurakucho Line,西武有乐町线,세이부 유라쿠초선,#F17901,2,SI,,,,#F17900,,,,HALF_SQUARE_DARK_TEXT,,,,0,22003,1192.33408 +22004,12,西武豊島線,セイブトシマセン,西武豊島線,Seibu Toshima Line,Seibu Toshima Line,西武丰岛线,세이부 도시마선,#F17900,2,SI,,,,#F17900,,,,HALF_SQUARE_DARK_TEXT,,,,0,22004,903.87278 +22005,12,西武狭山線,セイブサヤマセン,西武狭山線,Seibu Sayama Line,Seibu Sayama Line,西武狭山线,세이부 사야마선,#F17900,2,SI,,,,#F17900,,,,HALF_SQUARE_DARK_TEXT,,,,0,22005,2026.49521 +22006,12,レオライナー,レオライナー,西武山口線,Seibu Yamaguchi Line,Seibu Yamaguchi Line,西武山口线,세이부 야마구치선,#FF69B4,5,SY,,,,#FF3333,,,,HALF_SQUARE_DARK_TEXT,,,,0,22006,1384.74496 +22007,12,西武新宿線,セイブシンジュクセン,西武新宿線,Seibu Shinjuku Line,Seibu Shinjuku Line,西武新宿线,세이부 신주쿠선,#00A6C0,2,SS,,,,#00A6C0,,,,HALF_SQUARE_DARK_TEXT,,,,0,22007,1681.79404 +22008,12,西武拝島線,セイブハイジマセン,西武拝島線,Seibu Haijima Line,Seibu Haijima Line,西武拜岛线,세이부 하이지마선,#00A6C0,2,SS,,,,#00A6C0,,,,HALF_SQUARE_DARK_TEXT,,,,0,22008,2011.14468 +22009,12,西武西武園線,セイブセイブエンセン,西武西武園線,Seibu Seibuen Line,Seibu Seibuen Line,西武西武园线,세이부 세이부엔선,#00A6C0,2,SK,,,,#00A6C0,,,,HALF_SQUARE_DARK_TEXT,,,,0,22009,2432.68591 +22010,12,西武国分寺線,セイブコクブンジセン,西武国分寺線,Seibu Kokubunji Line,Seibu Kokubunji Line,西武国分寺线,세이부 고쿠분지선,#00BB00,2,SK,,,,#00BB00,,,,HALF_SQUARE_DARK_TEXT,,,,0,22010,1911.94322 +22011,12,西武多摩湖線,セイブタマコセン,西武多摩湖線,Seibu Tamako Line,Seibu Tamako Line,西武多摩湖线,세이부 다마코선,#FFA500,2,ST,,,,#FFA500,,,,HALF_SQUARE_DARK_TEXT,,,,0,22011,1497.83003 +22012,12,西武多摩川線,セイブタマガワセン,西武多摩川線,Seibu Tamagawa Line,Seibu Tamagawa Line,西武多摩川线,세이부 다마가와선,#F17900,2,SW,,,,#F17900,,,,HALF_SQUARE_DARK_TEXT,,,,0,22012,1556.25362 +23001,13,京成本線,ケイセイホンセン,京成本線,Keisei Main Line,Keisei Main Line,京成本线,게이세이 본선,#005AAA,2,KS,,,,#005AAA,,,,KEISEI,,,,0,23001,1640.0498 +23002,13,京成押上線,ケイセイオシアゲセン,京成押上線,Keisei Oshiage Line,Keisei Oshiage Line,京成押上线,게이세이 오시아게선,#005AAA,2,KS,A,,,#005AAA,#E85298,,,KEISEI,ROUND,,,0,23002,1120.25622 +23003,13,京成金町線,ケイセイカナマチセン,京成金町線,Keisei Kanamachi Line,Keisei Kanamachi Line,京成金町线,게이세이 가나마치선,#005AAA,2,KS,,,,#005AAA,,,,KEISEI,,,,0,23003,1261.42049 +23004,13,京成千葉線,ケイセイチバセン,京成千葉線,Keisei Chiba Line,Keisei Chiba Line,京成千叶线,게이세이 지바선,#005AAA,2,KS,,,,#005AAA,,,,KEISEI,,,,0,23004,1394.3923 +23005,13,京成千原線,ケイセイチハラセン,京成千原線,Keisei Chihara Line,Keisei Chihara Line,京成千原线,게이세이 지하라선,#005AAA,2,KS,,,,#005AAA,,,,KEISEI,,,,0,23005,2123.10699 +23006,13,成田スカイアクセス線,ナリタスカイアクセスセン,京成成田空港線,Keisei Narita Airport Line,Keisei Narita Airport Line,京成成田机场线,게이세이 나리타 공항선,#FF6600,2,KS,HS,,,#005AAA,#3333FF,,,KEISEI,KEISEI,,,0,23006,7555.64232 +24001,14,京王線,ケイオウセン,京王線,Keio Line,Keio Line,京王线,게이오선,#CA0073,2,KO,,,,#CA0073,,,,KEIO,,,,0,24001,1199.29758 +24002,14,京王相模原線,ケイオウサガミハラセン,京王相模原線,Keio Sagamihara Line,Keio Sagamihara Line,京王相模原线,게이오 사가미하라선,#CA0073,2,KO,,,,#CA0073,,,,KEIO,,,,0,24002,1995.06796 +24003,14,京王高尾線,ケイオウタカオセン,京王高尾線,Keio Takao Line,Keio Takao Line,京王高尾线,게이오 다카오선,#CA0073,2,KO,,,,#CA0073,,,,KEIO,,,,0,24003,1403.25349 +24004,14,京王競馬場線,ケイオウケイバジョウセン,京王競馬場線,Keio Keibajo Line,Keio Keibajo Line,京王竞马场线,게이오 게이바조선,#CA0073,2,KO,,,,#CA0073,,,,KEIO,,,,0,24004,926.37779 +24005,14,京王動物園線,ケイオウドウブツエンセン,京王動物園線,Keio Dobutsuen Line,Keio Dobutsuen Line,京王动物园线,게이오 도부쓰엔선,#CA0073,2,KO,,,,#CA0073,,,,KEIO,,,,0,24005,1947.7838 +24006,14,京王井の頭線,ケイオウイノガシラセン,京王井の頭線,Keio Inokashira Line,Keio Inokashira Line,京王井之头线,게이오 이노카시라선,#000088,2,IN,,,,#000088,,,,KEIO,,,,0,24006,802.89748 +24007,14,京王新線,ケイオウシンセン,京王新線,Keio New Line,Keio New Line,京王新线,게이오 신선,#CA0073,2,KO,,,,#CA0073,,,,KEIO,,,,0,24007,1104.45578 +25001,15,小田急線,オダキュウセン,小田急小田原線,Odakyu Line,Odakyu Line,小田急线,오다큐선,#2F79BC,2,OH,,,,#2F79BC,,,,ODAKYU,,,,0,25001,1771.38549 +25002,15,小田急江ノ島線,オダキュウエノシマセン,小田急江ノ島線,Odakyu Enoshima Line,Odakyu Enoshima Line,小田急江之岛线,오다큐 에노시마선,#2D8BD0,2,OE,OH,,,#2F79BC,#2F79BC,,,ODAKYU,ODAKYU,,,0,25002,1685.25136 +25003,15,小田急多摩線,オダキュウタマセン,小田急多摩線,Odakyu Tama Line,Odakyu Tama Line,小田急多摩线,오다큐 다마선,#2D8BD0,2,OT,OH,,,#2F79BC,#2F79BC,,,ODAKYU,ODAKYU,,,0,25003,1494.74821 +26001,16,東急東横線,トウキュウトウヨコセン,東急東横線,Tokyu Toyoko Line,Tokyu Toyoko Line,东急东横线,도큐 도요코선,#EE0011,2,TY,,,,#EE0011,,,,REVERSED_SQUARE,,,,0,26001,1189.02738 +26002,16,東急目黒線,トウキュウメグロセン,東急目黒線,Tokyu Meguro Line,Tokyu Meguro Line,东急目黑线,도큐 메구로선,#2C94B6,2,MG,,,,#2C94B6,,,,REVERSED_SQUARE,,,,0,26002,985.08403 +26003,16,東急田園都市線,トウキュウデンエントシセン,東急田園都市線,Tokyu Den-en-toshi Line,Tokyu Den-en-toshi Line,东急田园都市线,도큐 덴엔토시선,#018D54,2,DT,,,,#018D54,,,,REVERSED_SQUARE,,,,0,26003,1191.38645 +26004,16,東急大井町線,トウキュウオオイマチセン,東急大井町線,Tokyu Oimachi Line,Tokyu Oimachi Line,东急大井町线,도큐 오이마치선,#FD9A3D,2,OM,,,,#FD9A3D,,,,REVERSED_SQUARE,,,,0,26004,722.37423 +26005,16,東急池上線,トウキュウイケガミセン,東急池上線,Tokyu Ikegami Line,Tokyu Ikegami Line,东急池上线,도큐 이케가미선,#DE65B0,2,IK,,,,#DE65B0,,,,REVERSED_SQUARE,,,,0,26005,761.78481 +26006,16,東急多摩川線,トウキュウタマガワセン,東急多摩川線,Tokyu Tamagawa Line,Tokyu Tamagawa Line,东急多摩川线,도큐 다마가와선,#A3016E,2,TM,,,,#A3016E,,,,REVERSED_SQUARE,,,,0,26006,919.05782 26007,16,東急世田谷線,トウキュウセタガヤセン,東急世田谷線,Tokyu Setagaya Line,Tokyu Setagaya Line,东急世田谷线,도큐 세타가야선,#FCC70D,4,SG,,,,#FCC70D,,,,REVERSED_SQUARE_DARK_TEXT,,,,0,26007,679.48258 -26008,16,東急こどもの国線,トウキュウコドモノクニセン,東急こどもの国線,Tokyu Kodomonokuni Line,Tokyu Kodomonokuni Line,东急子供之国线,도큐 고도모노쿠니선,#0068B7,2,KD,,,,#0068B7,,,,REVERSED_SQUARE,,,,0,26008,1719.44388 -26009,16,東急新横浜線,トウキュウシンヨコハマセン,東急新横浜線,Tokyu Shin-yokohama Line,Tokyu Shin-yokohama Line,东急新横滨线,도큐 신요코하마선,#890D84,2,SH,,,,#890D84,,,,REVERSED_SQUARE,,,,0,26009,3251.96596 -27001,17,京急本線,ケイキュウホンセン,京急本線,Keikyu Main Line,Keikyu Main Line,京急本线,게이큐 본선,#00CCFF,2,KK,A,,,#00CCFF,#EC6E65,,,KEIKYU,ROUND,,,0,27001,1288.54078 -27002,17,京急空港線,ケイキュウクウコウセン,京急空港線,Keikyu Airport Line,Keikyu Airport Line,京急机场线,게이큐 공항선,#00CCFF,2,KK,,,,#00CCFF,,,,KEIKYU,,,,0,27002,1198.21904 -27003,17,京急大師線,ケイキュウダイシセン,京急大師線,Keikyu Daishi Line,Keikyu Daishi Line,京急大师线,게이큐 다이시선,#00CCFF,2,KK,,,,#00CCFF,,,,KEIKYU,,,,0,27003,822.28876 -27004,17,京急逗子線,ケイキュウズシセン,京急逗子線,Keikyu Zushi Line,Keikyu Zushi Line,京急逗子线,게이큐 즈시선,#00CCFF,2,KK,,,,#00CCFF,,,,KEIKYU,,,,0,27004,2100.61337 -27005,17,京急久里浜線,ケイキュウクリハマセン,京急久里浜線,Keikyu Kurihama Line,Keikyu Kurihama Line,京急久里滨线,게이큐 구리하마선,#00CCFF,2,KK,,,,#00CCFF,,,,KEIKYU,,,,0,27005,1852.02809 -28001,18,東京メトロ銀座線,トウキョウメトロギンザセン,東京メトロ銀座線,Tokyo Metro Ginza Line,Tokyo Metro Ginza Line,银座线,긴자선,#F39700,3,G,,,,#F39700,,,,ROUND,,,,0,28001,831.06096 +26008,16,東急こどもの国線,トウキュウコドモノクニセン,東急こどもの国線,Tokyu Kodomonokuni Line,Tokyu Kodomonokuni Line,东急子供之国线,도큐 고도모노쿠니선,#0068B7,2,KD,,,,#0068B7,,,,REVERSED_SQUARE,,,,0,26008,1536.1571 +26009,16,東急新横浜線,トウキュウシンヨコハマセン,東急新横浜線,Tokyu Shin-yokohama Line,Tokyu Shin-yokohama Line,东急新横滨线,도큐 신요코하마선,#890D84,2,SH,,,,#890D84,,,,REVERSED_SQUARE,,,,0,26009,2873.29633 +27001,17,京急本線,ケイキュウホンセン,京急本線,Keikyu Main Line,Keikyu Main Line,京急本线,게이큐 본선,#00CCFF,2,KK,A,,,#00CCFF,#EC6E65,,,KEIKYU,ROUND,,,0,27001,1137.89949 +27002,17,京急空港線,ケイキュウクウコウセン,京急空港線,Keikyu Airport Line,Keikyu Airport Line,京急机场线,게이큐 공항선,#00CCFF,2,KK,,,,#00CCFF,,,,KEIKYU,,,,0,27002,1041.9296 +27003,17,京急大師線,ケイキュウダイシセン,京急大師線,Keikyu Daishi Line,Keikyu Daishi Line,京急大师线,게이큐 다이시선,#00CCFF,2,KK,,,,#00CCFF,,,,KEIKYU,,,,0,27003,727.04466 +27004,17,京急逗子線,ケイキュウズシセン,京急逗子線,Keikyu Zushi Line,Keikyu Zushi Line,京急逗子线,게이큐 즈시선,#00CCFF,2,KK,,,,#00CCFF,,,,KEIKYU,,,,0,27004,1900.49399 +27005,17,京急久里浜線,ケイキュウクリハマセン,京急久里浜線,Keikyu Kurihama Line,Keikyu Kurihama Line,京急久里滨线,게이큐 구리하마선,#00CCFF,2,KK,,,,#00CCFF,,,,KEIKYU,,,,0,27005,1634.45156 +28001,18,東京メトロ銀座線,トウキョウメトロギンザセン,東京メトロ銀座線,Tokyo Metro Ginza Line,Tokyo Metro Ginza Line,银座线,긴자선,#F39700,3,G,,,,#F39700,,,,ROUND,,,,0,28001,780.46154 28002,18,東京メトロ丸ノ内線,トウキョウメトロマルノウチセン,東京メトロ丸ノ内線,Tokyo Metro Marunouchi Line,Tokyo Metro Marunouchi Line,丸之内线,마루노우치선,#E60012,3,M,Mb,,,#E60012,#E60012,,,ROUND,ROUND,,,0,28002,1232.26083 -28003,18,東京メトロ日比谷線,トウキョウメトロヒビヤセン,東京メトロ日比谷線,Tokyo Metro Hibiya Line,Tokyo Metro Hibiya Line,日比谷线,히비야선,#9CAEB7,3,H,,,,#9CAEB7,,,,ROUND,,,,0,28003,1047.30996 -28004,18,東京メトロ東西線,トウキョウメトロトウザイセン,東京メトロ東西線,Tokyo Metro Tozai Line,Tokyo Metro Tozai Line,东西线,도자이선,#00A7DB,3,T,,,,#00A7DB,,,,ROUND,,,,0,28004,1492.96386 +28003,18,東京メトロ日比谷線,トウキョウメトロヒビヤセン,東京メトロ日比谷線,Tokyo Metro Hibiya Line,Tokyo Metro Hibiya Line,日比谷线,히비야선,#9CAEB7,3,H,,,,#9CAEB7,,,,ROUND,,,,0,28003,927.06703 +28004,18,東京メトロ東西線,トウキョウメトロトウザイセン,東京メトロ東西線,Tokyo Metro Tozai Line,Tokyo Metro Tozai Line,东西线,도자이선,#00A7DB,3,T,,,,#00A7DB,,,,ROUND,,,,0,28004,1376.11236 28005,18,東京メトロ千代田線,トウキョウメトロチヨダセン,東京メトロ千代田線,Tokyo Metro Chiyoda Line,Tokyo Metro Chiyoda Line,千代田线,지요다선,#009944,3,C,,,,#009944,,,,ROUND,,,,0,28005,1292.70369 -28006,18,東京メトロ有楽町線,トウキョウメトロユウラクチョウセン,東京メトロ有楽町線,Tokyo Metro Yurakucho Line,Tokyo Metro Yurakucho Line,有乐町线,유라쿠초선,#C1A470,3,Y,,,,#C1A470,,,,ROUND,,,,0,28006,1308.69669 -28008,18,東京メトロ半蔵門線,トウキョウメトロハンゾウモンセン,東京メトロ半蔵門線,Tokyo Metro Hanzomon Line,Tokyo Metro Hanzomon Line,半藏门线,한조몬선,#9B7CB6,3,Z,,,,#9B7CB6,,,,ROUND,,,,0,28008,1304.40096 -28009,18,東京メトロ南北線,トウキョウメトロナンボクセン,東京メトロ南北線,Tokyo Metro Namboku Line,Tokyo Metro Namboku Line,南北线,난보쿠선,#00ADA9,3,N,,,,#00ADA9,,,,ROUND,,,,0,28009,1221.80115 -28010,18,東京メトロ副都心線,トウキョウメトロフクトシンセン,東京メトロ副都心線,Tokyo Metro Fukutoshin Line,Tokyo Metro Fukutoshin Line,副都心线,후쿠토신선,#BB641D,3,F,,,,#BB641D,,,,ROUND,,,,0,28010,1410.03115 -29001,19,相鉄本線,ソウテツホンセン,相鉄本線,Sotetsu Main Line,Sotetsu Main Line,相铁本线,소테쓰 본선,#000080,2,SO,,,,#0967B4,,,,REVERSED_SQUARE,,,,0,29001,1611.21641 -29002,19,相鉄いずみ野線,ソウテツイズミノセン,相鉄いずみ野線,Sotetsu Izumino Line,Sotetsu Izumino Line,相铁泉野线,소테쓰 이즈미노선,#000080,2,SO,,,,#0967B4,,,,REVERSED_SQUARE,,,,0,29002,1676.38470 +28006,18,東京メトロ有楽町線,トウキョウメトロユウラクチョウセン,東京メトロ有楽町線,Tokyo Metro Yurakucho Line,Tokyo Metro Yurakucho Line,有乐町线,유라쿠초선,#C1A470,3,Y,,,,#C1A470,,,,ROUND,,,,0,28006,1208.42847 +28008,18,東京メトロ半蔵門線,トウキョウメトロハンゾウモンセン,東京メトロ半蔵門線,Tokyo Metro Hanzomon Line,Tokyo Metro Hanzomon Line,半藏门线,한조몬선,#9B7CB6,3,Z,,,,#9B7CB6,,,,ROUND,,,,0,28008,1283.41956 +28009,18,東京メトロ南北線,トウキョウメトロナンボクセン,東京メトロ南北線,Tokyo Metro Namboku Line,Tokyo Metro Namboku Line,南北线,난보쿠선,#00ADA9,3,N,,,,#00ADA9,,,,ROUND,,,,0,28009,1144.78154 +28010,18,東京メトロ副都心線,トウキョウメトロフクトシンセン,東京メトロ副都心線,Tokyo Metro Fukutoshin Line,Tokyo Metro Fukutoshin Line,副都心线,후쿠토신선,#BB641D,3,F,,,,#BB641D,,,,ROUND,,,,0,28010,1327.77135 +29001,19,相鉄本線,ソウテツホンセン,相鉄本線,Sotetsu Main Line,Sotetsu Main Line,相铁本线,소테쓰 본선,#000080,2,SO,,,,#0967B4,,,,REVERSED_SQUARE,,,,0,29001,1417.12757 +29002,19,相鉄いずみ野線,ソウテツイズミノセン,相鉄いずみ野線,Sotetsu Izumino Line,Sotetsu Izumino Line,相铁泉野线,소테쓰 이즈미노선,#000080,2,SO,,,,#0967B4,,,,REVERSED_SQUARE,,,,0,29002,1555.09015 29003,19,相鉄・JR直通線,ソウテツ・ジェイアールチョクツウセン,相鉄・JR直通線,Sotetsu-JR Link Line,Sotetsu-JR Link Line,相铁·JR直通线,소테츠·JR직통선,#000080,2,SO,JS,JA,,#0967B4,#E31F26,#00B48D,,REVERSED_SQUARE,SQUARE,SQUARE,,0,29003,3270.97376 -29004,19,相鉄新横浜線,ソウテツシンヨコハマセン,相鉄新横浜線,Sotetsu Shin-yokohama Line,Sotetsu Shin-yokohama Line,相铁新横滨线,소테츠 신요코하마선,#000080,2,SO,,,,#0967B4,,,,REVERSED_SQUARE,,,,0,29004,3493.87213 -30001,20,名鉄名古屋本線,メイテツナゴヤホンセン,名鉄名古屋本線,Nagoya Line,Nagoya Line,名古屋本线,나고야 본선,#D12027,2,NH,,,,#D12027,,,,HALF_SQUARE,,,,0,30001,1904.95450 -30002,20,名鉄豊川線,メイテツトヨカワセン,名鉄豊川線,Toyokawa Line,Toyokawa Line,丰川线,도요카와 선,#D12027,2,TK,NH,,,#D12027,#D12027,,,HALF_SQUARE,HALF_SQUARE,,,0,30002,1923.02098 -30003,20,名鉄西尾線,メイテツニシオセン,名鉄西尾線,Nishio Line,Nishio Line,西尾线,니시오 선,#654E9E,2,GN,NH,,,#654E9E,#D12027,,,HALF_SQUARE,HALF_SQUARE,,,0,30003,2073.86910 -30004,20,名鉄蒲郡線,メイテツガマゴオリセン,名鉄蒲郡線,Gamagori Line,Gamagori Line,蒲郡线,가마고리 선,#654E9E,2,GN,NH,,,#654E9E,#D12027,,,HALF_SQUARE,HALF_SQUARE,,,0,30004,2127.01349 -30005,20,名鉄三河線,メイテツミカワセン,名鉄三河線,Mikawa Line,Mikawa Line,三河线,미카와 선,#9EB03A,2,MY,NH,MU,,#9EB03A,#D12027,#654E9E,,HALF_SQUARE,HALF_SQUARE,HALF_SQUARE,,0,30005,1970.99044 -30006,20,名鉄豊田線,メイテツトヨタセン,名鉄豊田線,Toyota Line,Toyota Line,丰田线,도요타 선,#9EB03A,2,TT,MY,,,#9EB03A,#9EB03A,,,HALF_SQUARE,HALF_SQUARE,,,0,30006,2336.21958 +29004,19,相鉄新横浜線,ソウテツシンヨコハマセン,相鉄新横浜線,Sotetsu Shin-yokohama Line,Sotetsu Shin-yokohama Line,相铁新横滨线,소테츠 신요코하마선,#000080,2,SO,,,,#0967B4,,,,REVERSED_SQUARE,,,,0,29004,3065.75393 +30001,20,名鉄名古屋本線,メイテツナゴヤホンセン,名鉄名古屋本線,Nagoya Line,Nagoya Line,名古屋本线,나고야 본선,#D12027,2,NH,,,,#D12027,,,,HALF_SQUARE,,,,0,30001,1662.80435 +30002,20,名鉄豊川線,メイテツトヨカワセン,名鉄豊川線,Toyokawa Line,Toyokawa Line,丰川线,도요카와 선,#D12027,2,TK,NH,,,#D12027,#D12027,,,HALF_SQUARE,HALF_SQUARE,,,0,30002,1731.21241 +30003,20,名鉄西尾線,メイテツニシオセン,名鉄西尾線,Nishio Line,Nishio Line,西尾线,니시오 선,#654E9E,2,GN,NH,,,#654E9E,#D12027,,,HALF_SQUARE,HALF_SQUARE,,,0,30003,1864.89715 +30004,20,名鉄蒲郡線,メイテツガマゴオリセン,名鉄蒲郡線,Gamagori Line,Gamagori Line,蒲郡线,가마고리 선,#654E9E,2,GN,NH,,,#654E9E,#D12027,,,HALF_SQUARE,HALF_SQUARE,,,0,30004,1890.88623 +30005,20,名鉄三河線,メイテツミカワセン,名鉄三河線,Mikawa Line,Mikawa Line,三河线,미카와 선,#9EB03A,2,MY,NH,MU,,#9EB03A,#D12027,#654E9E,,HALF_SQUARE,HALF_SQUARE,HALF_SQUARE,,0,30005,1770.04093 +30006,20,名鉄豊田線,メイテツトヨタセン,名鉄豊田線,Toyota Line,Toyota Line,丰田线,도요타 선,#9EB03A,2,TT,MY,,,#9EB03A,#9EB03A,,,HALF_SQUARE,HALF_SQUARE,,,0,30006,2044.5201 30007,20,名鉄常滑・空港線,メイテツトコナメクウコウセン,名鉄空港線,Airport Line,Airport Line,机场线,쿠코 선,#1065AB,2,TA,NH,,,#1065AB,#D12027,,,HALF_SQUARE,HALF_SQUARE,,,0,30007,2261.47887 -30008,20,名鉄常滑線,メイテツトコナメセン,名鉄常滑線,Tokoname Line,Tokoname Line,常滑线,도코나메 선,#1065AB,2,TA,NH,,,#1065AB,#D12027,,,HALF_SQUARE,HALF_SQUARE,,,0,30008,1585.95157 -30009,20,名鉄河和線,メイテツコウワセン,名鉄河和線,Kowa Line,Kowa Line,河和线,고와 선,#2A9DD8,2,KC,TA,,,#2A9DD8,#1065AB,,,HALF_SQUARE,HALF_SQUARE,,,0,30009,1520.82107 -30010,20,名鉄知多新線,メイテツチタシンセン,名鉄知多新線,Chita Line,Chita Line,知多新线,지타 신선,#2A9DD8,2,KC,TA,,,#2A9DD8,#1065AB,,,HALF_SQUARE,HALF_SQUARE,,,0,30010,2883.58427 -30011,20,名鉄築港線,メイテツチッコウセン,名鉄築港線,Chikko Line,Chikko Line,筑港线,짓코 선,#727171,2,CH,TA,,,#727171,#1065AB,,,HALF_SQUARE,HALF_SQUARE,,,0,30011,1509.98236 -30012,20,名鉄瀬戸線,メイテツセトセン,名鉄瀬戸線,Seto Line,Seto Line,濑户线,세토 선,#990099,2,ST,,,,#7C2982,,,,HALF_SQUARE,,,,0,30012,1184.93250 -30013,20,名鉄津島線,メイテツツシマセン,名鉄津島線,Tsushima Line,Tsushima Line,津岛线,쓰시마 선,#E85624,2,TB,NH,,,#E85624,#D12027,,,HALF_SQUARE,HALF_SQUARE,,,0,30013,1888.07939 -30014,20,名鉄尾西線,メイテツビサイセン,名鉄尾西線,Bisai Line,Bisai Line,尾西线,비사이 선,#E85624,2,TB,BS,NH,,#E85624,#E85624,#D12027,,HALF_SQUARE,HALF_SQUARE,HALF_SQUARE,,0,30014,1562.63460 +30008,20,名鉄常滑線,メイテツトコナメセン,名鉄常滑線,Tokoname Line,Tokoname Line,常滑线,도코나메 선,#1065AB,2,TA,NH,,,#1065AB,#D12027,,,HALF_SQUARE,HALF_SQUARE,,,0,30008,1381.83694 +30009,20,名鉄河和線,メイテツコウワセン,名鉄河和線,Kowa Line,Kowa Line,河和线,고와 선,#2A9DD8,2,KC,TA,,,#2A9DD8,#1065AB,,,HALF_SQUARE,HALF_SQUARE,,,0,30009,1495.95881 +30010,20,名鉄知多新線,メイテツチタシンセン,名鉄知多新線,Chita Line,Chita Line,知多新线,지타 신선,#2A9DD8,2,KC,TA,,,#2A9DD8,#1065AB,,,HALF_SQUARE,HALF_SQUARE,,,0,30010,2739.0839 +30011,20,名鉄築港線,メイテツチッコウセン,名鉄築港線,Chikko Line,Chikko Line,筑港线,짓코 선,#727171,2,CH,TA,,,#727171,#1065AB,,,HALF_SQUARE,HALF_SQUARE,,,0,30011,1313.02814 +30012,20,名鉄瀬戸線,メイテツセトセン,名鉄瀬戸線,Seto Line,Seto Line,濑户线,세토 선,#990099,2,ST,,,,#7C2982,,,,HALF_SQUARE,,,,0,30012,1050.07891 +30013,20,名鉄津島線,メイテツツシマセン,名鉄津島線,Tsushima Line,Tsushima Line,津岛线,쓰시마 선,#E85624,2,TB,NH,,,#E85624,#D12027,,,HALF_SQUARE,HALF_SQUARE,,,0,30013,1669.75524 +30014,20,名鉄尾西線,メイテツビサイセン,名鉄尾西線,Bisai Line,Bisai Line,尾西线,비사이 선,#E85624,2,TB,BS,NH,,#E85624,#E85624,#D12027,,HALF_SQUARE,HALF_SQUARE,HALF_SQUARE,,0,30014,1451.99735 30015,20,名鉄犬山線,メイテツイヌヤマセン,名鉄犬山線,Inuyama Line,Inuyama Line,犬山线,이누야마 선,#018B44,2,IY,NH,,,#018B44,#D12027,,,HALF_SQUARE,HALF_SQUARE,,,0,30015,1777.76181 -30016,20,名鉄各務原線,メイテツカカミガハラセン,名鉄各務原線,Kakamigahara Line,Kakamigahara Line,各务原线,가카미가하라 선,#018B44,2,KG,IY,,,#018B44,#018B44,,,HALF_SQUARE,HALF_SQUARE,,,0,30016,1167.59488 -30017,20,名鉄広見線,メイテツヒロミセン,名鉄広見線,Hiromi Line,Hiromi Line,广见线,히로미 선,#018B44,2,HM,IY,,,#018B44,#018B44,,,HALF_SQUARE,HALF_SQUARE,,,0,30017,2235.48301 -30018,20,名鉄小牧線,メイテツコマキセン,名鉄小牧線,Komaki Line,Komaki Line,小牧线,고마키 선,#DA5290,2,KM,IY,,,#DA5290,#018B44,,,HALF_SQUARE,HALF_SQUARE,,,0,30018,1791.76787 +30016,20,名鉄各務原線,メイテツカカミガハラセン,名鉄各務原線,Kakamigahara Line,Kakamigahara Line,各务原线,가카미가하라 선,#018B44,2,KG,IY,,,#018B44,#018B44,,,HALF_SQUARE,HALF_SQUARE,,,0,30016,1021.66184 +30017,20,名鉄広見線,メイテツヒロミセン,名鉄広見線,Hiromi Line,Hiromi Line,广见线,히로미 선,#018B44,2,HM,IY,,,#018B44,#018B44,,,HALF_SQUARE,HALF_SQUARE,,,0,30017,2136.41769 +30018,20,名鉄小牧線,メイテツコマキセン,名鉄小牧線,Komaki Line,Komaki Line,小牧线,고마키 선,#DA5290,2,KM,IY,,,#DA5290,#018B44,,,HALF_SQUARE,HALF_SQUARE,,,0,30018,1558.11789 30019,20,犬山モノレール,イヌヤマモノレール,名鉄モンキーパークモノレール線,Inuyama Monorail,Inuyama Monorail,犬山单轨电车,이누야마 모노레일,#808080,5,,,,,,,,,,,,,2,30019,617.56367 -30020,20,名鉄竹鼻線,メイテツタケハナセン,名鉄竹鼻線,Takehana Line,Takehana Line,竹鼻线,다케하나 선,#D7A629,2,TH,NH,,,#D7A629,#D12027,,,HALF_SQUARE,HALF_SQUARE,,,0,30020,1398.37115 -30021,20,名鉄羽島線,メイテツハシマセン,名鉄羽島線,Hashima Line,Hashima Line,羽岛线,하시마 선,#D7A629,2,TH,NH,,,#D7A629,#D12027,,,HALF_SQUARE,HALF_SQUARE,,,0,30021,1367.32051 -31001,21,近鉄難波線,キンテツナンバセン,近鉄難波線,Kintetsu Namba Line,Kintetsu Namba Line,近铁难波线,긴테쓰 난바선,#008000,2,A,,,,#D21644,,,,KINTETSU,,,,0,31001,1356.92664 -31002,21,近鉄橿原線,キンテツカシハラセン,近鉄橿原線,Kintetsu Kashihara Line,Kintetsu Kashihara Line,近铁橿原线,긴테쓰 가시하라선,#DEA83F,2,B,,,,#FAB202,,,,KINTETSU,,,,0,31002,1689.52313 -31003,21,近鉄南大阪線,キンテツミナミオオサカセン,近鉄南大阪線,Kintetsu Minami-Osaka Line,Kintetsu Minami-Osaka Line,近铁南大阪线,긴테쓰 미나미오사카선,#FF1493,2,F,,,,#028E46,,,,KINTETSU,,,,0,31003,1623.28971 +30020,20,名鉄竹鼻線,メイテツタケハナセン,名鉄竹鼻線,Takehana Line,Takehana Line,竹鼻线,다케하나 선,#D7A629,2,TH,NH,,,#D7A629,#D12027,,,HALF_SQUARE,HALF_SQUARE,,,0,30020,1248.15533 +30021,20,名鉄羽島線,メイテツハシマセン,名鉄羽島線,Hashima Line,Hashima Line,羽岛线,하시마 선,#D7A629,2,TH,NH,,,#D7A629,#D12027,,,HALF_SQUARE,HALF_SQUARE,,,0,30021,1280.75978 +31001,21,近鉄難波線,キンテツナンバセン,近鉄難波線,Kintetsu Namba Line,Kintetsu Namba Line,近铁难波线,긴테쓰 난바선,#008000,2,A,,,,#D21644,,,,KINTETSU,,,,0,31001,1058.17493 +31002,21,近鉄橿原線,キンテツカシハラセン,近鉄橿原線,Kintetsu Kashihara Line,Kintetsu Kashihara Line,近铁橿原线,긴테쓰 가시하라선,#DEA83F,2,B,,,,#FAB202,,,,KINTETSU,,,,0,31002,1477.6481 +31003,21,近鉄南大阪線,キンテツミナミオオサカセン,近鉄南大阪線,Kintetsu Minami-Osaka Line,Kintetsu Minami-Osaka Line,近铁南大阪线,긴테쓰 미나미오사카선,#FF1493,2,F,,,,#028E46,,,,KINTETSU,,,,0,31003,1440.61933 31004,21,近鉄養老線,キンテツヨウロウセン,近鉄養老線,Kintetsu Yoro Line,Kintetsu Yoro Line,近铁养老线,긴테쓰 요로선,#228B22,2,,,,,,,,,,,,,2,31004,2398.89369 -31005,21,近鉄大阪線,キンテツオオサカセン,近鉄大阪線,Kintetsu Osaka Line,Kintetsu Osaka Line,近铁大阪线,긴테쓰 오사카선,#B33249,2,D,,,,#4694D1,,,,KINTETSU,,,,0,31005,2561.40952 +31005,21,近鉄大阪線,キンテツオオサカセン,近鉄大阪線,Kintetsu Osaka Line,Kintetsu Osaka Line,近铁大阪线,긴테쓰 오사카선,#B33249,2,D,,,,#4694D1,,,,KINTETSU,,,,0,31005,2250.1387 31006,21,近鉄伊賀線,キンテツイガセン,近鉄伊賀線,Kintetsu Iga Line,Kintetsu Iga Line,近铁伊贺线,긴테쓰 이가선,#808080,2,,,,,,,,,,,,,2,31006,1351.96836 -31007,21,近鉄吉野線,キンテツヨシノセン,近鉄吉野線,Kintetsu Yoshino Line,Kintetsu Yoshino Line,近铁吉野线,긴테쓰 요시노선,#339932,2,F,,,,#028E46,,,,KINTETSU,,,,0,31007,1813.23616 -31008,21,近鉄湯の山線,キンテツユノヤマセン,近鉄湯の山線,Kintetsu Yunoyama Line,Kintetsu Yunoyama Line,近铁汤之山线,긴테쓰 유노야마선,#339932,2,K,,,,#153F97,,,,KINTETSU,,,,0,31008,1879.79771 -31009,21,近鉄山田線,キンテツヤマダセン,近鉄山田線,Kintetsu Yamada Line,Kintetsu Yamada Line,近铁山田线,긴테쓰 야마다선,#003399,2,M,,,,#00B3C1,,,,KINTETSU,,,,0,31009,2468.85892 -31010,21,近鉄鳥羽線,キンテツトバセン,近鉄鳥羽線,Kintetsu Toba Line,Kintetsu Toba Line,近铁鸟羽线,긴테쓰 도바선,#339932,2,M,,,,#00B3C1,,,,KINTETSU,,,,0,31010,3613.65872 -31011,21,近鉄天理線,キンテツテンリセン,近鉄天理線,Kintetsu Tenri Line,Kintetsu Tenri Line,近铁天理线,긴테쓰 덴리선,#339932,2,H,,,,#FAB202,,,,KINTETSU,,,,0,31011,1682.67757 -31012,21,近鉄道明寺線,キンテツドウミョウジセン,近鉄道明寺線,Kintetsu Domyoji Line,Kintetsu Domyoji Line,近铁道明寺线,긴테쓰 도묘지선,#1B904A,2,N,,,,#028E46,,,,KINTETSU,,,,0,31012,1216.55857 -31013,247,内部線,ウツベセン,内部線,Utsube Line,Utsube Line,内部线,우쓰베선,#003399,2,,,,,,,,,,,,,0,31013,919.38313 -31014,247,八王子線,ハチオウジセン,八王子線,Hachioji Line,Hachioji Line,八王子线,하치오지선,#003399,2,,,,,,,,,,,,,0,31014,1148.85765 -31015,21,近鉄志摩線,キンテツシマセン,近鉄志摩線,Kintetsu Shima Line,Kintetsu Shima Line,近铁志摩线,긴테쓰 시마선,#FF00FF,2,M,,,,#00B3C1,,,,KINTETSU,,,,0,31015,1733.56629 -31016,21,近鉄生駒線,キンテツイコマセン,近鉄生駒線,Kintetsu Ikoma Line,Kintetsu Ikoma Line,近铁生驹线,긴테쓰 이코마선,#F6160D,2,G,,,,#D21644,,,,KINTETSU,,,,0,31016,1240.05304 -31017,21,近鉄田原本線,キンテツタワラモトセン,近鉄田原本線,Kintetsu Tawaramoto Line,Kintetsu Tawaramoto Line,近铁田原本线,긴테쓰 다와라모토선,#003399,2,I,,,,#FAB202,,,,KINTETSU,,,,0,31017,1594.58156 -31018,21,近鉄御所線,キンテツゴセセン,近鉄御所線,Kintetsu Gose Line,Kintetsu Gose Line,近铁御所线,긴테쓰 고세선,#F6160D,2,P,,,,#028E46,,,,KINTETSU,,,,0,31018,1920.71164 -31019,21,近鉄鈴鹿線,キンテツスズカセン,近鉄鈴鹿線,Kintetsu Suzuka Line,Kintetsu Suzuka Line,近铁铃鹿线,긴테쓰 스즈카선,#FF9900,2,L,,,,#153F97,,,,KINTETSU,,,,0,31019,2174.83915 -31020,21,近鉄奈良線,キンテツナラセン,近鉄奈良線,Kintetsu Nara Line,Kintetsu Nara Line,近铁奈良线,긴테쓰 나라선,#B33249,2,A,,,,#D21644,,,,KINTETSU,,,,0,31020,3099.49478 -31021,21,近鉄信貴線,キンテツシギセン,近鉄信貴線,Kintetsu Shigi Line,Kintetsu Shigi Line,近铁信贵线,긴테쓰 시기선,#339932,2,J,,,,#4694D1,,,,KINTETSU,,,,0,31021,1569.59370 -31022,21,近鉄長野線,キンテツナガノセン,近鉄長野線,Kintetsu Nagano Line,Kintetsu Nagano Line,近铁长野线,긴테쓰 나가노선,#003399,2,O,,,,#028E46,,,,KINTETSU,,,,0,31022,1996.77034 -31023,21,近鉄けいはんな線,キンテツケイハンナセン,近鉄けいはんな線,Kintetsu Keihanna Line,Kintetsu Keihanna Line,近铁京阪奈线,긴테쓰 게이한나선,#019A66,2,C,,,,#32CD32,,,,KINTETSU,,,,0,31023,2766.42058 -31024,21,西信貴ケーブル,ニシシギケーブル,近鉄西信貴鋼索線,Nishishigi Cable,Nishishigi Cable,西信贵缆车,니시시기 케이블,#DDDDDD,0,Z,,,,#DD9966,,,,KINTETSU,,,,0,31024,1468.44810 -31025,21,近鉄京都線,キンテツキョウトセン,近鉄京都線,Kintestu Kyoto Line,Kintestu Kyoto Line,近铁京都线,긴테쓰 교토선,#DEA83F,2,B,,,,#FAB202,,,,KINTETSU,,,,0,31025,1610.66106 +31007,21,近鉄吉野線,キンテツヨシノセン,近鉄吉野線,Kintetsu Yoshino Line,Kintetsu Yoshino Line,近铁吉野线,긴테쓰 요시노선,#339932,2,F,,,,#028E46,,,,KINTETSU,,,,0,31007,1630.97696 +31008,21,近鉄湯の山線,キンテツユノヤマセン,近鉄湯の山線,Kintetsu Yunoyama Line,Kintetsu Yunoyama Line,近铁汤之山线,긴테쓰 유노야마선,#339932,2,K,,,,#153F97,,,,KINTETSU,,,,0,31008,1656.83316 +31009,21,近鉄山田線,キンテツヤマダセン,近鉄山田線,Kintetsu Yamada Line,Kintetsu Yamada Line,近铁山田线,긴테쓰 야마다선,#003399,2,M,,,,#00B3C1,,,,KINTETSU,,,,0,31009,2153.37624 +31010,21,近鉄鳥羽線,キンテツトバセン,近鉄鳥羽線,Kintetsu Toba Line,Kintetsu Toba Line,近铁鸟羽线,긴테쓰 도바선,#339932,2,M,,,,#00B3C1,,,,KINTETSU,,,,0,31010,3248.65164 +31011,21,近鉄天理線,キンテツテンリセン,近鉄天理線,Kintetsu Tenri Line,Kintetsu Tenri Line,近铁天理线,긴테쓰 덴리선,#339932,2,H,,,,#FAB202,,,,KINTETSU,,,,0,31011,1463.19789 +31012,21,近鉄道明寺線,キンテツドウミョウジセン,近鉄道明寺線,Kintetsu Domyoji Line,Kintetsu Domyoji Line,近铁道明寺线,긴테쓰 도묘지선,#1B904A,2,N,,,,#028E46,,,,KINTETSU,,,,0,31012,1057.87702 +31013,247,内部線,ウツベセン,内部線,Utsube Line,Utsube Line,内部线,우쓰베선,#003399,2,,,,,,,,,,,,,0,31013,799.46359 +31014,247,八王子線,ハチオウジセン,八王子線,Hachioji Line,Hachioji Line,八王子线,하치오지선,#003399,2,,,,,,,,,,,,,0,31014,999.00665 +31015,21,近鉄志摩線,キンテツシマセン,近鉄志摩線,Kintetsu Shima Line,Kintetsu Shima Line,近铁志摩线,긴테쓰 시마선,#FF00FF,2,M,,,,#00B3C1,,,,KINTETSU,,,,0,31015,1557.69034 +31016,21,近鉄生駒線,キンテツイコマセン,近鉄生駒線,Kintetsu Ikoma Line,Kintetsu Ikoma Line,近铁生驹线,긴테쓰 이코마선,#F6160D,2,G,,,,#D21644,,,,KINTETSU,,,,0,31016,1081.18343 +31017,21,近鉄田原本線,キンテツタワラモトセン,近鉄田原本線,Kintetsu Tawaramoto Line,Kintetsu Tawaramoto Line,近铁田原本线,긴테쓰 다와라모토선,#003399,2,I,,,,#FAB202,,,,KINTETSU,,,,0,31017,1407.31079 +31018,21,近鉄御所線,キンテツゴセセン,近鉄御所線,Kintetsu Gose Line,Kintetsu Gose Line,近铁御所线,긴테쓰 고세선,#F6160D,2,P,,,,#028E46,,,,KINTETSU,,,,0,31018,1730.13383 +31019,21,近鉄鈴鹿線,キンテツスズカセン,近鉄鈴鹿線,Kintetsu Suzuka Line,Kintetsu Suzuka Line,近铁铃鹿线,긴테쓰 스즈카선,#FF9900,2,L,,,,#153F97,,,,KINTETSU,,,,0,31019,1991.74931 +31020,21,近鉄奈良線,キンテツナラセン,近鉄奈良線,Kintetsu Nara Line,Kintetsu Nara Line,近铁奈良线,긴테쓰 나라선,#B33249,2,A,,,,#D21644,,,,KINTETSU,,,,0,31020,2902.78939 +31021,21,近鉄信貴線,キンテツシギセン,近鉄信貴線,Kintetsu Shigi Line,Kintetsu Shigi Line,近铁信贵线,긴테쓰 시기선,#339932,2,J,,,,#4694D1,,,,KINTETSU,,,,0,31021,1364.86409 +31022,21,近鉄長野線,キンテツナガノセン,近鉄長野線,Kintetsu Nagano Line,Kintetsu Nagano Line,近铁长野线,긴테쓰 나가노선,#003399,2,O,,,,#028E46,,,,KINTETSU,,,,0,31022,1755.60208 +31023,21,近鉄けいはんな線,キンテツケイハンナセン,近鉄けいはんな線,Kintetsu Keihanna Line,Kintetsu Keihanna Line,近铁京阪奈线,긴테쓰 게이한나선,#019A66,2,C,,,,#32CD32,,,,KINTETSU,,,,0,31023,2657.72168 +31024,21,西信貴ケーブル,ニシシギケーブル,近鉄西信貴鋼索線,Nishishigi Cable,Nishishigi Cable,西信贵缆车,니시시기 케이블,#DDDDDD,0,Z,,,,#DD9966,,,,KINTETSU,,,,0,31024,1468.4481 +31025,21,近鉄京都線,キンテツキョウトセン,近鉄京都線,Kintestu Kyoto Line,Kintestu Kyoto Line,近铁京都线,긴테쓰 교토선,#DEA83F,2,B,,,,#FAB202,,,,KINTETSU,,,,0,31025,1414.08952 31026,21,生駒ケーブル,イコマケーブル,近鉄生駒鋼索線,Ikoma Cable,Ikoma Cable,生驹缆车,이코마 케이블,#AA8861,0,Y,,,,#DD9966,,,,KINTETSU,,,,0,31026,586.83434 -31027,21,近鉄名古屋線,キンテツナゴヤセン,近鉄名古屋線,Kintetsu Nagoya Line,Kintetsu Nagoya Line,近铁名古屋线,긴테쓰 나고야선,#5E34F8,2,E,,,,#153F97,,,,KINTETSU,,,,0,31027,2055.47309 -32001,22,南海本線,ナンカイホンセン,南海本線,Nankai Main Line,Nankai Main Line,南海本线,난카이 본선,#3366CC,2,NK,,,,#000000,,,,NANKAI,,,,0,32001,1863.60901 -32002,22,南海空港線,ナンカイクウコウセン,南海空港線,Nankai Airport Line,Nankai Airport Line,南海机场线,난카이 공항선,#996699,2,NK,,,,#000000,,,,NANKAI,,,,0,32002,4276.35124 -32003,22,南海和歌山港線,ナンカイワカヤマコウセン,南海和歌山港線,Nankai Wakayamako Line,Nankai Wakayamako Line,南海和歌山港线,난카이 와카야마코선,#3366CC,2,NK,,,,#000000,,,,NANKAI,,,,0,32003,3282.99228 -32004,22,南海高師浜線,ナンカイタカシノハマセン,南海高師浜線,Nankai Takashinohama Line,Nankai Takashinohama Line,南海高师浜线,난카이 다카시노하마선,#3366CC,2,NK,,,,#000000,,,,NANKAI,,,,0,32004,723.02757 -32005,22,南海加太線,ナンカイカダセン,南海加太線,Nankai Kada Line,Nankai Kada Line,南海加太线,난카이 가다선,#3366CC,2,NK,,,,#000000,,,,NANKAI,,,,0,32005,1582.88510 -32006,22,南海多奈川線,ナンカイタナガワセン,南海多奈川線,Nankai Tanagawa Line,Nankai Tanagawa Line,南海多奈川线,난카이 다나가와선,#3366CC,2,NK,,,,#000000,,,,NANKAI,,,,0,32006,905.04315 -32007,22,南海高野線,ナンカイコウヤセン,南海高野線,Nankai Koya Line,Nankai Koya Line,南海高野线,난카이 고야선,#009900,2,NK,,,,#000000,,,,NANKAI,,,,0,32007,1633.18571 +31027,21,近鉄名古屋線,キンテツナゴヤセン,近鉄名古屋線,Kintetsu Nagoya Line,Kintetsu Nagoya Line,近铁名古屋线,긴테쓰 나고야선,#5E34F8,2,E,,,,#153F97,,,,KINTETSU,,,,0,31027,1808.75107 +32001,22,南海本線,ナンカイホンセン,南海本線,Nankai Main Line,Nankai Main Line,南海本线,난카이 본선,#3366CC,2,NK,,,,#000000,,,,NANKAI,,,,0,32001,1583.85625 +32002,22,南海空港線,ナンカイクウコウセン,南海空港線,Nankai Airport Line,Nankai Airport Line,南海机场线,난카이 공항선,#996699,2,NK,,,,#000000,,,,NANKAI,,,,0,32002,4277.22275 +32003,22,南海和歌山港線,ナンカイワカヤマコウセン,南海和歌山港線,Nankai Wakayamako Line,Nankai Wakayamako Line,南海和歌山港线,난카이 와카야마코선,#3366CC,2,NK,,,,#000000,,,,NANKAI,,,,0,32003,2854.7759 +32004,22,南海高師浜線,ナンカイタカシノハマセン,南海高師浜線,Nankai Takashinohama Line,Nankai Takashinohama Line,南海高师浜线,난카이 다카시노하마선,#3366CC,2,NK,,,,#000000,,,,NANKAI,,,,0,32004,713.94106 +32005,22,南海加太線,ナンカイカダセン,南海加太線,Nankai Kada Line,Nankai Kada Line,南海加太线,난카이 가다선,#3366CC,2,NK,,,,#000000,,,,NANKAI,,,,0,32005,1468.18212 +32006,22,南海多奈川線,ナンカイタナガワセン,南海多奈川線,Nankai Tanagawa Line,Nankai Tanagawa Line,南海多奈川线,난카이 다나가와선,#3366CC,2,NK,,,,#000000,,,,NANKAI,,,,0,32006,801.73389 +32007,22,南海高野線,ナンカイコウヤセン,南海高野線,Nankai Koya Line,Nankai Koya Line,南海高野线,난카이 고야선,#009900,2,NK,,,,#000000,,,,NANKAI,,,,0,32007,1508.08877 32008,22,南海高野山ケーブル,ナンカイコウヤサンケーブル,南海高野山ケーブル,Nankai Koyasan Cable,Nankai Koyasan Cable,南海高野山缆车,난카이 고야산 케이블,#009900,0,NK,,,,#000000,,,,NANKAI,,,,0,32008,962.35557 -32009,22,南海汐見橋線,ナンカイシオミバシセン,南海汐見橋線,Nankai Shiomibashi Line,Nankai Shiomibashi Line,南海汐见桥线,난카이 시오미바시선,#009900,2,NK,,,,#000000,,,,NANKAI,,,,0,32009,1076.87934 -33001,23,京阪本線,ケイハンホンセン,京阪本線,Keihan Main Line,Keihan Main Line,京阪本线,게이한 본선,#66CC33,2,KH,,,,#1D2088,,,,KEIHAN,,,,0,33001,1401.05426 -33002,23,京阪宇治線,ケイハンウジセン,京阪宇治線,Keihan Uji Line,Keihan Uji Line,京阪宇治线,게이한 우지선,#00AE00,2,KH,,,,#1D2089,,,,KEIHAN,,,,0,33002,1222.63460 -33003,23,京阪交野線,ケイハンカタノセン,京阪交野線,Keihan Katano Line,Keihan Katano Line,京阪交野线,게이한 가타노선,#00AE00,2,KH,,,,#1D2090,,,,KEIHAN,,,,0,33003,1088.11861 -33004,23,京阪鴨東線,ケイハンオウトウセン,京阪鴨東線,Keihan Oto Line,Keihan Oto Line,京阪鸭东线,게이한 오토선,#00AE00,2,KH,,,,#1D2091,,,,KEIHAN,,,,0,33004,1313.36657 -33005,23,石清水八幡宮参道ケーブル,イワシミズハチマングウサンドウケーブル,京阪鋼索線,Iwashimizuhachiman Sando Cable,Iwashimizuhachiman Sando Cable,石清水八幡宫参道缆车,이와시미즈하치만구 산도 케이블,#DBA75A,0,,,,,,,,,,,,,0,33005,445.18740 -33006,23,京阪石山坂本線,ケイハンイシヤマサカモトセン,京阪石山坂本線,Keihan Ishiyama Sakamoto Line,Keihan Ishiyama Sakamoto Line,京阪石山坂本线,게이한 이시야마사카모토선,#009933,4,OT,,,,#1D2091,,,,KEIHAN,,,,0,33006,851.92519 -33007,23,京阪京津線,ケイハンケイシンセン,京阪京津線,Keihan Keishin Line,Keihan Keishin Line,京阪京津线,게이한 게이신선,#FFCC00,4,OT,T,,,#1D2091,#FF4500,,,KEIHAN,REVERSED_ROUND,,,0,33007,1457.05532 -33008,23,京阪中之島線,ケイハンナカノシマセン,京阪中之島線,Keihan Nakanoshima Line,Keihan Nakanoshima Line,京阪中之岛线,게이한 나카노시마선,#00AE00,2,KH,,,,#1D2088,,,,KEIHAN,,,,0,33008,802.97185 -34001,24,阪急神戸本線,ハンキュウコウベホンセン,阪急神戸本線,Hankyu Kobe Main Line,Hankyu Kobe Main Line,阪急神户本线,한큐 고베 본선,#0000FF,2,HK,,,,#007AC4,,,,HANKYU,,,,0,34001,2434.67178 -34002,24,阪急宝塚本線,ハンキュウタカラヅカホンセン,阪急宝塚本線,Hankyu Takarazuka Main Line,Hankyu Takarazuka Main Line,阪急宝塚本线,한큐 다카라즈카 본선,#FF00CC,2,HK,,,,#F26627,,,,HANKYU,,,,0,34002,1519.64858 -34003,24,阪急京都本線,ハンキュウキョウトホンセン,阪急京都本線,Hankyu Kyoto Main Line,Hankyu Kyoto Main Line,阪急京都本线,한큐 교토 본선,#33CC00,2,HK,,,,#2A9B50,,,,HANKYU,,,,0,34003,2274.09021 -34004,24,阪急今津線,ハンキュウイマヅセン,阪急今津線,Hankyu Imazu Line,Hankyu Imazu Line,阪急今津线,한큐 이마즈선,#0000FF,2,HK,,,,#007AC4,,,,HANKYU,,,,0,34004,1171.94899 -34005,24,阪急甲陽線,ハンキュウコウヨウセン,阪急甲陽線,Hankyu Koyo Line,Hankyu Koyo Line,阪急甲阳线,한큐 고요선,#0000FF,2,HK,,,,#007AC4,,,,HANKYU,,,,0,34005,1197.47943 -34006,24,阪急伊丹線,ハンキュウイタミセン,阪急伊丹線,Hankyu Itami Line,Hankyu Itami Line,阪急伊丹线,한큐 이타미선,#0000FF,2,HK,,,,#007AC4,,,,HANKYU,,,,0,34006,1159.83027 -34007,24,阪急箕面線,ハンキュウミノオセン,阪急箕面線,Hankyu Mino Line,Hankyu Mino Line,阪急箕面线,한큐 미노오선,#FF00CC,2,HK,,,,#F26627,,,,HANKYU,,,,0,34007,1454.42899 -34008,24,阪急千里線,ハンキュウセンリセン,阪急千里線,Hankyu Senri Line,Hankyu Senri Line,阪急千里线,한큐 센리선,#33CC00,2,HK,K,,,#2A9B50,#814721,,,HANKYU,REVERSED_ROUND,,,0,34008,1496.59260 -34009,24,阪急嵐山線,ハンキュウアラシヤマセン,阪急嵐山線,Hankyu Arashiyama Line,Hankyu Arashiyama Line,阪急岚山线,한큐 아라시야마선,#33CC00,2,HK,,,,#2A9B50,,,,HANKYU,,,,0,34009,1516.24664 -35001,25,阪神本線,ハンシンホンセン,阪神本線,Hanshin Main Line,Hanshin Main Line,阪神本线,한신 본선,#FFA00E,2,HS,,,,#1F64B1,,,,HANSHIN,,,,0,35001,1131.18401 -35002,25,阪神なんば線,ハンシンナンバセン,阪神なんば線,Hanshin Namba Line,Hanshin Namba Line,阪神难波线,한신 난바선,#6BB5E6,2,HS,,,,#1F64B1,,,,HANSHIN,,,,0,35002,1139.28457 -35003,25,阪神武庫川線,ハンシンムコガワセン,阪神武庫川線,Hanshin Mukogawa Line,Hanshin Mukogawa Line,阪神武库川线,한신 무코가와선,#4A74B0,2,HS,,,,#1F64B1,,,,HANSHIN,,,,0,35003,653.33320 -36001,26,西鉄天神大牟田線,ニシテツテンジンオオムタセン,西鉄天神大牟田線,Nishitetsu Tenjin Omuta Line,Nishitetsu Tenjin Omuta Line,西铁天神大牟田线,니시테쓰 덴진오무타선,#1065AB,2,T,,,,#1065AB,,,,NISHITETSU,,,,0,36001,1744.69215 -36002,26,西鉄太宰府線,ニシテツダザイフセン,西鉄太宰府線,Nishitetsu Dazaifu Line,Nishitetsu Dazaifu Line,西铁太宰府线,니시테쓰 다자이후선,#FD8A02,2,D,T,,,#1065AB,#1065AB,,,NISHITETSU,NISHITETSU,,,0,36002,1300.04933 -36003,26,西鉄甘木線,ニシテツアマギセン,西鉄甘木線,Nishitetsu Amagi Line,Nishitetsu Amagi Line,西铁甘木线,니시테쓰 아마기선,#1065AB,2,A,T,,,#1065AB,,,,NISHITETSU,,,,0,36003,1804.23973 -36004,26,西鉄貝塚線,ニシテツカイヅカセン,西鉄貝塚線,Nishitetsu Kaizuka Line,Nishitetsu Kaizuka Line,西铁贝冢线,니시테쓰 가이즈카선,#1065AB,2,NK,,,,#1065AB,,,,NISHITETSU,,,,0,36004,1552.15120 -99101,101,札幌市営地下鉄東西線,サッポロシエイチカテツトウザイセン,札幌市営地下鉄東西線,Sapporo Municipal Subway Tozai Line,Sapporo Municipal Subway Tozai Line,札幌市营地铁东西线,삿포로 시영 지하철 도자이선,#FFA500,3,T,,,,#FFA500,,,,ROUND,,,,0,99101,1189.45005 -99102,101,札幌市営地下鉄南北線,サッポロシエイチカテツナンボクセン,札幌市営地下鉄南北線,Sapporo Municipal Subway Namboku Line,Sapporo Municipal Subway Namboku Line,札幌市营地铁南北线,삿포로 시영 지하철 난보쿠선,#008000,3,N,,,,#008000,,,,ROUND,,,,0,99102,1033.60987 +32009,22,南海汐見橋線,ナンカイシオミバシセン,南海汐見橋線,Nankai Shiomibashi Line,Nankai Shiomibashi Line,南海汐见桥线,난카이 시오미바시선,#009900,2,NK,,,,#000000,,,,NANKAI,,,,0,32009,936.41681 +33001,23,京阪本線,ケイハンホンセン,京阪本線,Keihan Main Line,Keihan Main Line,京阪本线,게이한 본선,#66CC33,2,KH,,,,#1D2088,,,,KEIHAN,,,,0,33001,1238.09532 +33002,23,京阪宇治線,ケイハンウジセン,京阪宇治線,Keihan Uji Line,Keihan Uji Line,京阪宇治线,게이한 우지선,#00AE00,2,KH,,,,#1D2089,,,,KEIHAN,,,,0,33002,1073.40383 +33003,23,京阪交野線,ケイハンカタノセン,京阪交野線,Keihan Katano Line,Keihan Katano Line,京阪交野线,게이한 가타노선,#00AE00,2,KH,,,,#1D2090,,,,KEIHAN,,,,0,33003,951.2774 +33004,23,京阪鴨東線,ケイハンオウトウセン,京阪鴨東線,Keihan Oto Line,Keihan Oto Line,京阪鸭东线,게이한 오토선,#00AE00,2,KH,,,,#1D2091,,,,KEIHAN,,,,0,33004,1142.05789 +33005,23,石清水八幡宮参道ケーブル,イワシミズハチマングウサンドウケーブル,京阪鋼索線,Iwashimizuhachiman Sando Cable,Iwashimizuhachiman Sando Cable,石清水八幡宫参道缆车,이와시미즈하치만구 산도 케이블,#DBA75A,0,,,,,,,,,,,,,0,33005,445.1874 +33006,23,京阪石山坂本線,ケイハンイシヤマサカモトセン,京阪石山坂本線,Keihan Ishiyama Sakamoto Line,Keihan Ishiyama Sakamoto Line,京阪石山坂本线,게이한 이시야마사카모토선,#009933,4,OT,,,,#1D2091,,,,KEIHAN,,,,0,33006,718.51102 +33007,23,京阪京津線,ケイハンケイシンセン,京阪京津線,Keihan Keishin Line,Keihan Keishin Line,京阪京津线,게이한 게이신선,#FFCC00,4,OT,T,,,#1D2091,#FF4500,,,KEIHAN,REVERSED_ROUND,,,0,33007,1195.90325 +33008,23,京阪中之島線,ケイハンナカノシマセン,京阪中之島線,Keihan Nakanoshima Line,Keihan Nakanoshima Line,京阪中之岛线,게이한 나카노시마선,#00AE00,2,KH,,,,#1D2088,,,,KEIHAN,,,,0,33008,751.54697 +34001,24,阪急神戸本線,ハンキュウコウベホンセン,阪急神戸本線,Hankyu Kobe Main Line,Hankyu Kobe Main Line,阪急神户本线,한큐 고베 본선,#0000FF,2,HK,,,,#007AC4,,,,HANKYU,,,,0,34001,2117.44985 +34002,24,阪急宝塚本線,ハンキュウタカラヅカホンセン,阪急宝塚本線,Hankyu Takarazuka Main Line,Hankyu Takarazuka Main Line,阪急宝塚本线,한큐 다카라즈카 본선,#FF00CC,2,HK,,,,#F26627,,,,HANKYU,,,,0,34002,1322.49263 +34003,24,阪急京都本線,ハンキュウキョウトホンセン,阪急京都本線,Hankyu Kyoto Main Line,Hankyu Kyoto Main Line,阪急京都本线,한큐 교토 본선,#33CC00,2,HK,,,,#2A9B50,,,,HANKYU,,,,0,34003,1740.94577 +34004,24,阪急今津線,ハンキュウイマヅセン,阪急今津線,Hankyu Imazu Line,Hankyu Imazu Line,阪急今津线,한큐 이마즈선,#0000FF,2,HK,,,,#007AC4,,,,HANKYU,,,,0,34004,1034.3153 +34005,24,阪急甲陽線,ハンキュウコウヨウセン,阪急甲陽線,Hankyu Koyo Line,Hankyu Koyo Line,阪急甲阳线,한큐 고요선,#0000FF,2,HK,,,,#007AC4,,,,HANKYU,,,,0,34005,1067.57925 +34006,24,阪急伊丹線,ハンキュウイタミセン,阪急伊丹線,Hankyu Itami Line,Hankyu Itami Line,阪急伊丹线,한큐 이타미선,#0000FF,2,HK,,,,#007AC4,,,,HANKYU,,,,0,34006,1008.54806 +34007,24,阪急箕面線,ハンキュウミノオセン,阪急箕面線,Hankyu Mino Line,Hankyu Mino Line,阪急箕面线,한큐 미노오선,#FF00CC,2,HK,,,,#F26627,,,,HANKYU,,,,0,34007,1300.92808 +34008,24,阪急千里線,ハンキュウセンリセン,阪急千里線,Hankyu Senri Line,Hankyu Senri Line,阪急千里线,한큐 센리선,#33CC00,2,HK,K,,,#2A9B50,#814721,,,HANKYU,REVERSED_ROUND,,,0,34008,1308.95808 +34009,24,阪急嵐山線,ハンキュウアラシヤマセン,阪急嵐山線,Hankyu Arashiyama Line,Hankyu Arashiyama Line,阪急岚山线,한큐 아라시야마선,#33CC00,2,HK,,,,#2A9B50,,,,HANKYU,,,,0,34009,1331.78071 +35001,25,阪神本線,ハンシンホンセン,阪神本線,Hanshin Main Line,Hanshin Main Line,阪神本线,한신 본선,#FFA00E,2,HS,,,,#1F64B1,,,,HANSHIN,,,,0,35001,986.45703 +35002,25,阪神なんば線,ハンシンナンバセン,阪神なんば線,Hanshin Namba Line,Hanshin Namba Line,阪神难波线,한신 난바선,#6BB5E6,2,HS,,,,#1F64B1,,,,HANSHIN,,,,0,35002,994.11761 +35003,25,阪神武庫川線,ハンシンムコガワセン,阪神武庫川線,Hanshin Mukogawa Line,Hanshin Mukogawa Line,阪神武库川线,한신 무코가와선,#4A74B0,2,HS,,,,#1F64B1,,,,HANSHIN,,,,0,35003,568.11583 +36001,26,西鉄天神大牟田線,ニシテツテンジンオオムタセン,西鉄天神大牟田線,Nishitetsu Tenjin Omuta Line,Nishitetsu Tenjin Omuta Line,西铁天神大牟田线,니시테쓰 덴진오무타선,#1065AB,2,T,,,,#1065AB,,,,NISHITETSU,,,,0,36001,1518.43874 +36002,26,西鉄太宰府線,ニシテツダザイフセン,西鉄太宰府線,Nishitetsu Dazaifu Line,Nishitetsu Dazaifu Line,西铁太宰府线,니시테쓰 다자이후선,#FD8A02,2,D,T,,,#1065AB,#1065AB,,,NISHITETSU,NISHITETSU,,,0,36002,1189.57765 +36003,26,西鉄甘木線,ニシテツアマギセン,西鉄甘木線,Nishitetsu Amagi Line,Nishitetsu Amagi Line,西铁甘木线,니시테쓰 아마기선,#1065AB,2,A,T,,,#1065AB,,,,NISHITETSU,,,,0,36003,1576.97881 +36004,26,西鉄貝塚線,ニシテツカイヅカセン,西鉄貝塚線,Nishitetsu Kaizuka Line,Nishitetsu Kaizuka Line,西铁贝冢线,니시테쓰 가이즈카선,#1065AB,2,NK,,,,#1065AB,,,,NISHITETSU,,,,0,36004,1190.996 +99101,101,札幌市営地下鉄東西線,サッポロシエイチカテツトウザイセン,札幌市営地下鉄東西線,Sapporo Municipal Subway Tozai Line,Sapporo Municipal Subway Tozai Line,札幌市营地铁东西线,삿포로 시영 지하철 도자이선,#FFA500,3,T,,,,#FFA500,,,,ROUND,,,,0,99101,1110.60862 +99102,101,札幌市営地下鉄南北線,サッポロシエイチカテツナンボクセン,札幌市営地下鉄南北線,Sapporo Municipal Subway Namboku Line,Sapporo Municipal Subway Namboku Line,札幌市营地铁南北线,삿포로 시영 지하철 난보쿠선,#008000,3,N,,,,#008000,,,,ROUND,,,,0,99102,947.50386 99103,101,札幌市営地下鉄東豊線,サッポロシエイチカテツトウホウセン,札幌市営地下鉄東豊線,Sapporo Municipal Subway Toho Line,Sapporo Municipal Subway Toho Line,札幌市营地铁东丰线,삿포로 시영 지하철 도호선,#0080FF,3,H,,,,#0080FF,,,,ROUND,,,,0,99103,1113.91678 99104,252,札幌市電,サッポロシデン,札幌市電 一条・山鼻軌道線,Yamahana Streetcar Line,Yamahana Streetcar Line,札幌市电,삿포로 시덴,#2A74BC,4,SC,,,,#2A74BC,,,,ROUND,,,,0,99104,458.55484 -99105,102,函館市電2系統,ハコダテシデンニケイトウ,函館市電2系統,Hakodate Streetcar Route 2,Hakodate Streetcar Route 2,函馆市电2系统,하코다테 시덴 2계통,#004896,4,DY,Y,,,#004896,,,,ROUND,,,,0,99105,508.54493 -99106,102,函館市電5系統,ハコダテシデンゴケイトウ,函館市電5系統,Hakodate Streetcar Route 5,Hakodate Streetcar Route 5,函馆市电5系统,하코다테 시덴 5계통,#004896,4,DY,D,,,#004896,,,,ROUND,,,,0,99106,526.24151 +99105,102,函館市電2系統,ハコダテシデンニケイトウ,函館市電2系統,Hakodate Streetcar Route 2,Hakodate Streetcar Route 2,函馆市电2系统,하코다테 시덴 2계통,#004896,4,DY,Y,,,#004896,,,,ROUND,,,,0,99105,452.62201 +99106,102,函館市電5系統,ハコダテシデンゴケイトウ,函館市電5系統,Hakodate Streetcar Route 5,Hakodate Streetcar Route 5,函馆市电5系统,하코다테 시덴 5계통,#004896,4,DY,D,,,#004896,,,,ROUND,,,,0,99106,467.86281 99107,103,ふるさと銀河線,フルサトギンガセン,北海道ちほく高原鉄道ふるさと銀河線,Furusato Ginga Line,Furusato Ginga Line,故乡银河线,후루사토 긴가선,#B63238,2,,,,,,,,,,,,,2,99107,4695.94041 -99108,248,道南いさりび鉄道線,ドウナンイサリビテツドウセン,道南いさりび鉄道線,South Hokkaido Railway Line,South Hokkaido Railway Line,道南渔火铁道线,도난이사리비 철도선,#246DAC,2,sh,H,,,#246DAC,#0072BC,,,REVERSED_ROUND,ROUND,,,0,99108,3509.81609 -99201,104,津軽鉄道線,ツガルテツドウセン,津軽鉄道線,Tsugaru Railway Line,Tsugaru Railway Line,津轻铁道线,쓰가루 철도선,#8D8335,2,,,,,,,,,,,,,0,99201,2057.67942 -99202,105,弘南鉄道弘南線,コウナンテツドウコウナンセン,弘南鉄道弘南線,Konan Railway Konan Line,Konan Railway Konan Line,弘南铁道弘南线,고난 철도 고난선,#1E9B49,2,KK,,,,#231816,,,,REVERSED_ROUND,,,,0,99202,1637.29627 -99203,105,弘南鉄道大鰐線,コウナンテツドウオオワニセン,弘南鉄道大鰐線,Konan Railway Owani Line,Konan Railway Owani Line,弘南铁道大鳄线,고난 철도 오와니선,#F39918,2,KW,,,,#D80C18,,,,REVERSED_ROUND,,,,0,99203,1191.08100 +99108,248,道南いさりび鉄道線,ドウナンイサリビテツドウセン,道南いさりび鉄道線,South Hokkaido Railway Line,South Hokkaido Railway Line,道南渔火铁道线,도난이사리비 철도선,#246DAC,2,sh,H,,,#246DAC,#0072BC,,,REVERSED_ROUND,ROUND,,,0,99108,3386.87637 +99201,104,津軽鉄道線,ツガルテツドウセン,津軽鉄道線,Tsugaru Railway Line,Tsugaru Railway Line,津轻铁道线,쓰가루 철도선,#8D8335,2,,,,,,,,,,,,,0,99201,1815.8183 +99202,105,弘南鉄道弘南線,コウナンテツドウコウナンセン,弘南鉄道弘南線,Konan Railway Konan Line,Konan Railway Konan Line,弘南铁道弘南线,고난 철도 고난선,#1E9B49,2,KK,,,,#231816,,,,REVERSED_ROUND,,,,0,99202,1360.44342 +99203,105,弘南鉄道大鰐線,コウナンテツドウオオワニセン,弘南鉄道大鰐線,Konan Railway Owani Line,Konan Railway Owani Line,弘南铁道大鳄线,고난 철도 오와니선,#F39918,2,KW,,,,#D80C18,,,,REVERSED_ROUND,,,,0,99203,1043.47334 99204,106,十和田観光電鉄線,トワダカンコウデンテツセン,十和田観光電鉄線,Towada Kanko Electric Railway Line,Towada Kanko Electric Railway Line,十和田观光电铁线,도와다 관광 전철선,#2826FE,2,,,,,,,,,,,,,2,99204,1581.06990 -99205,107,いわて銀河鉄道線,イワテギンガテツドウセン,いわて銀河鉄道線,Iwate Galaxy Railway Line,Iwate Galaxy Railway Line,岩手银河铁道线,이와테 긴가 철도선,#003399,2,,,,,,,,,,,,,0,99205,5212.94630 -99206,108,青い森鉄道線,アオイモリテツドウセン,青い森鉄道線,Aoimori Railway Line,Aoimori Railway Line,青森铁道线,아오이모리 철도선,#00FFFF,2,,,,,,,,,,,,,0,99206,5186.77544 +99205,107,いわて銀河鉄道線,イワテギンガテツドウセン,いわて銀河鉄道線,Iwate Galaxy Railway Line,Iwate Galaxy Railway Line,岩手银河铁道线,이와테 긴가 철도선,#003399,2,,,,,,,,,,,,,0,99205,4773.70355 +99206,108,青い森鉄道線,アオイモリテツドウセン,青い森鉄道線,Aoimori Railway Line,Aoimori Railway Line,青森铁道线,아오이모리 철도선,#00FFFF,2,,,,,,,,,,,,,0,99206,4646.29433 99207,109,三陸鉄道北リアス線,サンリクテツドウキタリアスセン,三陸鉄道北リアス線,Sanriku Railway North Rias Line,Sanriku Railway North Rias Line,三陆铁道北里亚斯线,산리쿠 철도 기타리아스선,#EC6821,2,,,,,,,,,,,,,2,99207,0 -99208,109,三陸鉄道リアス線,サンリクテツドウリアスセン,三陸鉄道リアス線,Sanriku Railway Rias Line,Sanriku Railway Rias Line,三陆铁道里亚斯线,산리쿠 철도 리아스선,#EC6821,2,,,,,,,,,,,,,0,99208,4293.10739 -99209,110,秋田内陸線,アキタナイリクセン,秋田内陸縦貫鉄道秋田内陸線,Akita Nairiku Line,Akita Nairiku Line,秋田内陆线,아키타 나이리쿠선,#990000,2,,,,,,,,,,,,,0,99209,3642.70825 -99210,111,鳥海山ろく線,チョウカイサンロクセン,由利高原鉄道鳥海山ろく線,Chokai Sanroku Line,Chokai Sanroku Line,鸟海山麓线,조카이산로쿠선,#B5E61D,2,,,,,,,,,,,,,0,99210,2194.18091 -99211,112,フラワー長井線,ヤマガタテツドウフラワーナガイセン,山形鉄道フラワー長井線,Flower Nagai Line,Flower Nagai Line,花长井线,플라워 나가이선,#F892F4,2,,,,,,,,,,,,,0,99211,2094.29681 +99208,109,三陸鉄道リアス線,サンリクテツドウリアスセン,三陸鉄道リアス線,Sanriku Railway Rias Line,Sanriku Railway Rias Line,三陆铁道里亚斯线,산리쿠 철도 리아스선,#EC6821,2,,,,,,,,,,,,,0,99208,4007.72176 +99209,110,秋田内陸線,アキタナイリクセン,秋田内陸縦貫鉄道秋田内陸線,Akita Nairiku Line,Akita Nairiku Line,秋田内陆线,아키타 나이리쿠선,#990000,2,,,,,,,,,,,,,0,99209,3317.10338 +99210,111,鳥海山ろく線,チョウカイサンロクセン,由利高原鉄道鳥海山ろく線,Chokai Sanroku Line,Chokai Sanroku Line,鸟海山麓线,조카이산로쿠선,#B5E61D,2,,,,,,,,,,,,,0,99210,2051.2472 +99211,112,フラワー長井線,ヤマガタテツドウフラワーナガイセン,山形鉄道フラワー長井線,Flower Nagai Line,Flower Nagai Line,花长井线,플라워 나가이선,#F892F4,2,,,,,,,,,,,,,0,99211,1882.55335 99212,113,くりはら田園鉄道線,クリハラデンエンテツドウセン,くりはら田園鉄道線,Kurihara Den'en Railway Line,Kurihara Den'en Railway Line,栗原田园铁道线,구리하라 덴엔 철도선,#8E2229,2,,,,,,,,,,,,,2,99212,1907.17502 -99213,114,阿武隈急行線,アブクマキュウコウセン,阿武隈急行線,Abukuma Kyūkō Line,Abukuma Kyūkō Line,阿武隈急行线,아부쿠마 급행선,#37CB7F,2,,,,,,,,,,,,,0,99213,2616.24486 -99214,115,仙台市営地下鉄南北線,センダイシエイチカテツナンボクセン,仙台市営地下鉄南北線,Sendai Subway Namboku Line,Sendai Subway Namboku Line,仙台市营地铁南北线,센다이 시영 지하철 난보쿠선,#339966,3,N,,,,#339966,,,,ROUND,,,,0,99214,951.33164 -99218,115,仙台市営地下鉄東西線,センダイシエイチカテツトウザイセン,仙台市営地下鉄東西線,Sendai Subway Tozai Line,Sendai Subway Tozai Line,仙台市营地铁东西线,센다이 시영 지하철 도자이선,#00B1DD,3,T,,,,#00B1DD,,,,ROUND,,,,0,99214,1122.00447 -99215,116,福島交通飯坂線,フクシマシエイコウツウイイザカセン,福島交通飯坂線,Fukushima Kotsu Iizaka Line,Fukushima Kotsu Iizaka Line,福岛交通饭坂线,후쿠시마 교통 이이자카선,#BFBFFF,2,,,,,,,,,,,,,0,99215,962.41577 -99216,117,会津鉄道会津線,アイヅテツドウアイヅセン,会津鉄道会津線,Aizu Railway Aizu Line,Aizu Railway Aizu Line,会津铁道会津线,아이즈 철도 아이즈선,#265613,2,,,,,,,,,,,,,0,99216,3059.64261 -99217,118,仙台空港線,センダイクウコウセン,仙台空港鉄道仙台空港線,Sendai Airport Line,Sendai Airport Line,仙台机场线,센다이 공항선,#2A5CAA,2,,,,,,,,,,,,,0,99217,2321.20167 -99301,119,都営大江戸線,トエイオオエドセン,都営大江戸線,Toei Oedo Line,Toei Oedo Line,都营大江户线,도에이 오에도선,#B6007A,3,E,,,,#B6007A,,,,ROUND,,,,0,99301,1065.80557 -99302,119,都営浅草線,トエイアサクサセン,都営浅草線,Toei Asakusa Line,Toei Asakusa Line,都营浅草线,도에이 아사쿠사선,#EC6E65,3,A,,,,#EC6E65,,,,ROUND,,,,0,99302,1031.42837 -99303,119,都営三田線,トエイミタセン,都営三田線,Toei Mita Line,Toei Mita Line,都营三田线,도에이 미타선,#0079C2,3,I,,,,#0079C2,,,,ROUND,,,,0,99303,1065.42594 -99304,119,都営新宿線,トエイシンジュクセン,都営新宿線,Toei Shinjuku Line,Toei Shinjuku Line,都营新宿线,도에이 신주쿠선,#B0BF1E,3,S,,,,#B0BF1E,,,,ROUND,,,,0,99304,1268.36623 -99305,119,東京さくらトラム(都電荒川線),トウキョウサクラトラム(トデンアラカワセン),都営都電荒川線,Tokyo Sakura Tram,Tokyo Sakura Tram,都电荒川线,도덴 아라카와선,#EE86A7,4,SA,,,,#EE86A7,,,,REVERSED_ROUND,,,,0,99305,500.05847 -99342,119,日暮里・舎人ライナー,ニッポリ・トネリライナー,日暮里・舎人ライナー,Nippori-Toneri Liner,Nippori-Toneri Liner,日暮里-舍人线,닛포리·도네리 라이너,#69B444,5,NT,,,,#69B444,,,,NTL,,,,0,99305,899.31678 -99306,120,秩父鉄道秩父本線,チチブテツドウチチブホンセン,秩父鉄道秩父本線,Chichibu Railway Chichibu Main Line,Chichibu Railway Chichibu Main Line,秩父铁道秩父本线,지치부 철도 지치부 본선,#0054A6,2,CR,,,,#0054A6,,,,ROUND,,,,0,99306,2308.95903 -99307,121,埼玉高速鉄道線,サイタマコウソクテツドウセン,埼玉高速鉄道線,Saitama Rapid Railway Line,Saitama Rapid Railway Line,埼玉高速铁道线,사이타마 고속 철도선,#3565AD,2,SR,,,,#3565AD,,,,ROUND,,,,0,99307,2244.03884 -99308,122,いすみ線,イスミセン,いすみ鉄道いすみ線,Isumi Line,Isumi Line,夷隅线,이스미선,#FFDC00,2,,,,,,,,,,,,,0,99308,2588.21061 -99309,123,つくばエクスプレス線,ツクバエクスプレスセン,首都圏新都市鉄道つくばエクスプレス,Tsukuba Express Line,Tsukuba Express Line,筑波快线,쓰쿠바 익스프레스,#273E6C,2,TX,,,,#273E6C,,,,REVERSED_SQUARE,,,,0,99309,3336.64237 -99310,124,みなとみらい線,ミナトミライセン,みなとみらい21線,Minatomirai Line,Minatomirai Line,港未来线,미나토미라이선,#013274,2,MM,,,,#013274,,,,REVERSED_SQUARE,,,,0,99310,875.04931 -99311,125,ゆりかもめ,ユリカモメ,ゆりかもめ東京臨海新交通臨海線,Yurikamome,Yurikamome,百合鸥,유리카모메,#00418E,5,U,,,,#00418E,,,,REVERSED_ROUND,,,,0,99311,890.24203 -99312,126,わたらせ渓谷線,ワタラセケイコクセン,わたらせ渓谷鐵道わたらせ渓谷線,Watarase Keikoku Line,Watarase Keikoku Line,渡良濑溪谷线,와타라세 계곡선,#5B1511,2,WK,,,,#5B1511,,,,ROUND,,,,0,99312,2777.56028 -99313,127,ユーカリが丘線,ユーガリガオカセン,山万ユーカリが丘線,Yukarigaoka Line,Yukarigaoka Line,有加利丘线,유카리가오카선,#30B474,5,,,,,#5B1511,,,,ROUND,,,,0,99313,729.14827 -99314,128,伊豆箱根鉄道大雄山線,イズハコネテツドウダイユウザンセン,伊豆箱根鉄道大雄山線,Izuhakone Railway Daiyuzan Line,Izuhakone Railway Daiyuzan Line,伊豆箱根铁道大雄山线,이즈하코네 철도 다이유잔선,#4086E5,2,ID,,,,#4086E5,,,,IZUHAKONE,,,,0,99314,969.98974 -99315,129,ひたちなか海浜鉄道湊線,ヒタチナカカイヒンテツドウミナトセン,ひたちなか海浜鉄道湊線,Hitachinaka Seaside Railway,Hitachinaka Seaside Railway,常陆那珂海滨铁道凑线,히타치나카 해안철도 미나토선,#A77718,2,,,,,,,,,,,,,0,99315,1888.23637 -99316,130,横浜市営地下鉄ブルーライン,ヨコハマシエイチカテツブルーライン,横浜市高速鉄道1号線・3号線,Yokohama Municipal Subway Blue Line,Yokohama Municipal Subway Blue Line,横滨市营地铁蓝线,요코하마 시영 지하철 블루 라인,#005BA5,3,B,,,,#005BA5,,,,REVERSED_ROUND,,,,0,99316,1345.51871 -99343,130,横浜市営地下鉄グリーンライン,ヨコハマシエイチカテツグリーンライン,横浜市高速鉄道4号線,Yokohama Municipal Subway Green Line,Yokohama Municipal Subway Green Line,横滨市营地铁绿线,요코하마 시영 지하철 그린 라인,#40CC40,3,G,,,,#40CC40,,,,REVERSED_ROUND,,,,0,99316,1522.33152 -99317,131,金沢シーサイドライン,カナザワシーサイドライン,横浜新都市交通金沢シーサイドライン,Kanazawa Seaside Line,Kanazawa Seaside Line,横滨海岸线,요코하마 시사이드라인,#F68B1E,5,,,,,#5466BC,,,,REVERSED_ROUND_HORIZONTAL,,,,0,99317,811.52098 -99318,132,関東鉄道常総線,カントウテツドウジョウソウセン,関東鉄道常総線,Kanto Railway Joso Line,Kanto Railway Joso Line,关东铁道常总线,간토 철도 조소선,#121892,2,,,,,,,,,,,,,0,99318,2469.41797 -99319,132,関東鉄道竜ヶ崎線,カントウテツドウリュウガサキセン,関東鉄道竜ヶ崎線,Kanto Railway Ryugasaki Line,Kanto Railway Ryugasaki Line,关东铁道龙崎线,간토 철도 류가사키선,#121892,2,,,,,,,,,,,,,0,99319,2499.68837 -99320,133,江ノ島電鉄線,エノシマデンテツセン,江ノ島電鉄線,Enoshima Electric Railway Line,Enoshima Electric Railway Line,江之岛电铁线,에노시마 전철선,#209A3F,2,EN,,,,#209A3F,,,,ENODEN,,,,0,99320,778.98276 -99321,134,ニューシャトル,ニューシャトル,埼玉新都市交通伊奈線,New Shuttle,New Shuttle,伊奈线,이나선,#339999,5,NS,,,,#339999,,,,NEW_SHUTTLE,,,,0,99321,1166.87369 +99213,114,阿武隈急行線,アブクマキュウコウセン,阿武隈急行線,Abukuma Kyūkō Line,Abukuma Kyūkō Line,阿武隈急行线,아부쿠마 급행선,#37CB7F,2,,,,,,,,,,,,,0,99213,2369.63173 +99214,115,仙台市営地下鉄南北線,センダイシエイチカテツナンボクセン,仙台市営地下鉄南北線,Sendai Subway Namboku Line,Sendai Subway Namboku Line,仙台市营地铁南北线,센다이 시영 지하철 난보쿠선,#339966,3,N,,,,#339966,,,,ROUND,,,,0,99214,891.24713 +99218,115,仙台市営地下鉄東西線,センダイシエイチカテツトウザイセン,仙台市営地下鉄東西線,Sendai Subway Tozai Line,Sendai Subway Tozai Line,仙台市营地铁东西线,센다이 시영 지하철 도자이선,#00B1DD,3,T,,,,#00B1DD,,,,ROUND,,,,0,99214,1129.33276 +99215,116,福島交通飯坂線,フクシマシエイコウツウイイザカセン,福島交通飯坂線,Fukushima Kotsu Iizaka Line,Fukushima Kotsu Iizaka Line,福岛交通饭坂线,후쿠시마 교통 이이자카선,#BFBFFF,2,,,,,,,,,,,,,0,99215,855.93195 +99216,117,会津鉄道会津線,アイヅテツドウアイヅセン,会津鉄道会津線,Aizu Railway Aizu Line,Aizu Railway Aizu Line,会津铁道会津线,아이즈 철도 아이즈선,#265613,2,,,,,,,,,,,,,0,99216,2815.55776 +99217,118,仙台空港線,センダイクウコウセン,仙台空港鉄道仙台空港線,Sendai Airport Line,Sendai Airport Line,仙台机场线,센다이 공항선,#2A5CAA,2,,,,,,,,,,,,,0,99217,2316.47225 +99301,119,都営大江戸線,トエイオオエドセン,都営大江戸線,Toei Oedo Line,Toei Oedo Line,都营大江户线,도에이 오에도선,#B6007A,3,E,,,,#B6007A,,,,ROUND,,,,0,99301,1066.83815 +99302,119,都営浅草線,トエイアサクサセン,都営浅草線,Toei Asakusa Line,Toei Asakusa Line,都营浅草线,도에이 아사쿠사선,#EC6E65,3,A,,,,#EC6E65,,,,ROUND,,,,0,99302,952.38538 +99303,119,都営三田線,トエイミタセン,都営三田線,Toei Mita Line,Toei Mita Line,都营三田线,도에이 미타선,#0079C2,3,I,,,,#0079C2,,,,ROUND,,,,0,99303,992.91929 +99304,119,都営新宿線,トエイシンジュクセン,都営新宿線,Toei Shinjuku Line,Toei Shinjuku Line,都营新宿线,도에이 신주쿠선,#B0BF1E,3,S,,,,#B0BF1E,,,,ROUND,,,,0,99304,1157.85443 +99305,119,東京さくらトラム(都電荒川線),トウキョウサクラトラム(トデンアラカワセン),都営都電荒川線,Tokyo Sakura Tram,Tokyo Sakura Tram,都电荒川线,도덴 아라카와선,#EE86A7,4,SA,,,,#EE86A7,,,,REVERSED_ROUND,,,,0,99305,437.36399 +99342,119,日暮里・舎人ライナー,ニッポリ・トネリライナー,日暮里・舎人ライナー,Nippori-Toneri Liner,Nippori-Toneri Liner,日暮里-舍人线,닛포리·도네리 라이너,#69B444,5,NT,,,,#69B444,,,,NTL,,,,0,99305,817.56071 +99306,120,秩父鉄道秩父本線,チチブテツドウチチブホンセン,秩父鉄道秩父本線,Chichibu Railway Chichibu Main Line,Chichibu Railway Chichibu Main Line,秩父铁道秩父本线,지치부 철도 지치부 본선,#0054A6,2,CR,,,,#0054A6,,,,ROUND,,,,0,99306,1959.10704 +99307,121,埼玉高速鉄道線,サイタマコウソクテツドウセン,埼玉高速鉄道線,Saitama Rapid Railway Line,Saitama Rapid Railway Line,埼玉高速铁道线,사이타마 고속 철도선,#3565AD,2,SR,,,,#3565AD,,,,ROUND,,,,0,99307,2047.79834 +99308,122,いすみ線,イスミセン,いすみ鉄道いすみ線,Isumi Line,Isumi Line,夷隅线,이스미선,#FFDC00,2,,,,,,,,,,,,,0,99308,2002.27441 +99309,123,つくばエクスプレス線,ツクバエクスプレスセン,首都圏新都市鉄道つくばエクスプレス,Tsukuba Express Line,Tsukuba Express Line,筑波快线,쓰쿠바 익스프레스,#273E6C,2,TX,,,,#273E6C,,,,REVERSED_SQUARE,,,,0,99309,3016.22347 +99310,124,みなとみらい線,ミナトミライセン,みなとみらい21線,Minatomirai Line,Minatomirai Line,港未来线,미나토미라이선,#013274,2,MM,,,,#013274,,,,REVERSED_SQUARE,,,,0,99310,793.27142 +99311,125,ゆりかもめ,ユリカモメ,ゆりかもめ東京臨海新交通臨海線,Yurikamome,Yurikamome,百合鸥,유리카모메,#00418E,5,U,,,,#00418E,,,,REVERSED_ROUND,,,,0,99311,936.45551 +99312,126,わたらせ渓谷線,ワタラセケイコクセン,わたらせ渓谷鐵道わたらせ渓谷線,Watarase Keikoku Line,Watarase Keikoku Line,渡良濑溪谷线,와타라세 계곡선,#5B1511,2,WK,,,,#5B1511,,,,ROUND,,,,0,99312,2683.8255 +99313,127,ユーカリが丘線,ユーガリガオカセン,山万ユーカリが丘線,Yukarigaoka Line,Yukarigaoka Line,有加利丘线,유카리가오카선,#30B474,5,,,,,#5B1511,,,,ROUND,,,,0,99313,681.93148 +99314,128,伊豆箱根鉄道大雄山線,イズハコネテツドウダイユウザンセン,伊豆箱根鉄道大雄山線,Izuhakone Railway Daiyuzan Line,Izuhakone Railway Daiyuzan Line,伊豆箱根铁道大雄山线,이즈하코네 철도 다이유잔선,#4086E5,2,ID,,,,#4086E5,,,,IZUHAKONE,,,,0,99314,861.50661 +99315,129,ひたちなか海浜鉄道湊線,ヒタチナカカイヒンテツドウミナトセン,ひたちなか海浜鉄道湊線,Hitachinaka Seaside Railway,Hitachinaka Seaside Railway,常陆那珂海滨铁道凑线,히타치나카 해안철도 미나토선,#A77718,2,,,,,,,,,,,,,0,99315,1390.85906 +99316,130,横浜市営地下鉄ブルーライン,ヨコハマシエイチカテツブルーライン,横浜市高速鉄道1号線・3号線,Yokohama Municipal Subway Blue Line,Yokohama Municipal Subway Blue Line,横滨市营地铁蓝线,요코하마 시영 지하철 블루 라인,#005BA5,3,B,,,,#005BA5,,,,REVERSED_ROUND,,,,0,99316,1273.71378 +99343,130,横浜市営地下鉄グリーンライン,ヨコハマシエイチカテツグリーンライン,横浜市高速鉄道4号線,Yokohama Municipal Subway Green Line,Yokohama Municipal Subway Green Line,横滨市营地铁绿线,요코하마 시영 지하철 그린 라인,#40CC40,3,G,,,,#40CC40,,,,REVERSED_ROUND,,,,0,99316,1391.75413 +99317,131,金沢シーサイドライン,カナザワシーサイドライン,横浜新都市交通金沢シーサイドライン,Kanazawa Seaside Line,Kanazawa Seaside Line,横滨海岸线,요코하마 시사이드라인,#F68B1E,5,,,,,#5466BC,,,,REVERSED_ROUND_HORIZONTAL,,,,0,99317,774.45917 +99318,132,関東鉄道常総線,カントウテツドウジョウソウセン,関東鉄道常総線,Kanto Railway Joso Line,Kanto Railway Joso Line,关东铁道常总线,간토 철도 조소선,#121892,2,,,,,,,,,,,,,0,99318,2131.01169 +99319,132,関東鉄道竜ヶ崎線,カントウテツドウリュウガサキセン,関東鉄道竜ヶ崎線,Kanto Railway Ryugasaki Line,Kanto Railway Ryugasaki Line,关东铁道龙崎线,간토 철도 류가사키선,#121892,2,,,,,,,,,,,,,0,99319,2173.64206 +99320,133,江ノ島電鉄線,エノシマデンテツセン,江ノ島電鉄線,Enoshima Electric Railway Line,Enoshima Electric Railway Line,江之岛电铁线,에노시마 전철선,#209A3F,2,EN,,,,#209A3F,,,,ENODEN,,,,0,99320,682.96003 +99321,134,ニューシャトル,ニューシャトル,埼玉新都市交通伊奈線,New Shuttle,New Shuttle,伊奈线,이나선,#339999,5,NS,,,,#339999,,,,NEW_SHUTTLE,,,,0,99321,1075.79739 99322,135,鹿島鉄道線,カシマテツドウセン,鹿島鉄道線,Kashima Railway Line,Kashima Railway Line,鹿岛鉄道线,카시마 철도선,#CC0000,2,,,,,,,,,,,,,2,99322,1887.65696 -99323,136,鹿島臨海鉄道大洗鹿島線,カシマリンカイテツドウオオアライカシマセン,鹿島臨海鉄道大洗鹿島線,Oarai Kashima Line,Oarai Kashima Line,鹿岛临海铁道大洗鹿岛线,가시마 임해 철도 오아라이카시마선,#3260C0,2,,,,,,,,,,,,,0,99323,4171.84832 -99324,137,芝山鉄道線,シバヤマテツドウセン,芝山鉄道線,Shibayama Railway Line,Shibayama Railway Line,芝山铁道线,시바야마 철도선,#33CC33,2,SR,KS,,,#007F5A,#005AAA,,,KEISEI,KEISEI,,,0,99324,2377.42668 -99325,138,小湊鉄道線,コミナトテツドウセン,小湊鉄道線,Kominato Line,Kominato Line,小凑铁道线,코미나토 철도선,#DCBC9F,2,,,,,,,,,,,,,0,99325,2432.96193 -99326,139,湘南モノレール,ショウナンモノレール,江の島線,Shonan Monorail,Shonan Monorail,湘南单轨电车,쇼난 모노레일,#3E7AFF,5,SMR,,,,#000000,,,,SMR,,,,0,99326,978.58805 -99327,140,上信電鉄,ジョウシンデンテツ,上信電鉄,Joshin Dentetsu Line,Joshin Dentetsu Line,上信电铁,조신 전철,#457BC6,2,,,,,,,,,,,,,0,99327,1795.45602 -99328,141,上毛電気鉄道上毛線,ジョウモウデンキテツドウジョウモウセン,上毛電気鉄道上毛線,Jomo Line,Jomo Line,上毛电气铁道上毛线,조모 전기 철도 조모선,#40E0D0,2,JM,,,,#40E0D0,,,,ROUND,,,,0,99328,1270.37817 -99329,13,京成松戸線,ケイセイマツドセン,京成電鉄松戸線,Keisei Matsudo Line,Keisei Matsudo Line,京成松户线,게이세이 마쓰도선,#005AAA,2,KS,,,,#005AAA,,,,KEISEI,,,,0,99329,1202.38012 -99330,143,真岡鐵道真岡線,モオカテツドウモオカセン,真岡鐵道真岡線,Moka Line,Moka Line,真冈铁道真冈线,모카 철도 모카선,#EE5B5B,2,,,,,,,,,,,,,0,99330,2853.64537 -99331,144,千葉都市モノレール1号線,チバトシモノレールイチゴウセン,千葉都市モノレール1号線,Chiba Urban Monorail Line 1,Chiba Urban Monorail Line 1,千叶都市单轨电车1号线,지바 도시 모노레일 1호선,#192198,5,CM,,,,#3E8BAD,,,,ROUND,,,,0,99331,604.26009 -99332,144,千葉都市モノレール2号線,チバトシモノレールニゴウセン,千葉都市モノレール2号線,Chiba Urban Monorail Line 2,Chiba Urban Monorail Line 2,千叶都市单轨电车2号线,지바 도시 모노레일 2호선,#192198,5,CM,,,,#3E8BAD,,,,ROUND,,,,0,99332,955.55162 -99333,145,流鉄流山線,リュウテツナガレヤマセン,流鉄流山線,Ryutetsu Nagareyama Line,Ryutetsu Nagareyama Line,流铁流山线,류테츠나가레야마선,#B58429,2,RN,,,,#B58429,,,,ROUND,,,,0,99333,1253.96121 -99334,146,多摩モノレール,タマモノレール,多摩都市モノレール線,Tama Toshi Monorail Line,Tama Toshi Monorail Line,多摩都市单轨电车线,다마 도시 모노레일선,#FF6633,5,TT,,,,#37615E,,,,SQUARE,,,,0,99334,941.35726 -99335,147,銚子電鉄線,チョウシデンテツセン,銚子電気鉄道線,Choshi Electric Railway Line,Choshi Electric Railway Line,铫子电气铁道线,조시 전기철도선,#A52A2A,2,CD,,,,#333333,,,,SQUARE,,,,0,99335,801.26357 -99336,148,東京モノレール,トウキョウモノレール,東京モノレール羽田空港線,Tokyo Monorail,Tokyo Monorail,东京单轨电车,도쿄 모노레일,#003686,5,MO,,,,#003686,,,,SQUARE,,,,0,99336,1772.70395 -99337,149,りんかい線,リンカイセン,東京臨海高速鉄道りんかい線,Rinkai Line,Rinkai Line,临海线,린카이선,#00418E,2,R,,,,#00418E,,,,TWR,,,,0,99337,1923.30131 -99338,150,東葉高速線,トウヨウコウソクセン,東葉高速鉄道東葉高速線,Toyo Rapid Railway Line,Toyo Rapid Railway Line,东叶高速线,도요 고속선,#66CC00,2,TR,,,,#66CC00,,,,ROUND,,,,0,99338,2307.01657 -99339,151,箱根登山鉄道鉄道線,ハコネトザンテツドウテツドウセン,箱根登山鉄道鉄道線,Hakone Tozan Line,Hakone Tozan Line,箱根登山线,하코네 등산선,#F04A00,2,OH,,,,#F04A00,,,,HAKONE,,,,0,99339,1346.91916 -99340,152,北総鉄道北総線,ホクソウテツドウホクソウセン,北総鉄道北総線,Hokuso Line,Hokuso Line,北总铁道北总线,호쿠소 철도 호쿠소선,#3333FF,2,HS,KS,,,#3333FF,#005AAA,,,KEISEI,KEISEI,,,0,99340,2607.68961 -99341,153,ほっとスパ・ライン,ホットスパライン,野岩鉄道会津鬼怒川線,Yagan Railway Aizu Kinugawa Line,Yagan Railway Aizu Kinugawa Line,野岩铁道会津鬼怒川线,야간 철도 아이즈키누가와선,#00733C,2,,,,,,,,,,,,,0,99341,4161.97201 +99323,136,鹿島臨海鉄道大洗鹿島線,カシマリンカイテツドウオオアライカシマセン,鹿島臨海鉄道大洗鹿島線,Oarai Kashima Line,Oarai Kashima Line,鹿岛临海铁道大洗鹿岛线,가시마 임해 철도 오아라이카시마선,#3260C0,2,,,,,,,,,,,,,0,99323,3711.69043 +99324,137,芝山鉄道線,シバヤマテツドウセン,芝山鉄道線,Shibayama Railway Line,Shibayama Railway Line,芝山铁道线,시바야마 철도선,#33CC33,2,SR,KS,,,#007F5A,#005AAA,,,KEISEI,KEISEI,,,0,99324,2107.62382 +99325,138,小湊鉄道線,コミナトテツドウセン,小湊鉄道線,Kominato Line,Kominato Line,小凑铁道线,코미나토 철도선,#DCBC9F,2,,,,,,,,,,,,,0,99325,2249.53509 +99326,139,湘南モノレール,ショウナンモノレール,江の島線,Shonan Monorail,Shonan Monorail,湘南单轨电车,쇼난 모노레일,#3E7AFF,5,SMR,,,,#000000,,,,SMR,,,,0,99326,895.55729 +99327,140,上信電鉄,ジョウシンデンテツ,上信電鉄,Joshin Dentetsu Line,Joshin Dentetsu Line,上信电铁,조신 전철,#457BC6,2,,,,,,,,,,,,,0,99327,1648.16489 +99328,141,上毛電気鉄道上毛線,ジョウモウデンキテツドウジョウモウセン,上毛電気鉄道上毛線,Jomo Line,Jomo Line,上毛电气铁道上毛线,조모 전기 철도 조모선,#40E0D0,2,JM,,,,#40E0D0,,,,ROUND,,,,0,99328,1118.88779 +99329,13,京成松戸線,ケイセイマツドセン,京成電鉄松戸線,Keisei Matsudo Line,Keisei Matsudo Line,京成松户线,게이세이 마쓰도선,#005AAA,2,KS,,,,#005AAA,,,,KEISEI,,,,0,99329,1112.85437 +99330,143,真岡鐵道真岡線,モオカテツドウモオカセン,真岡鐵道真岡線,Moka Line,Moka Line,真冈铁道真冈线,모카 철도 모카선,#EE5B5B,2,,,,,,,,,,,,,0,99330,2586.20889 +99331,144,千葉都市モノレール1号線,チバトシモノレールイチゴウセン,千葉都市モノレール1号線,Chiba Urban Monorail Line 1,Chiba Urban Monorail Line 1,千叶都市单轨电车1号线,지바 도시 모노레일 1호선,#192198,5,CM,,,,#3E8BAD,,,,ROUND,,,,0,99331,566.66594 +99332,144,千葉都市モノレール2号線,チバトシモノレールニゴウセン,千葉都市モノレール2号線,Chiba Urban Monorail Line 2,Chiba Urban Monorail Line 2,千叶都市单轨电车2号线,지바 도시 모노레일 2호선,#192198,5,CM,,,,#3E8BAD,,,,ROUND,,,,0,99332,916.35638 +99333,145,流鉄流山線,リュウテツナガレヤマセン,流鉄流山線,Ryutetsu Nagareyama Line,Ryutetsu Nagareyama Line,流铁流山线,류테츠나가레야마선,#B58429,2,RN,,,,#B58429,,,,ROUND,,,,0,99333,1090.40105 +99334,146,多摩モノレール,タマモノレール,多摩都市モノレール線,Tama Toshi Monorail Line,Tama Toshi Monorail Line,多摩都市单轨电车线,다마 도시 모노레일선,#FF6633,5,TT,,,,#37615E,,,,SQUARE,,,,0,99334,870.36393 +99335,147,銚子電鉄線,チョウシデンテツセン,銚子電気鉄道線,Choshi Electric Railway Line,Choshi Electric Railway Line,铫子电气铁道线,조시 전기철도선,#A52A2A,2,CD,,,,#333333,,,,SQUARE,,,,0,99335,723.60043 +99336,148,東京モノレール,トウキョウモノレール,東京モノレール羽田空港線,Tokyo Monorail,Tokyo Monorail,东京单轨电车,도쿄 모노레일,#003686,5,MO,,,,#003686,,,,SQUARE,,,,0,99336,1730.1195 +99337,149,りんかい線,リンカイセン,東京臨海高速鉄道りんかい線,Rinkai Line,Rinkai Line,临海线,린카이선,#00418E,2,R,,,,#00418E,,,,TWR,,,,0,99337,1739.57769 +99338,150,東葉高速線,トウヨウコウソクセン,東葉高速鉄道東葉高速線,Toyo Rapid Railway Line,Toyo Rapid Railway Line,东叶高速线,도요 고속선,#66CC00,2,TR,,,,#66CC00,,,,ROUND,,,,0,99338,2026.46605 +99339,151,箱根登山鉄道鉄道線,ハコネトザンテツドウテツドウセン,箱根登山鉄道鉄道線,Hakone Tozan Line,Hakone Tozan Line,箱根登山线,하코네 등산선,#F04A00,2,OH,,,,#F04A00,,,,HAKONE,,,,0,99339,1393.88661 +99340,152,北総鉄道北総線,ホクソウテツドウホクソウセン,北総鉄道北総線,Hokuso Line,Hokuso Line,北总铁道北总线,호쿠소 철도 호쿠소선,#3333FF,2,HS,KS,,,#3333FF,#005AAA,,,KEISEI,KEISEI,,,0,99340,2282.3843 +99341,153,ほっとスパ・ライン,ホットスパライン,野岩鉄道会津鬼怒川線,Yagan Railway Aizu Kinugawa Line,Yagan Railway Aizu Kinugawa Line,野岩铁道会津鬼怒川线,야간 철도 아이즈키누가와선,#00733C,2,,,,,,,,,,,,,0,99341,3792.83721 99344,151,箱根登山ケーブルカー,ハコネトザンケーブルカー,箱根登山鉄道鋼索線,Hakone Tozan Cable Car,Hakone Tozan Cable Car,箱根登山缆车,하코네 등산 케이블카,#BE3C27,0,,,,,,,,,,,,,0,99344,285.33449 -99345,250,芳賀・宇都宮LRT,ウツノミヤハガライトレールセン,宇都宮芳賀ライトレール線,Haga Utsunomiya LRT,Haga Utsunomiya LRT,芳贺/宇都宫LRT,하가 · 우츠노미야 LRT,#F9BE00,4,,,,,#F9BE00,,,,MONOCHROME_ROUND,,,,0,99345,966.66571 -99401,154,富士急行線,フジキュウコウセン,富士急行線,Fujikyuko Line,Fujikyuko Line,富士急行线,후지큐코선,#E83917,2,FJ,,,,#000000,,,,ROUND,,,,0,99401,1617.53982 -99402,155,北越急行ほくほく線,ホクエツキュウコウホクホクセン,北越急行ほくほく線,Hokuhoku Line,Hokuhoku Line,北越急行北北线,호쿠에쓰 급행 호쿠호쿠선,#CC3366,2,,,,,,,,,,,,,0,99402,5999.98707 -99403,156,しなの鉄道線,シナノテツドウセン,しなの鉄道線,Shinano Railway Line,Shinano Railway Line,信浓铁道线,시나노 철도선,#F0A401,2,,,,,,,,,,,,,0,99403,3944.95147 -99427,156,北しなの線,キタシナノセン,北しなの線,Kita-Shinano Line,Kita-Shinano Line,北信浓线,기타시나노선,#FEC9FE,2,,,,,,,,,,,,,0,99403,5153.32592 -99404,157,上田電鉄別所線,ウエダデンテツベッショセン,上田電鉄別所線,Ueda Electric Railway Bessho Line,Ueda Electric Railway Bessho Line,上田电铁别所线,우에다 전철 벳쇼선,#0B2846,2,BE,,,,#0B2846,,,,REVERSED_ROUND,,,,0,99404,903.54951 -99405,158,長野電鉄長野線,ナガノデンテツナガノセン,長野電鉄長野線,Nagano Electric Railway Nagano Line,Nagano Electric Railway Nagano Line,长野电铁长野线,나가노 전철 나가노선,#E21919,2,N,,,,#E21919,,,,ROUND,,,,0,99405,1534.91107 +99345,250,芳賀・宇都宮LRT,ウツノミヤハガライトレールセン,宇都宮芳賀ライトレール線,Haga Utsunomiya LRT,Haga Utsunomiya LRT,芳贺/宇都宫LRT,하가 · 우츠노미야 LRT,#F9BE00,4,,,,,#F9BE00,,,,MONOCHROME_ROUND,,,,0,99345,784.19167 +99401,154,富士急行線,フジキュウコウセン,富士急行線,Fujikyuko Line,Fujikyuko Line,富士急行线,후지큐코선,#E83917,2,FJ,,,,#000000,,,,ROUND,,,,0,99401,1488.82123 +99402,155,北越急行ほくほく線,ホクエツキュウコウホクホクセン,北越急行ほくほく線,Hokuhoku Line,Hokuhoku Line,北越急行北北线,호쿠에쓰 급행 호쿠호쿠선,#CC3366,2,,,,,,,,,,,,,0,99402,5366.7774 +99403,156,しなの鉄道線,シナノテツドウセン,しなの鉄道線,Shinano Railway Line,Shinano Railway Line,信浓铁道线,시나노 철도선,#F0A401,2,,,,,,,,,,,,,0,99403,3335.19718 +99427,156,北しなの線,キタシナノセン,北しなの線,Kita-Shinano Line,Kita-Shinano Line,北信浓线,기타시나노선,#FEC9FE,2,,,,,,,,,,,,,0,99403,5132.73044 +99404,157,上田電鉄別所線,ウエダデンテツベッショセン,上田電鉄別所線,Ueda Electric Railway Bessho Line,Ueda Electric Railway Bessho Line,上田电铁别所线,우에다 전철 벳쇼선,#0B2846,2,BE,,,,#0B2846,,,,REVERSED_ROUND,,,,0,99404,787.89761 +99405,158,長野電鉄長野線,ナガノデンテツナガノセン,長野電鉄長野線,Nagano Electric Railway Nagano Line,Nagano Electric Railway Nagano Line,长野电铁长野线,나가노 전철 나가노선,#E21919,2,N,,,,#E21919,,,,ROUND,,,,0,99405,1389.13664 99406,158,長野電鉄屋代線,ナガノデンテツヤシロセン,長野電鉄屋代線,Nagano Electric Railway Yashiro Line,Nagano Electric Railway Yashiro Line,长野电铁屋代线,나가노 전철 야시로선,#E21919,2,Y,,,,#E21919,,,,ROUND,,,,2,99406,2195.43210 -99407,159,上高地線,カミコウチセン,アルピコ交通上高地線,Kamikochi Line,Kamikochi Line,上高地线,가미코치선,#465DAA,2,AK,,,,#465DAA,,,,ROUND,,,,0,99407,1247.71405 -99408,160,富山地鉄本線,トヤマチテツホンセン,富山地鉄本線,Toyama Chiho Railway Main Line,Toyama Chiho Railway Main Line,富山地铁本线,도야마 지방 철도 본선,#1D1686,2,T,,,,#1D1686,,,,SQUARE,,,,0,99408,1493.75490 -99409,160,富山地鉄立山線,トヤマチテツタテヤマセン,富山地鉄立山線,Toyama Chiho Railway Tateyama Line,Toyama Chiho Railway Tateyama Line,富山地铁立山线,도야마 지방 철도 다테야마선,#008000,2,T,,,,#008000,,,,SQUARE,,,,0,99409,2071.54746 -99410,160,富山地鉄不二越・上滝線,トヤマチテツフジコシ・カミダキセン,富山地鉄不二越・上滝線,Toyama Chiho Railway Fujikoshi-Kamidaki Line,Toyama Chiho Railway Fujikoshi-Kamidaki Line,富山地铁不二越・上泷线,도야마 지방 철도 후지코시·가미다키선,#7E490A,2,T,,,,#7E490A,,,,SQUARE,,,,0,99410,1298.46152 +99407,159,上高地線,カミコウチセン,アルピコ交通上高地線,Kamikochi Line,Kamikochi Line,上高地线,가미코치선,#465DAA,2,AK,,,,#465DAA,,,,ROUND,,,,0,99407,1084.96874 +99408,160,富山地鉄本線,トヤマチテツホンセン,富山地鉄本線,Toyama Chiho Railway Main Line,Toyama Chiho Railway Main Line,富山地铁本线,도야마 지방 철도 본선,#1D1686,2,T,,,,#1D1686,,,,SQUARE,,,,0,99408,1312.56347 +99409,160,富山地鉄立山線,トヤマチテツタテヤマセン,富山地鉄立山線,Toyama Chiho Railway Tateyama Line,Toyama Chiho Railway Tateyama Line,富山地铁立山线,도야마 지방 철도 다테야마선,#008000,2,T,,,,#008000,,,,SQUARE,,,,0,99409,1834.83282 +99410,160,富山地鉄不二越・上滝線,トヤマチテツフジコシ・カミダキセン,富山地鉄不二越・上滝線,Toyama Chiho Railway Fujikoshi-Kamidaki Line,Toyama Chiho Railway Fujikoshi-Kamidaki Line,富山地铁不二越・上泷线,도야마 지방 철도 후지코시·가미다키선,#7E490A,2,T,,,,#7E490A,,,,SQUARE,,,,0,99410,1139.17683 99411,161,神岡鉄道神岡線,カミオカテツドウカミオカセン,神岡鉄道神岡線,Kamioka Railway Kamioka Line,Kamioka Railway Kamioka Line,神冈铁道神冈线,가미오카 철도 가미오카선,#DC4C14,2,,,,,,,,,,,,,2,99411,3068.94038 99412,162,黒部峡谷鉄道本線,クロベキョウコクテツドウホンセン,黒部峡谷鉄道本線,Kurobe Gorge Main Line,Kurobe Gorge Main Line,黑部峡谷铁道本线,구로베 협곡 철도 본선,#EE7700,2,,,,,,,,,,,,,0,99412,5823.20369 -99413,160,富山地鉄市内線【1・2系統】,トヤマチテツシナイセン,富山地鉄市内線,Toyama City Tram Line Route 1/2,Toyama City Tram Line Route 1/2,富山地铁市内线【1・2系统】,도야마 지방 철도 시내선【1·2계통】,#EF1731,4,C,,,,#EF1731,,,,ROUND,,,,0,99413,392.45692 -99422,160,富山地鉄富山都心線【3系統(環状線)】,トヤマチテツトヤマトシンセン,富山地鉄富山都心線,Toyama City Tram Line Route 3,Toyama City Tram Line Route 3,富山地铁富山都心线【3系统(环状线)】,도야마 지방 철도 도야마 도심선【3계통(순환선)】,#4243BE,4,C,,,,#4243BE,,,,ROUND,,,,0,99413,320.62673 -99414,163,万葉線,マンヨウセン,万葉線,Manyo Line,Manyo Line,万叶线,만요선,#FF0B4B,4,,,,,,,,,,,,,0,99414,667.84205 -99415,160,富山港線,トヤマコウセン,富山港線,Toyamako line,Toyamako line,富山港线,도야마코선,#3698C4,4,C,,,,#3698C4,,,,ROUND,,,,0,99415,682.64928 -99416,165,北陸鉄道石川線,ホクリクテツドウイシカワセン,北陸鉄道石川線,Hokuriku Railroad Ishikawa Line,Hokuriku Railroad Ishikawa Line,北陆铁道石川线,호쿠리쿠 철도 이시카와선,#A9731E,2,I,,,,#008000,,,,ROUND,,,,0,99416,1058.51050 -99417,165,北陸鉄道浅野川線,ホクリクテツドウアサノガワセン,北陸鉄道浅野川線,Hokuriku Railroad Asanogawa Line,Hokuriku Railroad Asanogawa Line,北陆铁道浅野川线,호쿠리쿠 철도 아사노가와선,#559652,2,A,,,,#0067C0,,,,ROUND,,,,0,99417,692.31231 -99423,244,日本海ひすいライン,ニホンカイヒスイライン,日本海ひすいライン,Nihonkai Hisui Line,Nihonkai Hisui Line,日本海翡翠线,니혼카이 히스이 라인,#3782BD,2,,,,,,,,,,,,,0,99417,6025.30132 -99424,244,妙高はねうまライン,ミョウコウハネウマライン,妙高はねうまライン,Myoko Haneuma Line,Myoko Haneuma Line,妙高跃马线,묘코 하네우마 라인,#35C98E,2,,,,,,,,,,,,,0,99417,4355.59822 -99425,245,あいの風とやま鉄道線,アイノカゼトヤマテツドウセン,あいの風とやま鉄道線,Ainokaze Toyama Railway Line,Ainokaze Toyama Railway Line,爱之风富山铁道线,아이노카제 도야마 철도선,#63C65E,2,,,,,,,,,,,,,0,99417,5013.80816 -99426,246,IRいしかわ鉄道線,アイアールイシカワテツドウセン,IRいしかわ鉄道株式会社,IR Ishikawa Railway Line,IR Ishikawa Railway Line,IR石川铁道线,IR이시카와 철도선,#25A6DF,2,,,,,,,,,,,,,0,99417,4017.05120 -99418,166,のと鉄道七尾線,ノトテツドウナナオセン,のと鉄道七尾線,Noto Railway Nanao Line,Noto Railway Nanao Line,能登铁道七尾线,노토 철도 나나오선,#1594EB,2,,,,,,,,,,,,,0,99418,4787.98731 -99419,167,えちぜん鉄道勝山永平寺線,エチゼンテツドウカツヤマエイヘイジセン,えちぜん鉄道勝山永平寺線,Echizen Railway Katsuyama Eiheiji Line,Echizen Railway Katsuyama Eiheiji Line,越前铁道胜山永平寺线,에치젠 철도 가쓰야마에이헤이지선,#FD6802,2,E,,,,#FD6802,,,,ROUND,,,,0,99419,1393.72981 -99420,167,えちぜん鉄道三国芦原線,エチゼンテツドウミクニアワラセン,えちぜん鉄道三国芦原線,Echizen Railway Mikuni Ashihara Line,Echizen Railway Mikuni Ashihara Line,越前铁道三国芦原线,에치젠 철도 미쿠니아와라선,#0069FF,2,E,,,,#0069FF,,,,ROUND,,,,0,99420,1453.26464 +99413,160,富山地鉄市内線【1・2系統】,トヤマチテツシナイセン,富山地鉄市内線,Toyama City Tram Line Route 1/2,Toyama City Tram Line Route 1/2,富山地铁市内线【1・2系统】,도야마 지방 철도 시내선【1·2계통】,#EF1731,4,C,,,,#EF1731,,,,ROUND,,,,0,99413,390.42487 +99422,160,富山地鉄富山都心線【3系統(環状線)】,トヤマチテツトヤマトシンセン,富山地鉄富山都心線,Toyama City Tram Line Route 3,Toyama City Tram Line Route 3,富山地铁富山都心线【3系统(环状线)】,도야마 지방 철도 도야마 도심선【3계통(순환선)】,#4243BE,4,C,,,,#4243BE,,,,ROUND,,,,0,99413,316.9133 +99414,163,万葉線,マンヨウセン,万葉線,Manyo Line,Manyo Line,万叶线,만요선,#FF0B4B,4,,,,,,,,,,,,,0,99414,651.0786 +99415,160,富山港線,トヤマコウセン,富山港線,Toyamako line,Toyamako line,富山港线,도야마코선,#3698C4,4,C,,,,#3698C4,,,,ROUND,,,,0,99415,565.76659 +99416,165,北陸鉄道石川線,ホクリクテツドウイシカワセン,北陸鉄道石川線,Hokuriku Railroad Ishikawa Line,Hokuriku Railroad Ishikawa Line,北陆铁道石川线,호쿠리쿠 철도 이시카와선,#A9731E,2,I,,,,#008000,,,,ROUND,,,,0,99416,848.60776 +99417,165,北陸鉄道浅野川線,ホクリクテツドウアサノガワセン,北陸鉄道浅野川線,Hokuriku Railroad Asanogawa Line,Hokuriku Railroad Asanogawa Line,北陆铁道浅野川线,호쿠리쿠 철도 아사노가와선,#559652,2,A,,,,#0067C0,,,,ROUND,,,,0,99417,621.57908 +99423,244,日本海ひすいライン,ニホンカイヒスイライン,日本海ひすいライン,Nihonkai Hisui Line,Nihonkai Hisui Line,日本海翡翠线,니혼카이 히스이 라인,#3782BD,2,,,,,,,,,,,,,0,99417,4887.26227 +99424,244,妙高はねうまライン,ミョウコウハネウマライン,妙高はねうまライン,Myoko Haneuma Line,Myoko Haneuma Line,妙高跃马线,묘코 하네우마 라인,#35C98E,2,,,,,,,,,,,,,0,99417,4172.06803 +99425,245,あいの風とやま鉄道線,アイノカゼトヤマテツドウセン,あいの風とやま鉄道線,Ainokaze Toyama Railway Line,Ainokaze Toyama Railway Line,爱之风富山铁道线,아이노카제 도야마 철도선,#63C65E,2,,,,,,,,,,,,,0,99417,4573.88042 +99426,246,IRいしかわ鉄道線,アイアールイシカワテツドウセン,IRいしかわ鉄道株式会社,IR Ishikawa Railway Line,IR Ishikawa Railway Line,IR石川铁道线,IR이시카와 철도선,#25A6DF,2,,,,,,,,,,,,,0,99417,3553.1462 +99418,166,のと鉄道七尾線,ノトテツドウナナオセン,のと鉄道七尾線,Noto Railway Nanao Line,Noto Railway Nanao Line,能登铁道七尾线,노토 철도 나나오선,#1594EB,2,,,,,,,,,,,,,0,99418,4704.77949 +99419,167,えちぜん鉄道勝山永平寺線,エチゼンテツドウカツヤマエイヘイジセン,えちぜん鉄道勝山永平寺線,Echizen Railway Katsuyama Eiheiji Line,Echizen Railway Katsuyama Eiheiji Line,越前铁道胜山永平寺线,에치젠 철도 가쓰야마에이헤이지선,#FD6802,2,E,,,,#FD6802,,,,ROUND,,,,0,99419,1227.41572 +99420,167,えちぜん鉄道三国芦原線,エチゼンテツドウミクニアワラセン,えちぜん鉄道三国芦原線,Echizen Railway Mikuni Ashihara Line,Echizen Railway Mikuni Ashihara Line,越前铁道三国芦原线,에치젠 철도 미쿠니아와라선,#0069FF,2,E,,,,#0069FF,,,,ROUND,,,,0,99420,1148.51023 99421,168,福井鉄道福武線,フクイテツドウフクブセン,福井鉄道福武線,Fukui Railway Fukutake Line,Fukui Railway Fukutake Line,福井铁道福武线,후쿠이 철도 후쿠타케선,#197A3D,4,F,,,,#197A3D,,,,ROUND,,,,0,99421,1071.15936 -99428,251,ハピラインふくい線,ハピラインフクイセン,ハピラインふくい線,Hapi-line Fukui,Hapi-line Fukui线,Hapi线福井线,하피라인 후쿠이선,#EC1C9C,2,,,,,,,,,,,,,0,99426,4889.63467 -99501,169,伊豆急行線,イズキュウコウセン,伊豆急行線,Izu Kyuko Line,Izu Kyuko Line,伊豆急行线,이즈 급행선,#0085CD,2,IZ,,,,#000000,,,,SQUARE,,,,0,99501,3264.89597 -99502,128,伊豆箱根鉄道駿豆線,イズハコネテツドウスンズセン,伊豆箱根鉄道駿豆線,Izuhakone Railway Sunzu Line,Izuhakone Railway Sunzu Line,伊豆箱根铁道骏豆线,이즈하코네 철도 순즈선,#4086E5,2,IS,,,,#4086E5,,,,IZUHAKONE,,,,0,99502,1785.40075 -99503,170,岳南鉄道線,ガクナンテツドウセン,岳南鉄道線,Gakunan Railway Line,Gakunan Railway Line,岳南铁道线,가쿠난 철도선,#6B0102,2,GD,,,,#6B0102,,,,MONOCHROME_ROUND,,,,0,99503,1064.28294 -99504,171,静岡鉄道静岡清水線,シズオカテツドウシズオカシミズセン,静岡鉄道静岡清水線,Shizuoka Railway Shizuoka Shimizu Line,Shizuoka Railway Shizuoka Shimizu Line,静冈铁道静冈清水线,시즈오카 철도 시즈오카시미즈선,#0063B5,2,S,,,,#0094E2,,,,ROUND_HORIZONTAL,,,,0,99504,872.77620 -99505,172,天竜浜名湖線,テンリュウハマナコセン,天竜浜名湖鉄道天竜浜名湖線,Tenryu Hamanako Line,Tenryu Hamanako Line,天龙浜名湖线,덴류하마나코선,#95805A,2,,,,,,,,,,,,,0,99505,2034.68416 -99506,173,遠州鉄道鉄道線,エンシュウテツドウテツドウセン,遠州鉄道鉄道線,Enshu Railway Line,Enshu Railway Line,远州铁道铁道线,엔슈 철도선,#0672B0,2,ET,,,,#0672B0,,,,NUMBER_ONLY,,,,0,99506,1196.12682 -99507,174,大井川鐵道大井川本線,オオイガワテツドウオオイガワホンセン,大井川鐵道大井川本線,Oigawa Railway Oigawa Main Line,Oigawa Railway Oigawa Main Line,大井川铁道大井川本线,오이가와 철도 오이가와 본선,#F5F5F5,2,,,,,,,,,,,,,0,99507,2234.33864 -99508,174,南アルプスあぷとライン,ミナミアルプスアプトライン,大井川鐵道井川線,Oigawa Railway Ikawa Line,Oigawa Railway Ikawa Line,南阿尔卑斯阿普特线,미나미알프스 아프트 라인,#FFFFCC,2,,,,,,,,,,,,,0,99508,1661.77440 -99509,175,あおなみ線,アオナミセン,西名古屋港線,Aonami Line,Aonami Line,青波线,아오나미선,#464285,2,AN,,,,#464285,,,,ROUND,,,,0,99509,1669.75442 -99510,176,東海交通事業城北線,トウカイコウツウジギョウジョウホクセン,東海交通事業城北線,Tokai Transport Service Johoku Line,Tokai Transport Service Johoku Line,东海交通事业城北线,도카이 교통 사업 조호쿠선,#FF6600,2,,,,,,,,,,,,,0,99510,2514.93796 -99511,177,愛知環状鉄道線,アイチカンジョウテツドウセン,愛知環状鉄道線,Aichi Loop Line,Aichi Loop Line,爱知环状铁道线,아이치 간조 철도선,#2A359D,2,,,,,#2A359D,,,,MONOCHROME_ROUND,,,,0,99511,2286.71556 -99512,178,リニモ,リニモ,東部丘陵線,Linimo,Linimo,磁浮列车,리니모,#0D1F70,5,L,,,,#000000,,,,ROUND,,,,0,99512,1157.60300 -99513,179,名古屋市営地下鉄東山線,ナゴヤシエイチカテツヒガシヤマセン,名古屋市営地下鉄東山線,Nagoya Municipal Subway Higashiyama Line,Nagoya Municipal Subway Higashiyama Line,名古屋市营地铁东山线,나고야 시영 지하철 히가시야마선,#FFCC00,3,H,,,,#FFCC00,,,,ROUND,,,,0,99513,1047.63495 -99514,179,名古屋市営地下鉄名城線,ナゴヤシエイチカテツメイジョウセン,名古屋市営地下鉄名城線,Nagoya Municipal Subway Meijo Line,Nagoya Municipal Subway Meijo Line,名古屋市营地铁名城线,나고야 시영 지하철 메이조선,#9B74C1,3,M,,,,#9B74C1,,,,ROUND,,,,0,99514,998.16404 -99515,179,名古屋市営地下鉄名港線,ナゴヤシエイチカテツメイコウセン,名古屋市営地下鉄名港線,Nagoya Municipal Subway Meiko Line,Nagoya Municipal Subway Meiko Line,名古屋市营地铁名港线,나고야 시영 지하철 메이코선,#9B74C1,3,E,,,,#9B74C1,,,,ROUND,,,,0,99515,1088.86074 -99516,179,名古屋市営地下鉄鶴舞線,ナゴヤシエイチカテツツルマイセン,名古屋市営地下鉄鶴舞線,Nagoya Municipal Subway Tsurumai Line,Nagoya Municipal Subway Tsurumai Line,名古屋市营地铁鹤舞线,나고야 시영 지하철 쓰루마이선,#04ACDD,3,T,,,,#04ACDD,,,,ROUND,,,,0,99516,1137.79845 -99517,179,名古屋市営地下鉄桜通線,ナゴヤシエイチカテツサクラドオリセン,名古屋市営地下鉄桜通線,Nagoya Municipal Subway Sakuradori Line,Nagoya Municipal Subway Sakuradori Line,名古屋市营地铁樱通线,나고야 시영 지하철 사쿠라도리선,#FF0000,3,S,,,,#FF0000,,,,ROUND,,,,0,99517,1034.06206 -99518,179,名古屋市営地下鉄上飯田線,ナゴヤシエイチカテツカミイイダセン,名古屋市営地下鉄上飯田線,Nagoya Municipal Subway Kamiida Line,Nagoya Municipal Subway Kamiida Line,名古屋市营地铁上饭田线,나고야 시영 지하철 가미이다선,#FF66C4,3,K,,,,#FF66C4,,,,ROUND,,,,0,99518,967.73345 +99428,251,ハピラインふくい線,ハピラインフクイセン,ハピラインふくい線,Hapi-line Fukui,Hapi-line Fukui线,Hapi线福井线,하피라인 후쿠이선,#EC1C9C,2,,,,,,,,,,,,,0,99426,4390.58048 +99501,169,伊豆急行線,イズキュウコウセン,伊豆急行線,Izu Kyuko Line,Izu Kyuko Line,伊豆急行线,이즈 급행선,#0085CD,2,IZ,,,,#000000,,,,SQUARE,,,,0,99501,3006.10916 +99502,128,伊豆箱根鉄道駿豆線,イズハコネテツドウスンズセン,伊豆箱根鉄道駿豆線,Izuhakone Railway Sunzu Line,Izuhakone Railway Sunzu Line,伊豆箱根铁道骏豆线,이즈하코네 철도 순즈선,#4086E5,2,IS,,,,#4086E5,,,,IZUHAKONE,,,,0,99502,1608.83117 +99503,170,岳南鉄道線,ガクナンテツドウセン,岳南鉄道線,Gakunan Railway Line,Gakunan Railway Line,岳南铁道线,가쿠난 철도선,#6B0102,2,GD,,,,#6B0102,,,,MONOCHROME_ROUND,,,,0,99503,991.96997 +99504,171,静岡鉄道静岡清水線,シズオカテツドウシズオカシミズセン,静岡鉄道静岡清水線,Shizuoka Railway Shizuoka Shimizu Line,Shizuoka Railway Shizuoka Shimizu Line,静冈铁道静冈清水线,시즈오카 철도 시즈오카시미즈선,#0063B5,2,S,,,,#0094E2,,,,ROUND_HORIZONTAL,,,,0,99504,776.48074 +99505,172,天竜浜名湖線,テンリュウハマナコセン,天竜浜名湖鉄道天竜浜名湖線,Tenryu Hamanako Line,Tenryu Hamanako Line,天龙浜名湖线,덴류하마나코선,#95805A,2,,,,,,,,,,,,,0,99505,1739.51349 +99506,173,遠州鉄道鉄道線,エンシュウテツドウテツドウセン,遠州鉄道鉄道線,Enshu Railway Line,Enshu Railway Line,远州铁道铁道线,엔슈 철도선,#0672B0,2,ET,,,,#0672B0,,,,NUMBER_ONLY,,,,0,99506,1040.11028 +99507,174,大井川鐵道大井川本線,オオイガワテツドウオオイガワホンセン,大井川鐵道大井川本線,Oigawa Railway Oigawa Main Line,Oigawa Railway Oigawa Main Line,大井川铁道大井川本线,오이가와 철도 오이가와 본선,#F5F5F5,2,,,,,,,,,,,,,0,99507,2006.41977 +99508,174,南アルプスあぷとライン,ミナミアルプスアプトライン,大井川鐵道井川線,Oigawa Railway Ikawa Line,Oigawa Railway Ikawa Line,南阿尔卑斯阿普特线,미나미알프스 아프트 라인,#FFFFCC,2,,,,,,,,,,,,,0,99508,1871.28994 +99509,175,あおなみ線,アオナミセン,西名古屋港線,Aonami Line,Aonami Line,青波线,아오나미선,#464285,2,AN,,,,#464285,,,,ROUND,,,,0,99509,1494.42718 +99510,176,東海交通事業城北線,トウカイコウツウジギョウジョウホクセン,東海交通事業城北線,Tokai Transport Service Johoku Line,Tokai Transport Service Johoku Line,东海交通事业城北线,도카이 교통 사업 조호쿠선,#FF6600,2,,,,,,,,,,,,,0,99510,2210.03734 +99511,177,愛知環状鉄道線,アイチカンジョウテツドウセン,愛知環状鉄道線,Aichi Loop Line,Aichi Loop Line,爱知环状铁道线,아이치 간조 철도선,#2A359D,2,,,,,#2A359D,,,,MONOCHROME_ROUND,,,,0,99511,2022.52706 +99512,178,リニモ,リニモ,東部丘陵線,Linimo,Linimo,磁浮列车,리니모,#0D1F70,5,L,,,,#000000,,,,ROUND,,,,0,99512,1073.771 +99513,179,名古屋市営地下鉄東山線,ナゴヤシエイチカテツヒガシヤマセン,名古屋市営地下鉄東山線,Nagoya Municipal Subway Higashiyama Line,Nagoya Municipal Subway Higashiyama Line,名古屋市营地铁东山线,나고야 시영 지하철 히가시야마선,#FFCC00,3,H,,,,#FFCC00,,,,ROUND,,,,0,99513,966.08368 +99514,179,名古屋市営地下鉄名城線,ナゴヤシエイチカテツメイジョウセン,名古屋市営地下鉄名城線,Nagoya Municipal Subway Meijo Line,Nagoya Municipal Subway Meijo Line,名古屋市营地铁名城线,나고야 시영 지하철 메이조선,#9B74C1,3,M,,,,#9B74C1,,,,ROUND,,,,0,99514,917.56259 +99515,179,名古屋市営地下鉄名港線,ナゴヤシエイチカテツメイコウセン,名古屋市営地下鉄名港線,Nagoya Municipal Subway Meiko Line,Nagoya Municipal Subway Meiko Line,名古屋市营地铁名港线,나고야 시영 지하철 메이코선,#9B74C1,3,E,,,,#9B74C1,,,,ROUND,,,,0,99515,989.8734 +99516,179,名古屋市営地下鉄鶴舞線,ナゴヤシエイチカテツツルマイセン,名古屋市営地下鉄鶴舞線,Nagoya Municipal Subway Tsurumai Line,Nagoya Municipal Subway Tsurumai Line,名古屋市营地铁鹤舞线,나고야 시영 지하철 쓰루마이선,#04ACDD,3,T,,,,#04ACDD,,,,ROUND,,,,0,99516,1056.06986 +99517,179,名古屋市営地下鉄桜通線,ナゴヤシエイチカテツサクラドオリセン,名古屋市営地下鉄桜通線,Nagoya Municipal Subway Sakuradori Line,Nagoya Municipal Subway Sakuradori Line,名古屋市营地铁樱通线,나고야 시영 지하철 사쿠라도리선,#FF0000,3,S,,,,#FF0000,,,,ROUND,,,,0,99517,944.55051 +99518,179,名古屋市営地下鉄上飯田線,ナゴヤシエイチカテツカミイイダセン,名古屋市営地下鉄上飯田線,Nagoya Municipal Subway Kamiida Line,Nagoya Municipal Subway Kamiida Line,名古屋市营地铁上饭田线,나고야 시영 지하철 가미이다선,#FF66C4,3,K,,,,#FF66C4,,,,ROUND,,,,0,99518,879.75768 99519,180,ピーチライナー,ピーチライナー,桃花台新交通,Peach Liner,Peach Liner,桃花快线,피치 라이너,#F9F9F9,5,,,,,,,,,,,,,2,99519,1220.51679 -99520,181,豊橋鉄道渥美線,トヨハシテツドウアツミセン,豊橋鉄道渥美線,Toyohashi Railroad Atsumi Line,Toyohashi Railroad Atsumi Line,丰桥铁道渥美线,도요하시 철도 아쓰미선,#1A9B96,4,,,,,,,,,,,,,0,99520,1455.67964 +99520,181,豊橋鉄道渥美線,トヨハシテツドウアツミセン,豊橋鉄道渥美線,Toyohashi Railroad Atsumi Line,Toyohashi Railroad Atsumi Line,丰桥铁道渥美线,도요하시 철도 아쓰미선,#1A9B96,4,,,,,,,,,,,,,0,99520,1164.54371 99521,181,豊橋鉄道東田本線,トヨハシテツドウアヅマダホンセン,豊橋鉄道東田本線,Toyohashi Railroad Azumada Main Line,Toyohashi Railroad Azumada Main Line,丰桥铁道东田本线,도요하시 철도 아즈마다 본선,#1A9B96,4,,,,,,,,,,,,,0,99521,533.24363 99522,181,豊橋鉄道運動公園前線,トヨハシテツドウウンドウコウエンマエセン,豊橋鉄道運動公園前線,Toyohashi Railroad Yagyu-bashi Branch Line,Toyohashi Railroad Yagyu-bashi Branch Line,丰桥铁道运动公园前线,도요하시 철도 야규바시 지선,#1A9B96,4,,,,,,,,,,,,,2,99522,805.15292 99523,182,ゆとりーとライン,ユトリートライン,ガイドウェイバス志段味線,Yutorito Line,Yutorito Line,导向巴士志段味线,유토리토 라인,#3C459A,5,Y,,,,#3C459A,,,,ROUND,,,,0,99523,859.80651 -99524,183,明知鉄道明知線,アケチテツドウアケチセン,明知鉄道明知線,Akechi Railway Akechi Line,Akechi Railway Akechi Line,明知铁道明知线,아케치 철도 아케치선,#000000,2,,,,,#000000,,,,MONOCHROME_ROUND,,,,0,99524,2727.69903 -99525,184,長良川鉄道越美南線,ナガラガワテツドウエツミナンセン,長良川鉄道越美南線,Nagaragawa Railway Etsumi-Nan Line,Nagaragawa Railway Etsumi-Nan Line,长良川铁道越美南线,나가라가와 철도 에쓰미난선,#FF1493,2,,,,,#FF1493,,,,MONOCHROME_ROUND,,,,0,99525,2018.05476 -99526,185,樽見鉄道樽見線,タルミテツドウタルミセン,樽見鉄道樽見線,Tarumi Railway Tarumi Line,Tarumi Railway Tarumi Line,樽见铁道樽见线,다루미 철도 다루미선,#097AD6,2,TR,,,,#D50707,,,,REVERSED_ROUND_HORIZONTAL,,,,0,99526,2133.41625 -99528,186,三岐鉄道三岐線,サンギテツドウサンギセン,三岐鉄道三岐線,Sangi Railway Sanki Line,Sangi Railway Sanki Line,三岐铁道三岐线,산기 철도 산기선,#0D287C,2,,,,,,,,,,,,,0,99528,2087.87599 -99529,186,三岐鉄道北勢線,サンギテツドウホクセイセン,三岐鉄道北勢線,Sangi Railway Hokusei Line,Sangi Railway Hokusei Line,三岐铁道北势线,산기 철도 호쿠세이선,#0D287C,2,,,,,,,,,,,,,0,99529,1844.54791 -99530,187,伊勢鉄道伊勢線,イセテツドウイセセン,伊勢鉄道伊勢線,Ise Railway Ise Line,Ise Railway Ise Line,伊势铁道伊势线,이세 철도 이세선,#0300FA,2,,,,,,,,,,,,,0,99530,2798.16920 -99531,188,伊賀鉄道伊賀線,イガテツドウイガセン,伊賀鉄道伊賀線,Iga Railway Iga Line,Iga Railway Iga Line,伊贺铁道伊贺线,이가 철도 이가선,#895B8A,2,,,,,,,,,,,,,0,99531,1255.88040 -99532,189,養老鉄道養老線,ヨウロウテツドウヨウロウセン,養老鉄道養老線,Yoro Railway Yoro Line,Yoro Railway Yoro Line,养老铁道养老线,요로 철도 요로선,#ADDB8E,2,,,,,,,,,,,,,0,99532,2398.89369 -99601,190,近江鉄道本線,オウミテツドウホンセン,近江鉄道本線,Ohmi Railway Main Line,Ohmi Railway Main Line,近江铁道本线,오미 철도 본선,#DF8A28,2,OR,,,,#DF8A28,,,,ROUND,,,,0,99601,2321.41926 -99602,190,近江鉄道多賀線,オウミテツドウタガセン,近江鉄道多賀線,Ohmi Railway Taga Line,Ohmi Railway Taga Line,近江铁道多贺线,오미 철도 다가선,#DF8A28,2,OR,,,,#DF8A28,,,,ROUND,,,,0,99602,1381.37630 -99603,190,近江鉄道八日市線,オウミテツドウヨウカイチセン,近江鉄道八日市線,Ohmi Railway Yokaichi Line,Ohmi Railway Yokaichi Line,近江铁道八日市线,오미 철도 요카이치선,#DF8A28,2,OR,,,,#DF8A28,,,,ROUND,,,,0,99603,1733.51568 -99604,191,信楽高原鐵道信楽線,シガラキコウゲンテツドウシガラキセン,信楽高原鐵道信楽線,Shigaraki Kogen Railway Shigaraki Line,Shigaraki Kogen Railway Shigaraki Line,信乐高原铁道信乐线,시가라키 고원 철도 시가라키선,#FF6633,2,,,,,,,,,,,,,0,99604,2809.61231 -99605,192,嵯峨野観光線,サガノカンコウセン,嵯峨野観光線,Sagano Scenic Railway,Sagano Scenic Railway,嵯峨野观光线,사가노 관광선,#B22222,2,,,,,,,,,,,,,0,99605,2777.76513 -99606,193,叡山電鉄叡山本線,エイザンデンテツエイザンホンセン,叡山電鉄叡山本線,Eizan Electric Railway Eizan Main Line,Eizan Electric Railway Eizan Main Line,叡山电铁叡山本线,에이잔 전철 에이잔 본선,#007F00,2,E,,,,#007F00,,,,KEIHAN,,,,0,99606,892.79646 -99607,193,叡山電鉄鞍馬線,エイザンデンテツクラマセン,叡山電鉄鞍馬線,Eizan Electric Railway Kurama Line,Eizan Electric Railway Kurama Line,叡山电铁鞍马线,에이잔 전철 구라마선,#FF0000,2,E,,,,#007F00,,,,KEIHAN,,,,0,99607,1046.04805 -99608,194,宮福線,ミヤフクセン,宮福線,Miyafuku Line,Miyafuku Line,宫福线,미야후쿠선,#429BE1,2,F,,,,#EA4F6F,,,,REVERSED_SQUARE,,,,0,99608,2574.35071 -99609,194,宮豊線,ミヤトヨセン,宮豊線,Miyatoyo Line,Miyatoyo Line,宫丰线,미야토요선,#FF4E6F,2,T,,,,#EA4F6F,,,,REVERSED_SQUARE,,,,0,99609,4761.87402 -99653,194,宮舞線,ミヤマイセン,宮舞線,Miyamai Line,Miyamai Line,宫舞线,미야마이선,#B230D1,0,M,,,,#EA4F6F,,,,REVERSED_SQUARE,,,,0,99609,3942.19922 -99610,195,京都市営地下鉄烏丸線,キョウトシエイチカテツカラスマセン,京都市営地下鉄烏丸線,Kyoto Municipal Subway Karasuma Line,Kyoto Municipal Subway Karasuma Line,京都市营地铁乌丸线,교토 시영 지하철 가라스마선,#66CC99,3,K,,,,#66CC99,,,,REVERSED_ROUND,,,,0,99610,1042.00981 -99611,195,京都市営地下鉄東西線,キョウトシエイチカテツトウザイセン,京都市営地下鉄東西線,Kyoto Municipal Subway Tozai Line,Kyoto Municipal Subway Tozai Line,京都市营地铁东西线,교토 시영 지하철 도자이선,#FF6600,3,T,,,,#FF6600,,,,REVERSED_ROUND,,,,0,99611,1159.56897 -99612,196,京福電鉄嵐山本線,ケイフクデンテツアラシヤマホンセン,京福電鉄嵐山本線,Keifuku Electric Railway Arashiyama Main Line,Keifuku Electric Railway Arashiyama Main Line,京福电铁岚山本线,게이후쿠 전철 아라시야마 본선,#CC0033,4,A,,,,#CC0033,,,,REVERSED_ROUND_HORIZONTAL,,,,0,99612,887.05308 +99524,183,明知鉄道明知線,アケチテツドウアケチセン,明知鉄道明知線,Akechi Railway Akechi Line,Akechi Railway Akechi Line,明知铁道明知线,아케치 철도 아케치선,#000000,2,,,,,#000000,,,,MONOCHROME_ROUND,,,,0,99524,2433.10424 +99525,184,長良川鉄道越美南線,ナガラガワテツドウエツミナンセン,長良川鉄道越美南線,Nagaragawa Railway Etsumi-Nan Line,Nagaragawa Railway Etsumi-Nan Line,长良川铁道越美南线,나가라가와 철도 에쓰미난선,#FF1493,2,,,,,#FF1493,,,,MONOCHROME_ROUND,,,,0,99525,1895.06044 +99526,185,樽見鉄道樽見線,タルミテツドウタルミセン,樽見鉄道樽見線,Tarumi Railway Tarumi Line,Tarumi Railway Tarumi Line,樽见铁道樽见线,다루미 철도 다루미선,#097AD6,2,TR,,,,#D50707,,,,REVERSED_ROUND_HORIZONTAL,,,,0,99526,1880.2054 +99528,186,三岐鉄道三岐線,サンギテツドウサンギセン,三岐鉄道三岐線,Sangi Railway Sanki Line,Sangi Railway Sanki Line,三岐铁道三岐线,산기 철도 산기선,#0D287C,2,,,,,,,,,,,,,0,99528,1855.04828 +99529,186,三岐鉄道北勢線,サンギテツドウホクセイセン,三岐鉄道北勢線,Sangi Railway Hokusei Line,Sangi Railway Hokusei Line,三岐铁道北势线,산기 철도 호쿠세이선,#0D287C,2,,,,,,,,,,,,,0,99529,1652.78385 +99530,187,伊勢鉄道伊勢線,イセテツドウイセセン,伊勢鉄道伊勢線,Ise Railway Ise Line,Ise Railway Ise Line,伊势铁道伊势线,이세 철도 이세선,#0300FA,2,,,,,,,,,,,,,0,99530,2449.10241 +99531,188,伊賀鉄道伊賀線,イガテツドウイガセン,伊賀鉄道伊賀線,Iga Railway Iga Line,Iga Railway Iga Line,伊贺铁道伊贺线,이가 철도 이가선,#895B8A,2,,,,,,,,,,,,,0,99531,1140.55469 +99532,189,養老鉄道養老線,ヨウロウテツドウヨウロウセン,養老鉄道養老線,Yoro Railway Yoro Line,Yoro Railway Yoro Line,养老铁道养老线,요로 철도 요로선,#ADDB8E,2,,,,,,,,,,,,,0,99532,2174.94449 +99601,190,近江鉄道本線,オウミテツドウホンセン,近江鉄道本線,Ohmi Railway Main Line,Ohmi Railway Main Line,近江铁道本线,오미 철도 본선,#DF8A28,2,OR,,,,#DF8A28,,,,ROUND,,,,0,99601,1965.32482 +99602,190,近江鉄道多賀線,オウミテツドウタガセン,近江鉄道多賀線,Ohmi Railway Taga Line,Ohmi Railway Taga Line,近江铁道多贺线,오미 철도 다가선,#DF8A28,2,OR,,,,#DF8A28,,,,ROUND,,,,0,99602,1201.19679 +99603,190,近江鉄道八日市線,オウミテツドウヨウカイチセン,近江鉄道八日市線,Ohmi Railway Yokaichi Line,Ohmi Railway Yokaichi Line,近江铁道八日市线,오미 철도 요카이치선,#DF8A28,2,OR,,,,#DF8A28,,,,ROUND,,,,0,99603,1507.40494 +99604,191,信楽高原鐵道信楽線,シガラキコウゲンテツドウシガラキセン,信楽高原鐵道信楽線,Shigaraki Kogen Railway Shigaraki Line,Shigaraki Kogen Railway Shigaraki Line,信乐高原铁道信乐线,시가라키 고원 철도 시가라키선,#FF6633,2,,,,,,,,,,,,,0,99604,2902.2727 +99605,192,嵯峨野観光線,サガノカンコウセン,嵯峨野観光線,Sagano Scenic Railway,Sagano Scenic Railway,嵯峨野观光线,사가노 관광선,#B22222,2,,,,,,,,,,,,,0,99605,2881.21078 +99606,193,叡山電鉄叡山本線,エイザンデンテツエイザンホンセン,叡山電鉄叡山本線,Eizan Electric Railway Eizan Main Line,Eizan Electric Railway Eizan Main Line,叡山电铁叡山本线,에이잔 전철 에이잔 본선,#007F00,2,E,,,,#007F00,,,,KEIHAN,,,,0,99606,776.34475 +99607,193,叡山電鉄鞍馬線,エイザンデンテツクラマセン,叡山電鉄鞍馬線,Eizan Electric Railway Kurama Line,Eizan Electric Railway Kurama Line,叡山电铁鞍马线,에이잔 전철 구라마선,#FF0000,2,E,,,,#007F00,,,,KEIHAN,,,,0,99607,920.4243 +99608,194,宮福線,ミヤフクセン,宮福線,Miyafuku Line,Miyafuku Line,宫福线,미야후쿠선,#429BE1,2,F,,,,#EA4F6F,,,,REVERSED_SQUARE,,,,0,99608,2310.20684 +99609,194,宮豊線,ミヤトヨセン,宮豊線,Miyatoyo Line,Miyatoyo Line,宫丰线,미야토요선,#FF4E6F,2,T,,,,#EA4F6F,,,,REVERSED_SQUARE,,,,0,99609,4782.36439 +99653,194,宮舞線,ミヤマイセン,宮舞線,Miyamai Line,Miyamai Line,宫舞线,미야마이선,#B230D1,0,M,,,,#EA4F6F,,,,REVERSED_SQUARE,,,,0,99609,4054.13143 +99610,195,京都市営地下鉄烏丸線,キョウトシエイチカテツカラスマセン,京都市営地下鉄烏丸線,Kyoto Municipal Subway Karasuma Line,Kyoto Municipal Subway Karasuma Line,京都市营地铁乌丸线,교토 시영 지하철 가라스마선,#66CC99,3,K,,,,#66CC99,,,,REVERSED_ROUND,,,,0,99610,971.61203 +99611,195,京都市営地下鉄東西線,キョウトシエイチカテツトウザイセン,京都市営地下鉄東西線,Kyoto Municipal Subway Tozai Line,Kyoto Municipal Subway Tozai Line,京都市营地铁东西线,교토 시영 지하철 도자이선,#FF6600,3,T,,,,#FF6600,,,,REVERSED_ROUND,,,,0,99611,1070.20956 +99612,196,京福電鉄嵐山本線,ケイフクデンテツアラシヤマホンセン,京福電鉄嵐山本線,Keifuku Electric Railway Arashiyama Main Line,Keifuku Electric Railway Arashiyama Main Line,京福电铁岚山本线,게이후쿠 전철 아라시야마 본선,#CC0033,4,A,,,,#CC0033,,,,REVERSED_ROUND_HORIZONTAL,,,,0,99612,625.336 99613,196,京福電鉄北野線,ケイフクデンテツキタノセン,京福電鉄北野線,Keifuku Electric Railway Kitano Line,Keifuku Electric Railway Kitano Line,京福电铁北野线,게이후쿠 전철 기타노선,#6666CC,4,B,A,,,#6666CC,#CC0033,,,REVERSED_ROUND_HORIZONTAL,,,,0,99613,509.30112 -99614,197,北大阪急行電鉄,キタオオサカキュウコウデンテツ,北大阪急行電鉄,Kita Osaka Express Electric Railway,Kita Osaka Express Electric Railway,北大阪急行电铁,기타오사카 급행 전철,#DD5B5C,2,M,,,,#E5171F,,,,REVERSED_ROUND,,,,0,99614,1887.07466 -99616,22,南海泉北線,ナンカイセンボクセン,南海泉北線,Nankai Semboku Line,Nankai Semboku Line,南海泉北线,난카이 센보쿠선,#0099FF,2,NK,,,,#000000,,,,NANKAI,,,,0,99616,3068.07668 -99617,199,水間鉄道水間線,ミズマテツドウミズマセン,水間鉄道水間線,Mizuma Railway Mizuma Line,Mizuma Railway Mizuma Line,水间铁道水间线,미즈마 철도 미즈마선,#005CB1,2,,,,,,,,,,,,,0,99617,687.45759 -99618,249,Osaka Metro御堂筋線,オオサカメトロミドウスジセン,高速電気軌道第1号線,Osaka Metro Midosuji Line,Osaka Metro Midosuji Line,御堂筋线,미도스지선,#E5171F,3,M,,,,#E5171F,,,,REVERSED_ROUND,,,,0,99618,1378.47226 -99619,249,Osaka Metro谷町線,オオサカメトロタニマチセン,高速電気軌道第2号線,Osaka Metro Tanimachi Line,Osaka Metro Tanimachi Line,谷町线,다니마치선,#522886,3,T,,,,#522886,,,,REVERSED_ROUND,,,,0,99619,1164.23432 -99620,249,Osaka Metro四つ橋線,オオサカメトロヨツバシセン,高速電気軌道第3号線,Osaka Metro Yotsubashi Line,Osaka Metro Yotsubashi Line,四桥线,요쓰바시선,#0078BA,3,Y,,,,#0078BA,,,,REVERSED_ROUND,,,,0,99620,1223.52640 -99621,249,Osaka Metro中央線,オオサカメトロチュウオウセン,高速電気軌道第4号線,Osaka Metro Chuo Line,Osaka Metro Chuo Line,中央线,주오선,#019A66,3,C,,,,#019A66,,,,REVERSED_ROUND,,,,0,99621,1571.42190 -99622,249,Osaka Metro千日前線,オオサカメトロセンニチマエセン,高速電気軌道第5号線,Osaka Metro Sennichimae Line,Osaka Metro Sennichimae Line,千日前线,센니치마에선,#E44D93,3,S,,,,#E44D93,,,,REVERSED_ROUND,,,,0,99622,1024.25759 -99623,249,Osaka Metro堺筋線,オオサカメトロサカイスジセン,高速電気軌道第6号線,Osaka Metro Sakaisuji Line,Osaka Metro Sakaisuji Line,堺筋线,사카이스지선,#814721,3,K,,,,#814721,,,,REVERSED_ROUND,,,,0,99623,1034.84196 -99624,249,Osaka Metro長堀鶴見緑地線,オオサカメトロナガホリツルミリョクチセン,高速電気軌道第7号線,Osaka Metro Nagahori Tsurumi-ryokuchi Line,Osaka Metro Nagahori Tsurumi-ryokuchi Line,长堀鹤见绿地线,나가호리쓰루미료쿠치선,#A9CC51,3,N,,,,#A9CC51,,,,REVERSED_ROUND,,,,0,99624,982.61129 +99614,197,北大阪急行電鉄,キタオオサカキュウコウデンテツ,北大阪急行電鉄,Kita Osaka Express Electric Railway,Kita Osaka Express Electric Railway,北大阪急行电铁,기타오사카 급행 전철,#DD5B5C,2,M,,,,#E5171F,,,,REVERSED_ROUND,,,,0,99614,1656.79284 +99616,22,南海泉北線,ナンカイセンボクセン,南海泉北線,Nankai Semboku Line,Nankai Semboku Line,南海泉北线,난카이 센보쿠선,#0099FF,2,NK,,,,#000000,,,,NANKAI,,,,0,99616,2819.48165 +99617,199,水間鉄道水間線,ミズマテツドウミズマセン,水間鉄道水間線,Mizuma Railway Mizuma Line,Mizuma Railway Mizuma Line,水间铁道水间线,미즈마 철도 미즈마선,#005CB1,2,,,,,,,,,,,,,0,99617,628.45348 +99618,249,Osaka Metro御堂筋線,オオサカメトロミドウスジセン,高速電気軌道第1号線,Osaka Metro Midosuji Line,Osaka Metro Midosuji Line,御堂筋线,미도스지선,#E5171F,3,M,,,,#E5171F,,,,REVERSED_ROUND,,,,0,99618,1280.32033 +99619,249,Osaka Metro谷町線,オオサカメトロタニマチセン,高速電気軌道第2号線,Osaka Metro Tanimachi Line,Osaka Metro Tanimachi Line,谷町线,다니마치선,#522886,3,T,,,,#522886,,,,REVERSED_ROUND,,,,0,99619,1088.54456 +99620,249,Osaka Metro四つ橋線,オオサカメトロヨツバシセン,高速電気軌道第3号線,Osaka Metro Yotsubashi Line,Osaka Metro Yotsubashi Line,四桥线,요쓰바시선,#0078BA,3,Y,,,,#0078BA,,,,REVERSED_ROUND,,,,0,99620,1119.92896 +99621,249,Osaka Metro中央線,オオサカメトロチュウオウセン,高速電気軌道第4号線,Osaka Metro Chuo Line,Osaka Metro Chuo Line,中央线,주오선,#019A66,3,C,,,,#019A66,,,,REVERSED_ROUND,,,,0,99621,1489.20988 +99622,249,Osaka Metro千日前線,オオサカメトロセンニチマエセン,高速電気軌道第5号線,Osaka Metro Sennichimae Line,Osaka Metro Sennichimae Line,千日前线,센니치마에선,#E44D93,3,S,,,,#E44D93,,,,REVERSED_ROUND,,,,0,99622,950.83706 +99623,249,Osaka Metro堺筋線,オオサカメトロサカイスジセン,高速電気軌道第6号線,Osaka Metro Sakaisuji Line,Osaka Metro Sakaisuji Line,堺筋线,사카이스지선,#814721,3,K,,,,#814721,,,,REVERSED_ROUND,,,,0,99623,940.76542 +99624,249,Osaka Metro長堀鶴見緑地線,オオサカメトロナガホリツルミリョクチセン,高速電気軌道第7号線,Osaka Metro Nagahori Tsurumi-ryokuchi Line,Osaka Metro Nagahori Tsurumi-ryokuchi Line,长堀鹤见绿地线,나가호리쓰루미료쿠치선,#A9CC51,3,N,,,,#A9CC51,,,,REVERSED_ROUND,,,,0,99624,908.75103 99652,249,Osaka Metro今里筋線,オオサカメトロイマザトスジセン,高速電気軌道第8号線,Osaka Metro Imazatosuji Line,Osaka Metro Imazatosuji Line,今里筋线,이마자토스지선,#EE7B1A,3,I,,,,#EE7B1A,,,,REVERSED_ROUND,,,,0,99624,1270.47569 -99625,249,Osaka Metro南港ポートタウン線,オオサカメトロナンコウポートタウンセン,大阪市高速電気軌道南港ポートタウン線,Osaka Metro Nanko Port Town Line,Osaka Metro Nanko Port Town Line,南港港城线,포트타운선,#00A0DE,5,P,,,,#00A0DE,,,,REVERSED_ROUND,,,,0,99625,921.36230 -99626,201,大阪モノレール線,オオサカモノレールセン,大阪モノレール線,Osaka Monorail Main Line,Osaka Monorail Main Line,大阪单轨电车线,오사카 모노레일선,#5058C3,5,,,,,,,,,,,,,0,99626,1656.77836 -99627,201,大阪モノレール彩都線,オオサカモノレールサイトセン,国際文化公園都市線,Osaka Monorail Saito Line,Osaka Monorail Saito Line,大阪单轨电车彩都线,오사카 모노레일 사이토선,#5058C3,5,,,,,,,,,,,,,0,99627,1737.16271 -99628,202,阪堺電軌上町線,ハンカイデンキウエマチセン,阪堺電軌上町線,Hankai Uemachi Line,Hankai Uemachi Line,阪堺电轨上町线,한카이 우에마치선,#083388,4,HN,,,,#000000,,,,SQUARE,,,,0,99628,551.14177 -99629,202,阪堺電軌阪堺線,ハンカイデンキハンカイセン,阪堺電軌阪堺線,Hankai Line,Hankai Line,阪堺电轨阪堺线,한카이선,#008947,4,HN,,,,#000000,,,,SQUARE,,,,0,99629,636.63244 -99630,203,神戸高速東西線,コウベコウソクトウザイセン,神戸高速東西線,Kobe Rapid Transit Railway Tozai Line,Kobe Rapid Transit Railway Tozai Line,神户高速东西线,고베 고속 도자이선,#2560A8,2,HS,HK,SY,,#2560A8,#2560A8,#F45757,,HANSHIN,HANKYU,SANYO,,0,99630,1006.25901 -99631,203,神戸高速南北線,コウベコウソクナンボクセン,神戸高速南北線,Kobe Rapid Transit Railway Namboku Line,Kobe Rapid Transit Railway Namboku Line,神户高速南北线,고베 고속 난보쿠선,#2560A8,2,KB,,,,#DD0033,,,,HANSHIN,,,,0,99631,505.26806 -99632,204,有馬線,アリマセン,神鉄有馬線,Arima Line,Arima Line,有马线,아리마선,#D53924,2,KB,,,,#DD0033,,,,HANSHIN,,,,0,99632,1458.12743 -99633,204,三田線,サンダセン,神鉄三田線,Sanda Line,Sanda Line,三田线,산다선,#D53924,2,KB,,,,#DD0033,,,,HANSHIN,,,,0,99633,1427.85631 -99634,204,公園都市線,コウエントシセン,神鉄公園都市線,Koen-Toshi Line,Koen-Toshi Line,公园都市线,고엔토시선,#D53924,2,KB,,,,#DD0033,,,,HANSHIN,,,,0,99634,1575.43661 -99635,204,粟生線,アオセン,神鉄粟生線,Ao Line,Ao Line,粟生线,아오선,#D53924,2,KB,,,,#DD0033,,,,HANSHIN,,,,0,99635,1669.54643 -99636,211,神戸市営地下鉄北神線,コウベシエイチカテツホクシンセン,神戸市営地下鉄北神線,Kobe Municipal Subway Hokushin Line,Kobe Municipal Subway Hokushin Line,神户市营地铁北神线,고베 시영 지하철 호쿠신선,#D59A00,2,S,S,,,#01AF98,#01AF98,,,SQUARE,REVERSED_SQUARE_WEST,,,0,99636,7516.62916 -99637,206,山陽電鉄本線,サンヨウデンテツホンセン,山陽電鉄本線,Sanyo Electric Railway Main Line,Sanyo Electric Railway Main Line,山阳电铁本线,산요 전철 본선,#F45757,2,SY,,,,#ED1A3D,,,,SANYO,,,,0,99637,1467.50825 -99638,206,山陽電鉄網干線,サンヨウデンテツアボシセン,山陽電鉄網干線,Sanyo Electric Railway Aboshi Line,Sanyo Electric Railway Aboshi Line,山阳电铁网干线,산요 전철 아보시선,#F45757,2,SY,,,,#ED1A3D,,,,SANYO,,,,0,99638,1597.08919 -99615,207,能勢電鉄妙見線,ノセデンテツミョウケンセン,能勢電鉄妙見線,Nose Electric Railway Myoken Line,Nose Electric Railway Myoken Line,能势电铁妙见线,노세 전철 묘켄선,#B72142,2,NS,,,,#B72142,,,,REVERSED_ROUND,,,,0,99640,1027.59969 -99640,207,能勢電鉄日生線,ノセデンテツニッセイセン,能勢電鉄日生線,Nose Electric Railway Nissei Line,Nose Electric Railway Nissei Line,能势电铁日生线,노세 전철 닛세이선,#B72142,2,NS,,,,#B72142,,,,REVERSED_ROUND,,,,0,99640,2634.71132 +99625,249,Osaka Metro南港ポートタウン線,オオサカメトロナンコウポートタウンセン,大阪市高速電気軌道南港ポートタウン線,Osaka Metro Nanko Port Town Line,Osaka Metro Nanko Port Town Line,南港港城线,포트타운선,#00A0DE,5,P,,,,#00A0DE,,,,REVERSED_ROUND,,,,0,99625,849.64254 +99626,201,大阪モノレール線,オオサカモノレールセン,大阪モノレール線,Osaka Monorail Main Line,Osaka Monorail Main Line,大阪单轨电车线,오사카 모노레일선,#5058C3,5,,,,,,,,,,,,,0,99626,1598.41043 +99627,201,大阪モノレール彩都線,オオサカモノレールサイトセン,国際文化公園都市線,Osaka Monorail Saito Line,Osaka Monorail Saito Line,大阪单轨电车彩都线,오사카 모노레일 사이토선,#5058C3,5,,,,,,,,,,,,,0,99627,1635.81889 +99628,202,阪堺電軌上町線,ハンカイデンキウエマチセン,阪堺電軌上町線,Hankai Uemachi Line,Hankai Uemachi Line,阪堺电轨上町线,한카이 우에마치선,#083388,4,HN,,,,#000000,,,,SQUARE,,,,0,99628,585.20252 +99629,202,阪堺電軌阪堺線,ハンカイデンキハンカイセン,阪堺電軌阪堺線,Hankai Line,Hankai Line,阪堺电轨阪堺线,한카이선,#008947,4,HN,,,,#000000,,,,SQUARE,,,,0,99629,488.59702 +99630,203,神戸高速東西線,コウベコウソクトウザイセン,神戸高速東西線,Kobe Rapid Transit Railway Tozai Line,Kobe Rapid Transit Railway Tozai Line,神户高速东西线,고베 고속 도자이선,#2560A8,2,HS,HK,SY,,#2560A8,#2560A8,#F45757,,HANSHIN,HANKYU,SANYO,,0,99630,875.00784 +99631,203,神戸高速南北線,コウベコウソクナンボクセン,神戸高速南北線,Kobe Rapid Transit Railway Namboku Line,Kobe Rapid Transit Railway Namboku Line,神户高速南北线,고베 고속 난보쿠선,#2560A8,2,KB,,,,#DD0033,,,,HANSHIN,,,,0,99631,439.36353 +99632,204,有馬線,アリマセン,神鉄有馬線,Arima Line,Arima Line,有马线,아리마선,#D53924,2,KB,,,,#DD0033,,,,HANSHIN,,,,0,99632,1532.09535 +99633,204,三田線,サンダセン,神鉄三田線,Sanda Line,Sanda Line,三田线,산다선,#D53924,2,KB,,,,#DD0033,,,,HANSHIN,,,,0,99633,1275.15137 +99634,204,公園都市線,コウエントシセン,神鉄公園都市線,Koen-Toshi Line,Koen-Toshi Line,公园都市线,고엔토시선,#D53924,2,KB,,,,#DD0033,,,,HANSHIN,,,,0,99634,1435.16656 +99635,204,粟生線,アオセン,神鉄粟生線,Ao Line,Ao Line,粟生线,아오선,#D53924,2,KB,,,,#DD0033,,,,HANSHIN,,,,0,99635,1512.8307 +99636,211,神戸市営地下鉄北神線,コウベシエイチカテツホクシンセン,神戸市営地下鉄北神線,Kobe Municipal Subway Hokushin Line,Kobe Municipal Subway Hokushin Line,神户市营地铁北神线,고베 시영 지하철 호쿠신선,#D59A00,2,S,S,,,#01AF98,#01AF98,,,SQUARE,REVERSED_SQUARE_WEST,,,0,99636,7328.54641 +99637,206,山陽電鉄本線,サンヨウデンテツホンセン,山陽電鉄本線,Sanyo Electric Railway Main Line,Sanyo Electric Railway Main Line,山阳电铁本线,산요 전철 본선,#F45757,2,SY,,,,#ED1A3D,,,,SANYO,,,,0,99637,1280.1745 +99638,206,山陽電鉄網干線,サンヨウデンテツアボシセン,山陽電鉄網干線,Sanyo Electric Railway Aboshi Line,Sanyo Electric Railway Aboshi Line,山阳电铁网干线,산요 전철 아보시선,#F45757,2,SY,,,,#ED1A3D,,,,SANYO,,,,0,99638,1444.82485 +99615,207,能勢電鉄妙見線,ノセデンテツミョウケンセン,能勢電鉄妙見線,Nose Electric Railway Myoken Line,Nose Electric Railway Myoken Line,能势电铁妙见线,노세 전철 묘켄선,#B72142,2,NS,,,,#B72142,,,,REVERSED_ROUND,,,,0,99640,902.44973 +99640,207,能勢電鉄日生線,ノセデンテツニッセイセン,能勢電鉄日生線,Nose Electric Railway Nissei Line,Nose Electric Railway Nissei Line,能势电铁日生线,노세 전철 닛세이선,#B72142,2,NS,,,,#B72142,,,,REVERSED_ROUND,,,,0,99640,2478.49816 99642,208,三木鉄道三木線,ミキテツドウミキセン,三木鉄道三木線,Miki Railway Miki Line,Miki Railway Miki Line,三木铁道三木线,미키 철도 미키선,#009CFF,2,,,,,,,,,,,,,2,99642,948.45333 -99643,209,北条鉄道北条線,ホウジョウテツドウホウジョウセン,北条鉄道北条線,Hojo Line,Hojo Line,北条铁道北条线,호조 철도 호조선,#7564D3,2,,,,,,,,,,,,,0,99643,2120.09577 -99644,210,智頭急行智頭線,チズキュウコウチズセン,智頭急行智頭線,Chizu Express Chizu Line,Chizu Express Chizu Line,智头急行智头线,지즈 급행 지즈선,#000099,2,,,,,,,,,,,,,0,99644,4590.31317 -99645,211,神戸市営地下鉄西神線,コウベシエイチカテツセイシンセン,神戸市営地下鉄西神線,Kobe Municipal Subway Seishin Line,Kobe Municipal Subway Seishin Line,神户市营地铁西神线,고베 시영 지하철 세이신선,#01AF98,3,S,,,,#01AF98,,,,REVERSED_SQUARE_WEST,,,,0,99645,1992.48519 -99646,211,神戸市営地下鉄山手線,コウベシエイチカテツヤマテセン,神戸市営地下鉄山手線,Kobe Municipal Subway Yamate Line,Kobe Municipal Subway Yamate Line,神户市营地铁山手线,고베 시영 지하철 야마테선,#01AF98,3,S,,,,#01AF98,,,,REVERSED_SQUARE_WEST,,,,0,99646,1160.17977 -99647,211,神戸市営地下鉄海岸線,コウベシエイチカテツカイガンセン,神戸市営地下鉄海岸線,Kobe Municipal Subway Kaigan Line,Kobe Municipal Subway Kaigan Line,神户市营地铁海岸线,고베 시영 지하철 가이간선,#0388C0,3,K,,,,#0388C0,,,,REVERSED_SQUARE_WEST,,,,0,99647,940.93299 +99643,209,北条鉄道北条線,ホウジョウテツドウホウジョウセン,北条鉄道北条線,Hojo Line,Hojo Line,北条铁道北条线,호조 철도 호조선,#7564D3,2,,,,,,,,,,,,,0,99643,1919.58856 +99644,210,智頭急行智頭線,チズキュウコウチズセン,智頭急行智頭線,Chizu Express Chizu Line,Chizu Express Chizu Line,智头急行智头线,지즈 급행 지즈선,#000099,2,,,,,,,,,,,,,0,99644,4299.89441 +99645,211,神戸市営地下鉄西神線,コウベシエイチカテツセイシンセン,神戸市営地下鉄西神線,Kobe Municipal Subway Seishin Line,Kobe Municipal Subway Seishin Line,神户市营地铁西神线,고베 시영 지하철 세이신선,#01AF98,3,S,,,,#01AF98,,,,REVERSED_SQUARE_WEST,,,,0,99645,1844.9049 +99646,211,神戸市営地下鉄山手線,コウベシエイチカテツヤマテセン,神戸市営地下鉄山手線,Kobe Municipal Subway Yamate Line,Kobe Municipal Subway Yamate Line,神户市营地铁山手线,고베 시영 지하철 야마테선,#01AF98,3,S,,,,#01AF98,,,,REVERSED_SQUARE_WEST,,,,0,99646,1083.42685 +99647,211,神戸市営地下鉄海岸線,コウベシエイチカテツカイガンセン,神戸市営地下鉄海岸線,Kobe Municipal Subway Kaigan Line,Kobe Municipal Subway Kaigan Line,神户市营地铁海岸线,고베 시영 지하철 가이간선,#0388C0,3,K,,,,#0388C0,,,,REVERSED_SQUARE_WEST,,,,0,99647,864.59592 99648,212,ポートライナー,ポートライナー,神戸新交通ポートアイランド線,Port Liner,Port Liner,港湾人工岛线,포트 라이너,#9686BD,5,P,PL,,,#9686BD,#9686BD,,,REVERSED_SQUARE,REVERSED_SQUARE,,,0,99648,1147.16066 -99649,212,六甲ライナー,ロッコウライナー,神戸新交通六甲アイランド線,Rokko Liner,Rokko Liner,六甲人工岛线,롯코 라이너,#9686BD,5,R,,,,#9686BD,,,,REVERSED_SQUARE,,,,0,99649,915.33649 -99650,213,紀州鉄道線,キシュウテツドウセン,紀州鉄道線,Kishu Railway Line,Kishu Railway Line,纪州铁道线,기슈 철도선,#081042,2,,,,,,,,,,,,,0,99650,698.90719 -99651,214,貴志川線,キシガワセン,和歌山電鐵貴志川線,Kishigawa Line,Kishigawa Line,贵志川线,기시가와선,#DA381B,2,,,,,,,,,,,,,0,99651,1209.46837 -99701,215,若桜線,ワカサセン,若桜鉄道若桜線,Wakasa Line,Wakasa Line,若樱线,와카사선,#FF2F1A,2,,,,,,,,,,,,,0,99701,2448.20632 -99702,216,北松江線,キタマツエセン,一畑電車北松江線,Kita-Matsue Line,Kita-Matsue Line,北松江线,기타마쓰에선,#EB5C02,2,,,,,#EB5C02,,,,REVERSED_ROUND,,,,0,99702,1783.89150 -99703,216,大社線,タイシャセン,一畑電車大社線,Taisha Line,Taisha Line,大社线,다이샤선,#EB5C02,2,,,,,,,,,,,,,0,99703,2345.81608 -99704,217,水島本線,ミズシマホンセン,水島臨海鉄道水島本線,Mizushima Main Line,Mizushima Main Line,水岛本线,미즈시마 본선,#3B82C5,2,MR,,,,#3B82C5,,,,REVERSED_ROUND,,,,0,99704,1297.02762 -99705,218,井原線,イバラセン,井原鉄道井原線,Ibara Line,Ibara Line,井原线,이바라선,#00AD66,2,,,,,,,,,,,,,0,99705,3297.12640 +99649,212,六甲ライナー,ロッコウライナー,神戸新交通六甲アイランド線,Rokko Liner,Rokko Liner,六甲人工岛线,롯코 라이너,#9686BD,5,R,,,,#9686BD,,,,REVERSED_SQUARE,,,,0,99649,893.11205 +99650,213,紀州鉄道線,キシュウテツドウセン,紀州鉄道線,Kishu Railway Line,Kishu Railway Line,纪州铁道线,기슈 철도선,#081042,2,,,,,,,,,,,,,0,99650,659.45614 +99651,214,貴志川線,キシガワセン,和歌山電鐵貴志川線,Kishigawa Line,Kishigawa Line,贵志川线,기시가와선,#DA381B,2,,,,,,,,,,,,,0,99651,1064.09728 +99701,215,若桜線,ワカサセン,若桜鉄道若桜線,Wakasa Line,Wakasa Line,若樱线,와카사선,#FF2F1A,2,,,,,,,,,,,,,0,99701,2342.28838 +99702,216,北松江線,キタマツエセン,一畑電車北松江線,Kita-Matsue Line,Kita-Matsue Line,北松江线,기타마쓰에선,#EB5C02,2,,,,,#EB5C02,,,,REVERSED_ROUND,,,,0,99702,1576.127 +99703,216,大社線,タイシャセン,一畑電車大社線,Taisha Line,Taisha Line,大社线,다이샤선,#EB5C02,2,,,,,,,,,,,,,0,99703,2059.70786 +99704,217,水島本線,ミズシマホンセン,水島臨海鉄道水島本線,Mizushima Main Line,Mizushima Main Line,水岛本线,미즈시마 본선,#3B82C5,2,MR,,,,#3B82C5,,,,REVERSED_ROUND,,,,0,99704,1170.384 +99705,218,井原線,イバラセン,井原鉄道井原線,Ibara Line,Ibara Line,井原线,이바라선,#00AD66,2,,,,,,,,,,,,,0,99705,2963.58483 99706,219,東山線,ヒガシヤマセン,岡山電軌東山本線,Higashiyama Line,Higashiyama Line,东山线,히가시야마선,#EF1731,4,H,,,,#EF1731,,,,ROUND,,,,0,99706,401.54121 -99707,219,清輝橋線,セイキバシセン,岡山電軌清輝橋線,Seikibashi Line,Seikibashi Line,清辉桥线,세이키바시선,#07502B,4,S,,,,#07502B,,,,ROUND,,,,0,99707,392.15505 +99707,219,清輝橋線,セイキバシセン,岡山電軌清輝橋線,Seikibashi Line,Seikibashi Line,清辉桥线,세이키바시선,#07502B,4,S,,,,#07502B,,,,ROUND,,,,0,99707,321.09156 99708,220,スカイレールみどり坂線,スカイレールミドリザカセン,広島短距離交通瀬野線,Skyrail Midorizaka Line,Skyrail Midorizaka Line,空中铁道绿坂线,스카이레일 미도리자카선,#F9F9F9,5,,,,,,,,,,,,,2,99708,651.30282 -99709,221,アストラムライン,アストラムライン,広島高速交通広島新交通1号線,Astram Line,Astram Line,新交通系统,아스트람 라인,#FFA500,5,,,,,,,,,,,,,0,99709,936.15191 -99710,222,広電1号線(宇品線),ヒロデンイチゴウセン,広電1号線(宇品線),Hiroden Ujina Line,Hiroden Ujina Line,广电1号线(宇品线),히로덴 1호선(우지나선),#FF5900,4,M,U,,,#00A85F,#0092D7,,,REVERSED_ROUND_HORIZONTAL,REVERSED_ROUND_HORIZONTAL,,,0,99710,372.29208 -99711,222,広電2号線(宮島線),ヒロデンニゴウセン,広電2号線(宮島線),Hiroden Miyajima Line,Hiroden Miyajima Line,广电2号线(宫岛线),히로덴 2호선(미야지마선),#EF1731,4,M,,,,#00A85F,,,,REVERSED_ROUND_HORIZONTAL,,,,0,99711,656.45839 -99712,222,広電3号線,ヒロデンサンゴウセン,広電3号線,Hiroden Streetcar Route 3,Hiroden Streetcar Route 3,广电3号线,히로덴 3호선,#4243BE,4,U,M,,,#0092D7,#00A85F,,,REVERSED_ROUND_HORIZONTAL,REVERSED_ROUND_HORIZONTAL,REVERSED_ROUND_HORIZONTAL,,0,99712,395.63880 -99713,222,広電5号線(皆実線),ヒロデンゴゴウセン,広電5号線(皆実線),Hiroden Minami Line,Hiroden Minami Line,广电5号线(皆实线),히로덴 5호선(미나미선),#00CC66,4,M,H,U,,#00A85F,#7DBF4C,#0092D7,,REVERSED_ROUND_HORIZONTAL,REVERSED_ROUND_HORIZONTAL,REVERSED_ROUND_HORIZONTAL,,0,99713,444.21272 -99714,222,広電6号線(江波線),ヒロデンロクゴウセン,広電6号線(江波線),Hiroden Eba Line,Hiroden Eba Line,广电6号线(江波线),히로덴 6호선(에바선),#FFCC00,4,E,M,,,#FEDB4F,#008033,,,REVERSED_ROUND_HORIZONTAL,REVERSED_ROUND_HORIZONTAL,,,0,99714,393.12732 +99709,221,アストラムライン,アストラムライン,広島高速交通広島新交通1号線,Astram Line,Astram Line,新交通系统,아스트람 라인,#FFA500,5,,,,,,,,,,,,,0,99709,856.37782 +99710,222,広電1号線(宇品線),ヒロデンイチゴウセン,広電1号線(宇品線),Hiroden Ujina Line,Hiroden Ujina Line,广电1号线(宇品线),히로덴 1호선(우지나선),#FF5900,4,M,U,,,#00A85F,#0092D7,,,REVERSED_ROUND_HORIZONTAL,REVERSED_ROUND_HORIZONTAL,,,0,99710,385.93525 +99711,222,広電2号線(宮島線),ヒロデンニゴウセン,広電2号線(宮島線),Hiroden Miyajima Line,Hiroden Miyajima Line,广电2号线(宫岛线),히로덴 2호선(미야지마선),#EF1731,4,M,,,,#00A85F,,,,REVERSED_ROUND_HORIZONTAL,,,,0,99711,672.49032 +99712,222,広電3号線,ヒロデンサンゴウセン,広電3号線,Hiroden Streetcar Route 3,Hiroden Streetcar Route 3,广电3号线,히로덴 3호선,#4243BE,4,U,M,,,#0092D7,#00A85F,,,REVERSED_ROUND_HORIZONTAL,REVERSED_ROUND_HORIZONTAL,REVERSED_ROUND_HORIZONTAL,,0,99712,383.85101 +99713,222,広電5号線(皆実線),ヒロデンゴゴウセン,広電5号線(皆実線),Hiroden Minami Line,Hiroden Minami Line,广电5号线(皆实线),히로덴 5호선(미나미선),#00CC66,4,M,H,U,,#00A85F,#7DBF4C,#0092D7,,REVERSED_ROUND_HORIZONTAL,REVERSED_ROUND_HORIZONTAL,REVERSED_ROUND_HORIZONTAL,,0,99713,437.72286 +99714,222,広電6号線(江波線),ヒロデンロクゴウセン,広電6号線(江波線),Hiroden Eba Line,Hiroden Eba Line,广电6号线(江波线),히로덴 6호선(에바선),#FFCC00,4,E,M,,,#FEDB4F,#008033,,,REVERSED_ROUND_HORIZONTAL,REVERSED_ROUND_HORIZONTAL,,,0,99714,413.23367 99715,222,広電7号線,ヒロデンナナゴウセン,広電7号線,Hiroden Streetcar Route 7,Hiroden Streetcar Route 7,广电7号线,히로덴 7호선,#005A52,4,Y,M,U,,#ED8095,#00A85F,#0092D7,,REVERSED_ROUND_HORIZONTAL,REVERSED_ROUND_HORIZONTAL,REVERSED_ROUND_HORIZONTAL,,0,99715,405.20802 99716,222,広電8号線(横川線),ヒロデンハチゴウセン,広電8号線(横川線),Hiroden Yokogawa Line,Hiroden Yokogawa Line,广电8号线(横川线),히로덴 8호선(요코가와선),#DF60AE,4,Y,M,E,,#ED8095,#00A85F,#FEDB4F,,REVERSED_ROUND_HORIZONTAL,REVERSED_ROUND_HORIZONTAL,REVERSED_ROUND_HORIZONTAL,,0,99716,494.20631 99717,222,広電9号線(白島線),ヒロデンキュウゴウセン,広電9号線(白島線),Hiroden Hakushima Line,Hiroden Hakushima Line,广电9号线(白岛线),히로덴 9호선(하쿠시마선),#797878,4,W,,,,#797878,,,,REVERSED_ROUND_HORIZONTAL,,,,0,99717,380.00763 -99718,223,錦川清流線,ニシキガワセイリュウセン,錦川鉄道錦川清流線,Nishikigawa Seiryu Line,Nishikigawa Seiryu Line,锦川清流线,니시키가와 세이류선,#E60010,2,,,,,,,,,,,,,0,99718,2746.72344 -99801,224,阿波室戸シーサイドライン,アワムロトシーサイドライン,阿佐海岸鉄道阿佐東線,Awa-Muroto Seaside Line,Awa-Muroto Seaside Line,阿波室户海滨线,아와무로토 시사이드 라인,#A5AEB4,2,AK,,,,#A5AEB4,,,,ROUND,,,,0,99801,3645.18043 -99802,225,琴電琴平線,コトデンコトヒラセン,琴電琴平線,Kotoden Kotohira Line,Kotoden Kotohira Line,琴电琴平线,고토덴 고토히라선,#FFD400,2,K,,,,#FFD400,,,,ROUND,,,,0,99802,1926.09173 -99803,225,琴電長尾線,コトデンナガオセン,琴電長尾線,Kotoden Nagao Line,Kotoden Nagao Line,琴电长尾线,고토덴 나가오선,#009966,2,N,,,,#009966,,,,ROUND,,,,0,99803,1060.55828 -99804,225,琴電志度線,コトデンシドセン,琴電志度線,Kotoden Shido Line,Kotoden Shido Line,琴电志度线,고토덴 시도선,#FF3366,2,S,,,,#FF3366,,,,ROUND,,,,0,99804,928.41684 -99805,226,伊予鉄道郡中線,イヨテツドウグンチュウセン,伊予鉄道郡中線,Iyotetsu Gunchu Line,Iyotetsu Gunchu Line,伊予铁道郡中线,이요 철도 군추선,#F15A22,2,IY,,,,#F15A22,,,,REVERSED_ROUND,,,,0,99805,1166.38416 -99806,226,伊予鉄道高浜線,イヨテツドウタカハマセン,伊予鉄道高浜線,Iyotetsu Takahama Line,Iyotetsu Takahama Line,伊予铁道高浜线,이요 철도 다카하마선,#9ACD32,2,IY,,,,#9ACD32,,,,REVERSED_ROUND,,,,0,99806,1093.48322 -99807,226,伊予鉄道横河原線,イヨテツドウヨコガワラセン,伊予鉄道横河原線,Iyotetsu Yokogawara Line,Iyotetsu Yokogawara Line,伊予铁道横河原线,이요 철도 요코가와라선,#00BBEE,2,IY,,,,#00BBEE,,,,REVERSED_ROUND,,,,0,99807,1075.51531 +99718,223,錦川清流線,ニシキガワセイリュウセン,錦川鉄道錦川清流線,Nishikigawa Seiryu Line,Nishikigawa Seiryu Line,锦川清流线,니시키가와 세이류선,#E60010,2,,,,,,,,,,,,,0,99718,2660.86581 +99801,224,阿波室戸シーサイドライン,アワムロトシーサイドライン,阿佐海岸鉄道阿佐東線,Awa-Muroto Seaside Line,Awa-Muroto Seaside Line,阿波室户海滨线,아와무로토 시사이드 라인,#A5AEB4,2,AK,,,,#A5AEB4,,,,ROUND,,,,0,99801,3291.48155 +99802,225,琴電琴平線,コトデンコトヒラセン,琴電琴平線,Kotoden Kotohira Line,Kotoden Kotohira Line,琴电琴平线,고토덴 고토히라선,#FFD400,2,K,,,,#FFD400,,,,ROUND,,,,0,99802,1462.64871 +99803,225,琴電長尾線,コトデンナガオセン,琴電長尾線,Kotoden Nagao Line,Kotoden Nagao Line,琴电长尾线,고토덴 나가오선,#009966,2,N,,,,#009966,,,,ROUND,,,,0,99803,933.5494 +99804,225,琴電志度線,コトデンシドセン,琴電志度線,Kotoden Shido Line,Kotoden Shido Line,琴电志度线,고토덴 시도선,#FF3366,2,S,,,,#FF3366,,,,ROUND,,,,0,99804,812.09522 +99805,226,伊予鉄道郡中線,イヨテツドウグンチュウセン,伊予鉄道郡中線,Iyotetsu Gunchu Line,Iyotetsu Gunchu Line,伊予铁道郡中线,이요 철도 군추선,#F15A22,2,IY,,,,#F15A22,,,,REVERSED_ROUND,,,,0,99805,1021.3182 +99806,226,伊予鉄道高浜線,イヨテツドウタカハマセン,伊予鉄道高浜線,Iyotetsu Takahama Line,Iyotetsu Takahama Line,伊予铁道高浜线,이요 철도 다카하마선,#9ACD32,2,IY,,,,#9ACD32,,,,REVERSED_ROUND,,,,0,99806,985.13285 +99807,226,伊予鉄道横河原線,イヨテツドウヨコガワラセン,伊予鉄道横河原線,Iyotetsu Yokogawara Line,Iyotetsu Yokogawara Line,伊予铁道横河原线,이요 철도 요코가와라선,#00BBEE,2,IY,,,,#00BBEE,,,,REVERSED_ROUND,,,,0,99807,940.73597 99808,226,伊予鉄道環状線(1系統),イヨテツドウカンジョウセン,伊予鉄道1系統,Iyotetsu Route 1 Loop Line,Iyotetsu Route 1 Loop Line,伊予铁道环状线(1系统),이요 철도 순환선(1계통),#CD6803,4,IY,,,,#CD6803,,,,REVERSED_ROUND,,,,0,99808,391.19973 99809,226,伊予鉄道環状線(2系統),イヨテツドウカンジョウセン,伊予鉄道2系統,Iyotetsu Route 2 Loop Line,Iyotetsu Route 2 Loop Line,伊予铁道环状线(2系统),이요 철도 순환선(2계통),#CD6803,4,IY,,,,#CD6803,,,,REVERSED_ROUND,,,,0,99809,391.65867 99810,226,伊予鉄道市駅線(3系統),イヨテツドウシエキセン,伊予鉄道3系統,Iyotetsu Route 3,Iyotetsu Route 3,伊予铁道市站线(3系统),이요 철도 시에키선(3계통),#CD6803,4,IY,,,,#CD6803,,,,REVERSED_ROUND,,,,0,99810,413.44857 99811,226,伊予鉄道松山駅前線(5系統),イヨテツドウマツヤマエキマエセン,伊予鉄道5系統,Iyotetsu Route 5,Iyotetsu Route 5,伊予铁道松山站前线(5系统),이요 철도 마쓰야마에키마에선(5계통),#CD6803,4,IY,,,,#CD6803,,,,REVERSED_ROUND,,,,0,99811,402.24475 -99812,226,伊予鉄道本町線(6系統),イヨテツドウホンマチセン,伊予鉄道6系統,Iyotetsu Route 6,Iyotetsu Route 6,伊予铁道本町线(6系统),이요 철도 혼마치선(6계통),#CD6803,4,IY,,,,#CD6803,,,,REVERSED_ROUND,,,,0,99812,438.92351 -99814,227,中村線,ナカムラセン,土佐くろしお鉄道中村線,Nakamura Line,Nakamura Line,中村线,나카무라선,#32455C,2,TK,,,,#32455C,,,,ROUND,,,,0,99814,3045.43947 -99815,227,宿毛線,スクモセン,土佐くろしお鉄道宿毛線,Sukumo Line,Sukumo Line,宿毛线,스쿠모선,#32455C,2,TK,,,,#32455C,,,,ROUND,,,,0,99815,3691.25087 -99816,227,ごめん・なはり線,ゴメン・ナハリセン,土佐くろしお鉄道ごめん・なはり線,Gomen-Nahari Line,Gomen-Nahari Line,后免・奈半利线,고멘·나하리선,#32455C,2,GN,,,,#A5AEB4,,,,ROUND,,,,0,99816,2347.05772 +99812,226,伊予鉄道本町線(6系統),イヨテツドウホンマチセン,伊予鉄道6系統,Iyotetsu Route 6,Iyotetsu Route 6,伊予铁道本町线(6系统),이요 철도 혼마치선(6계통),#CD6803,4,IY,,,,#CD6803,,,,REVERSED_ROUND,,,,0,99812,389.88748 +99814,227,中村線,ナカムラセン,土佐くろしお鉄道中村線,Nakamura Line,Nakamura Line,中村线,나카무라선,#32455C,2,TK,,,,#32455C,,,,ROUND,,,,0,99814,3023.55505 +99815,227,宿毛線,スクモセン,土佐くろしお鉄道宿毛線,Sukumo Line,Sukumo Line,宿毛线,스쿠모선,#32455C,2,TK,,,,#32455C,,,,ROUND,,,,0,99815,3398.58428 +99816,227,ごめん・なはり線,ゴメン・ナハリセン,土佐くろしお鉄道ごめん・なはり線,Gomen-Nahari Line,Gomen-Nahari Line,后免・奈半利线,고멘·나하리선,#32455C,2,GN,,,,#A5AEB4,,,,ROUND,,,,0,99816,2077.70167 99817,228,ごめん線,ゴメンセン,土佐電鉄ごめん線,Gomen Line,Gomen Line,后免线,고멘선,#2A9A38,4,,,,,,,,,,,,,0,99817,418.60311 -99818,228,伊野線,イノセン,土佐電鉄伊野線,Ino Line,Ino Line,伊野线,이노선,#2A9A38,4,,,,,,,,,,,,,0,99818,438.98478 -99819,228,桟橋線,サンバシセン,土佐電鉄桟橋線,Sambashi Line,Sambashi Line,栈桥线,산바시선,#2A9A38,4,,,,,,,,,,,,,0,99819,394.49027 -99901,229,甘木鉄道甘木線,アマギテツドウアマギセン,甘木鉄道甘木線,Amagi Railway,Amagi Railway,甘木铁道甘木线,아마기 철도 아마기선,#D43A2A,2,,,,,,,,,,,,,0,99901,1506.45797 -99902,230,伊田線,イダセン,平成筑豊鉄道伊田線,Ida Line,Ida Line,伊田线,이다선,#FF9900,2,HC,,,,#FF9900,,,,HALF_SQUARE,,,,0,99902,1270.12479 -99903,230,糸田線,イトダセン,平成筑豊鉄道糸田線,Itoda Line,Itoda Line,系田线,이토다선,#99CC00,2,HC,,,,#FF9900,,,,HALF_SQUARE,,,,0,99903,1487.70387 -99904,230,田川線,タガワセン,平成筑豊鉄道田川線,Tagawa Line,Tagawa Line,田川线,다가와선,#4DBBFF,2,,,,,,,,,,,,,0,99904,1820.17098 -99928,230,門司港レトロ観光線,モジコウレトロカンコウセン,平成筑豊鉄道門司港レトロ観光線,Mojiko Retro Scenic Line,Mojiko Retro Scenic Line,门司港怀旧观光线,모지코 레트로 관광선,#476FC1,2,,,,,,,,,,,,,0,99904,753.73667 -99905,231,福岡市営地下鉄空港線,フクオカシエイチカテツクウコウセン,福岡市営地下鉄空港線,Fukuoka City Subway Airport Line,Fukuoka City Subway Airport Line,福冈市营地铁机场线,후쿠오카 시영 지하철 공항선,#FFA500,3,K,,,,#FFA500,,,,ROUND,,,,0,99905,1118.10873 -99906,231,福岡市営地下鉄箱崎線,フクオカシエイチカテツハコザキセン,福岡市営地下鉄箱崎線,Fukuoka City Subway Hakozaki Line,Fukuoka City Subway Hakozaki Line,福冈市营地铁箱崎线,후쿠오카 시영 지하철 하코자키선,#00BFFF,3,H,,,,#00BFFF,,,,ROUND,,,,0,99906,866.85830 -99907,231,福岡市営地下鉄七隈線,フクオカシエイチカテツナナクマセン,福岡市営地下鉄七隈線,Fukuoka City Subway Nanakuma Line,Fukuoka City Subway Nanakuma Line,福冈市营地铁七隈线,후쿠오카 시영 지하철 나나쿠마선,#228B22,3,N,,,,#228B22,,,,ROUND,,,,0,99907,848.44187 -99908,232,北九州モノレール,キタキュウシュウモノレール,北九州高速鉄道,Kitakyushu Monorail,Kitakyushu Monorail,北九州单轨电车,기타큐슈 모노레일,#40BFE8,5,,,,,,,,,,,,,0,99908,795.15765 -99909,233,筑豊電気鉄道線,チクホウデンキテツドウセン,筑豊電気鉄道線,Chikuho Electric Railroad Line,Chikuho Electric Railroad Line,筑丰电气铁道线,지쿠호 전기 철도선,#E30075,2,CK,,,,#E30075,,,,HALF_SQUARE,,,,0,99909,896.98184 -99910,234,西九州線,ニシキュウシュウセン,松浦鉄道西九州線,Nishi-Kyushu Line,Nishi-Kyushu Line,西九州线,니시큐슈선,#0080FF,2,,,,,,,,,,,,,0,99910,1432.43600 -99911,234,西九州線,ニシキュウシュウセン,松浦鉄道西九州線,Nishi-Kyushu Line,Nishi-Kyushu Line,西九州线,니시큐슈선,#0080FF,2,,,,,,,,,,,,,0,99911,1794.12905 -99912,235,島原鉄道線,シマバラテツドウセン,島原鉄道線,Shimabara Railway Line,Shimabara Railway Line,岛原铁道线,시마바라 철도선,#FEE633,2,,,,,,,,,,,,,0,99912,1975.91890 +99818,228,伊野線,イノセン,土佐電鉄伊野線,Ino Line,Ino Line,伊野线,이노선,#2A9A38,4,,,,,,,,,,,,,0,99818,417.13513 +99819,228,桟橋線,サンバシセン,土佐電鉄桟橋線,Sambashi Line,Sambashi Line,栈桥线,산바시선,#2A9A38,4,,,,,,,,,,,,,0,99819,342.85359 +99901,229,甘木鉄道甘木線,アマギテツドウアマギセン,甘木鉄道甘木線,Amagi Railway,Amagi Railway,甘木铁道甘木线,아마기 철도 아마기선,#D43A2A,2,,,,,,,,,,,,,0,99901,1340.75892 +99902,230,伊田線,イダセン,平成筑豊鉄道伊田線,Ida Line,Ida Line,伊田线,이다선,#FF9900,2,HC,,,,#FF9900,,,,HALF_SQUARE,,,,0,99902,1118.3009 +99903,230,糸田線,イトダセン,平成筑豊鉄道糸田線,Itoda Line,Itoda Line,系田线,이토다선,#99CC00,2,HC,,,,#FF9900,,,,HALF_SQUARE,,,,0,99903,1349.80057 +99904,230,田川線,タガワセン,平成筑豊鉄道田川線,Tagawa Line,Tagawa Line,田川线,다가와선,#4DBBFF,2,,,,,,,,,,,,,0,99904,1608.54241 +99928,230,門司港レトロ観光線,モジコウレトロカンコウセン,平成筑豊鉄道門司港レトロ観光線,Mojiko Retro Scenic Line,Mojiko Retro Scenic Line,门司港怀旧观光线,모지코 레트로 관광선,#476FC1,2,,,,,,,,,,,,,0,99904,655.42319 +99905,231,福岡市営地下鉄空港線,フクオカシエイチカテツクウコウセン,福岡市営地下鉄空港線,Fukuoka City Subway Airport Line,Fukuoka City Subway Airport Line,福冈市营地铁机场线,후쿠오카 시영 지하철 공항선,#FFA500,3,K,,,,#FFA500,,,,ROUND,,,,0,99905,1056.94017 +99906,231,福岡市営地下鉄箱崎線,フクオカシエイチカテツハコザキセン,福岡市営地下鉄箱崎線,Fukuoka City Subway Hakozaki Line,Fukuoka City Subway Hakozaki Line,福冈市营地铁箱崎线,후쿠오카 시영 지하철 하코자키선,#00BFFF,3,H,,,,#00BFFF,,,,ROUND,,,,0,99906,811.72308 +99907,231,福岡市営地下鉄七隈線,フクオカシエイチカテツナナクマセン,福岡市営地下鉄七隈線,Fukuoka City Subway Nanakuma Line,Fukuoka City Subway Nanakuma Line,福冈市营地铁七隈线,후쿠오카 시영 지하철 나나쿠마선,#228B22,3,N,,,,#228B22,,,,ROUND,,,,0,99907,789.83764 +99908,232,北九州モノレール,キタキュウシュウモノレール,北九州高速鉄道,Kitakyushu Monorail,Kitakyushu Monorail,北九州单轨电车,기타큐슈 모노레일,#40BFE8,5,,,,,,,,,,,,,0,99908,729.89416 +99909,233,筑豊電気鉄道線,チクホウデンキテツドウセン,筑豊電気鉄道線,Chikuho Electric Railroad Line,Chikuho Electric Railroad Line,筑丰电气铁道线,지쿠호 전기 철도선,#E30075,2,CK,,,,#E30075,,,,HALF_SQUARE,,,,0,99909,791.53533 +99910,234,西九州線,ニシキュウシュウセン,松浦鉄道西九州線,Nishi-Kyushu Line,Nishi-Kyushu Line,西九州线,니시큐슈선,#0080FF,2,,,,,,,,,,,,,0,99910,1250.88679 +99911,234,西九州線,ニシキュウシュウセン,松浦鉄道西九州線,Nishi-Kyushu Line,Nishi-Kyushu Line,西九州线,니시큐슈선,#0080FF,2,,,,,,,,,,,,,0,99911,1695.1834 +99912,235,島原鉄道線,シマバラテツドウセン,島原鉄道線,Shimabara Railway Line,Shimabara Railway Line,岛原铁道线,시마바라 철도선,#FEE633,2,,,,,,,,,,,,,0,99912,1838.85554 99913,236,長崎電軌1系統,ナガサキデンキイチゴウケイトウ,長崎電軌1系統,Nagasaki Electric Tramway Route 1,Nagasaki Electric Tramway Route 1,长崎电轨1系统,나가사키 전기궤도 1계통,#4243BE,4,,,,,,,,,,,,,0,99913,350.09157 99914,236,長崎電軌3系統,ナガサキデンキサンゴウケイトウ,長崎電軌3系統,Nagasaki Electric Tramway Route 3,Nagasaki Electric Tramway Route 3,长崎电轨3系统,나가사키 전기궤도 3계통,#EF1731,4,,,,,,,,,,,,,0,99914,396.11844 -99915,236,長崎電軌4系統,ナガサキデンキヨンゴウケイトウ,長崎電軌4系統,Nagasaki Electric Tramway Route 4,Nagasaki Electric Tramway Route 4,长崎电轨4系统,나가사키 전기궤도 4계통,#FFCC00,4,,,,,,,,,,,,,0,99915,442.62606 -99916,236,長崎電軌5系統,ナガサキデンキゴゴウケイトウ,長崎電軌5系統,Nagasaki Electric Tramway Route 5,Nagasaki Electric Tramway Route 5,长崎电轨5系统,나가사키 전기궤도 5계통,#005A52,4,,,,,,,,,,,,,0,99916,418.65010 -99917,237,熊本電鉄本線,クマモトデンテツホンセン,熊本電鉄本線,Kumamoto Electric Railway Main Line,Kumamoto Electric Railway Main Line,熊本电铁本线,구마모토 전철 본선,#7B0D27,2,KD,,,,#BE302C,,,,SQUARE,,,,0,99917,896.37735 -99918,237,熊本電鉄上熊本線,クマモトデンテツカミクマモトセン,熊本電鉄上熊本線,Kumamoto Electric Railway Kami-Kumamoto Line,Kumamoto Electric Railway Kami-Kumamoto Line,熊本电铁上熊本线,구마모토 전철 가미쿠마모토선,#7B0D27,2,KD,,,,#BE302C,,,,SQUARE,,,,0,99918,749.84752 -99919,238,高森線,タカモリセン,南阿蘇鉄道高森線,Takamori Line,Takamori Line,高森线,다카모리선,#138068,2,,,,,,,,,,,,,0,99919,2129.62433 -99920,239,湯前線,ユノマエセン,くま川鉄道湯前線,Yunomae Line,Yunomae Line,汤前线,유노마에선,#153C36,2,,,,,,,,,,,,,0,99920,2136.29758 -99921,240,肥薩おれんじ鉄道線,ヒサツオレンジテツドウセン,肥薩おれんじ鉄道線,Hisatsu Orange Railway,Hisatsu Orange Railway,肥萨橙铁道线,히사쓰 오렌지 철도선,#FFA500,2,OR,,,,#FFA500,,,,ROUND,,,,0,99921,4472.82444 +99915,236,長崎電軌4系統,ナガサキデンキヨンゴウケイトウ,長崎電軌4系統,Nagasaki Electric Tramway Route 4,Nagasaki Electric Tramway Route 4,长崎电轨4系统,나가사키 전기궤도 4계통,#FFCC00,4,,,,,,,,,,,,,0,99915,378.80477 +99916,236,長崎電軌5系統,ナガサキデンキゴゴウケイトウ,長崎電軌5系統,Nagasaki Electric Tramway Route 5,Nagasaki Electric Tramway Route 5,长崎电轨5系统,나가사키 전기궤도 5계통,#005A52,4,,,,,,,,,,,,,0,99916,364.66745 +99917,237,熊本電鉄本線,クマモトデンテツホンセン,熊本電鉄本線,Kumamoto Electric Railway Main Line,Kumamoto Electric Railway Main Line,熊本电铁本线,구마모토 전철 본선,#7B0D27,2,KD,,,,#BE302C,,,,SQUARE,,,,0,99917,785.60254 +99918,237,熊本電鉄上熊本線,クマモトデンテツカミクマモトセン,熊本電鉄上熊本線,Kumamoto Electric Railway Kami-Kumamoto Line,Kumamoto Electric Railway Kami-Kumamoto Line,熊本电铁上熊本线,구마모토 전철 가미쿠마모토선,#7B0D27,2,KD,,,,#BE302C,,,,SQUARE,,,,0,99918,655.3384 +99919,238,高森線,タカモリセン,南阿蘇鉄道高森線,Takamori Line,Takamori Line,高森线,다카모리선,#138068,2,,,,,,,,,,,,,0,99919,1923.0291 +99920,239,湯前線,ユノマエセン,くま川鉄道湯前線,Yunomae Line,Yunomae Line,汤前线,유노마에선,#153C36,2,,,,,,,,,,,,,0,99920,1872.97933 +99921,240,肥薩おれんじ鉄道線,ヒサツオレンジテツドウセン,肥薩おれんじ鉄道線,Hisatsu Orange Railway,Hisatsu Orange Railway,肥萨橙铁道线,히사쓰 오렌지 철도선,#FFA500,2,OR,,,,#FFA500,,,,ROUND,,,,0,99921,4285.529 99922,241,熊本市電A系統,クマモトシデンエーライン,熊本市電A系統,Kumamoto City Tram Route A,Kumamoto City Tram Route A,熊本市电A系统,구마모토 시덴 A계통,#FF0000,4,A,,,,#FF0000,,,,REVERSED_SQUARE,,,,0,99922,444.53072 -99923,241,熊本市電B系統,クマモトシデンビーライン,熊本市電B系統,Kumamoto City Tram Route B,Kumamoto City Tram Route B,熊本市电B系统,구마모토 시덴 B계통,#0000FF,4,B,,,,#0000FF,,,,REVERSED_SQUARE,,,,0,99923,426.59086 -99925,242,鹿児島市電1系統,カゴシマシデンイチケイトウ,鹿児島市電1系統,Kagoshima City Tram Route 1,Kagoshima City Tram Route 1,鹿儿岛市电1系统,가고시마 시덴 1계통,#4243BE,4,I,,,,#4243BE,,,,REVERSED_ROUND,,,,0,99925,498.63208 +99923,241,熊本市電B系統,クマモトシデンビーライン,熊本市電B系統,Kumamoto City Tram Route B,Kumamoto City Tram Route B,熊本市电B系统,구마모토 시덴 B계통,#0000FF,4,B,,,,#0000FF,,,,REVERSED_SQUARE,,,,0,99923,375.32687 +99925,242,鹿児島市電1系統,カゴシマシデンイチケイトウ,鹿児島市電1系統,Kagoshima City Tram Route 1,Kagoshima City Tram Route 1,鹿儿岛市电1系统,가고시마 시덴 1계통,#4243BE,4,I,,,,#4243BE,,,,REVERSED_ROUND,,,,0,99925,419.36632 99926,242,鹿児島市電2系統,カゴシマシデンニケイトウ,鹿児島市電2系統,Kagoshima City Tram Route 2,Kagoshima City Tram Route 2,鹿儿岛市电2系统,가고시마 시덴 2계통,#EF1731,4,N,,,,#EF1731,,,,REVERSED_ROUND,,,,0,99926,367.48816 -99927,243,ゆいレール,ユイレール,沖縄都市モノレール線,Yui Rail,Yui Rail,冲绳都市单轨电车,유이레일,#CC0000,5,,,,,#CC0000,,,,MONOCHROME_ROUND,,,,0,99927,941.27910 +99927,243,ゆいレール,ユイレール,沖縄都市モノレール線,Yui Rail,Yui Rail,冲绳都市单轨电车,유이레일,#CC0000,5,,,,,#CC0000,,,,MONOCHROME_ROUND,,,,0,99927,875.63476 diff --git a/data/README.md b/data/README.md index 2f4bde07..3fb910d5 100644 --- a/data/README.md +++ b/data/README.md @@ -71,7 +71,7 @@ | `line_symbol4_shape` | 文字列 | - | 路線記号 4 の形状 | `HALF_SQUARE_WITHOUT_ROUND` | | `e_status` | 数値 | ✓ | 状態フラグ(0:運用中, 1:運用前, 2:廃止) | `0` | | `e_sort` | 数値 | ✓ | ソート順 | `1002` | -| `average_distance` | 数値 | - | 平均駅間距離(メートル) | `30294.05713` | +| `average_distance` | 数値 | - | 平均駅間距離(メートル、線路に沿った実距離ベース) | `31363.12011` | ### 入力時の注意点 @@ -79,6 +79,7 @@ - `company_cd`は`1!companies.csv`に存在する値を使用 - `line_type`: 新幹線の場合は`1`, 一般の場合は`2`, 地下鉄の場合は`3`, 市電・路面電車の場合は`4`, モノレール・新交通の場合は`5`, その他の場合は`0`を使用 - 記号が複数ある場合は`line_symbol1`, `line_symbol2`...の順で入力 +- `average_distance`は OpenStreetMap の線路ジオメトリに基づく**実際の平均駅間距離**(線路に沿った距離)。`scripts/compute_average_distance.py` で再計算できる(旧データは駅座標の直線距離に固定係数を掛けた推定値だった)。OSM のルート関係が取得できない一部路線は従来式での推定値にフォールバックする ## 🚉 3!stations.csv - 駅情報 diff --git a/docker/grafana/dashboards/stationapi-grpc.json b/docker/grafana/dashboards/stationapi-grpc.json deleted file mode 100644 index fd14c260..00000000 --- a/docker/grafana/dashboards/stationapi-grpc.json +++ /dev/null @@ -1,316 +0,0 @@ -{ - "annotations": { - "list": [] - }, - "editable": true, - "fiscalYearStartMonth": 0, - "graphTooltip": 1, - "links": [], - "panels": [ - { - "title": "Request Rate (per second)", - "type": "timeseries", - "gridPos": { "h": 8, "w": 12, "x": 0, "y": 0 }, - "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, - "fieldConfig": { - "defaults": { - "unit": "reqps", - "custom": { - "drawStyle": "line", - "lineInterpolation": "smooth", - "fillOpacity": 20, - "pointSize": 5, - "showPoints": "auto" - } - }, - "overrides": [] - }, - "targets": [ - { - "expr": "sum(rate(grpc_requests_total[1m])) by (method)", - "legendFormat": "{{ method }}", - "refId": "A" - } - ], - "options": { - "legend": { - "displayMode": "table", - "placement": "bottom", - "calcs": ["mean", "max"] - }, - "tooltip": { "mode": "multi" } - } - }, - { - "title": "Status Breakdown (per second)", - "type": "timeseries", - "gridPos": { "h": 8, "w": 12, "x": 12, "y": 0 }, - "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, - "fieldConfig": { - "defaults": { - "unit": "reqps", - "custom": { - "drawStyle": "line", - "lineInterpolation": "smooth", - "fillOpacity": 20, - "pointSize": 5, - "showPoints": "auto" - } - }, - "overrides": [] - }, - "targets": [ - { - "expr": "sum(rate(grpc_requests_total[1m])) by (status)", - "legendFormat": "{{ status }}", - "refId": "A" - } - ], - "options": { - "legend": { - "displayMode": "table", - "placement": "bottom", - "calcs": ["mean", "max"] - }, - "tooltip": { "mode": "multi" } - } - }, - { - "title": "Request Latency (p50 / p90 / p99)", - "type": "timeseries", - "gridPos": { "h": 8, "w": 24, "x": 0, "y": 8 }, - "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, - "fieldConfig": { - "defaults": { - "unit": "ms", - "custom": { - "drawStyle": "line", - "lineInterpolation": "smooth", - "fillOpacity": 10, - "pointSize": 5, - "showPoints": "auto" - } - }, - "overrides": [] - }, - "targets": [ - { - "expr": "histogram_quantile(0.50, sum(rate(grpc_request_duration_seconds_bucket[5m])) by (le, method)) * 1000", - "legendFormat": "p50 {{ method }}", - "refId": "A" - }, - { - "expr": "histogram_quantile(0.90, sum(rate(grpc_request_duration_seconds_bucket[5m])) by (le, method)) * 1000", - "legendFormat": "p90 {{ method }}", - "refId": "B" - }, - { - "expr": "histogram_quantile(0.99, sum(rate(grpc_request_duration_seconds_bucket[5m])) by (le, method)) * 1000", - "legendFormat": "p99 {{ method }}", - "refId": "C" - } - ], - "options": { - "legend": { - "displayMode": "table", - "placement": "bottom", - "calcs": ["mean", "max"] - }, - "tooltip": { "mode": "multi" } - } - }, - { - "title": "Latency Heatmap", - "type": "heatmap", - "gridPos": { "h": 8, "w": 24, "x": 0, "y": 16 }, - "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, - "targets": [ - { - "expr": "sum(increase(grpc_request_duration_seconds_bucket[1m])) by (le)", - "legendFormat": "{{ le }}", - "refId": "A", - "format": "heatmap" - } - ], - "options": { - "calculate": false, - "yAxis": { "unit": "s" }, - "color": { "scheme": "Oranges" }, - "tooltip": { "show": true } - } - }, - { - "title": "Total Requests (Started)", - "type": "stat", - "gridPos": { "h": 4, "w": 6, "x": 0, "y": 24 }, - "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, - "fieldConfig": { - "defaults": { - "thresholds": { - "steps": [ - { "color": "green", "value": null } - ] - } - }, - "overrides": [] - }, - "targets": [ - { - "expr": "sum(grpc_requests_started_total)", - "legendFormat": "Total Started", - "refId": "A" - } - ], - "options": { - "reduceOptions": { "calcs": ["lastNotNull"] }, - "colorMode": "value" - } - }, - { - "title": "Total Requests (Completed)", - "type": "stat", - "gridPos": { "h": 4, "w": 6, "x": 6, "y": 24 }, - "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, - "fieldConfig": { - "defaults": { - "thresholds": { - "steps": [ - { "color": "green", "value": null } - ] - } - }, - "overrides": [] - }, - "targets": [ - { - "expr": "sum(grpc_requests_total)", - "legendFormat": "Total Completed", - "refId": "A" - } - ], - "options": { - "reduceOptions": { "calcs": ["lastNotNull"] }, - "colorMode": "value" - } - }, - { - "title": "Current Error Ratio", - "type": "gauge", - "gridPos": { "h": 4, "w": 6, "x": 12, "y": 24 }, - "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, - "fieldConfig": { - "defaults": { - "unit": "percentunit", - "min": 0, - "max": 1, - "thresholds": { - "steps": [ - { "color": "green", "value": null }, - { "color": "yellow", "value": 0.01 }, - { "color": "red", "value": 0.05 } - ] - } - }, - "overrides": [] - }, - "targets": [ - { - "expr": "(sum(rate(grpc_requests_total{status!=\"ok\"}[5m])) / clamp_min(sum(rate(grpc_requests_total[5m])), 1e-9)) or vector(0)", - "legendFormat": "Error Ratio", - "refId": "A" - } - ], - "options": { - "reduceOptions": { "calcs": ["lastNotNull"] } - } - }, - { - "title": "Average Duration per Method", - "type": "timeseries", - "gridPos": { "h": 4, "w": 6, "x": 18, "y": 24 }, - "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, - "fieldConfig": { - "defaults": { - "unit": "ms", - "custom": { - "drawStyle": "line", - "lineInterpolation": "smooth", - "fillOpacity": 10, - "pointSize": 5, - "showPoints": "auto" - } - }, - "overrides": [] - }, - "targets": [ - { - "expr": "(sum(rate(grpc_request_duration_seconds_sum[5m])) by (method) / sum(rate(grpc_request_duration_seconds_count[5m])) by (method)) * 1000", - "legendFormat": "avg {{ method }}", - "refId": "A" - } - ], - "options": { - "legend": { - "displayMode": "table", - "placement": "bottom", - "calcs": ["mean", "max"] - }, - "tooltip": { "mode": "multi" } - } - }, - { - "title": "Requests by Method and Status", - "type": "timeseries", - "gridPos": { "h": 8, "w": 24, "x": 0, "y": 28 }, - "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, - "fieldConfig": { - "defaults": { - "unit": "reqps", - "custom": { - "drawStyle": "line", - "lineInterpolation": "smooth", - "fillOpacity": 12, - "pointSize": 4, - "showPoints": "auto" - } - }, - "overrides": [] - }, - "targets": [ - { - "expr": "sum(rate(grpc_requests_total[5m])) by (method, status)", - "legendFormat": "{{ method }} / {{ status }}", - "refId": "A" - } - ], - "options": { - "legend": { - "displayMode": "table", - "placement": "bottom", - "calcs": ["mean", "max"] - }, - "tooltip": { "mode": "multi" } - } - } - ], - "refresh": "10s", - "schemaVersion": 39, - "templating": { - "list": [ - { - "current": {}, - "hide": 0, - "includeAll": false, - "name": "DS_PROMETHEUS", - "query": "prometheus", - "type": "datasource" - } - ] - }, - "time": { "from": "now-30m", "to": "now" }, - "timepicker": {}, - "timezone": "", - "title": "StationAPI gRPC Metrics", - "uid": "stationapi-grpc", - "version": 1 -} \ No newline at end of file diff --git a/docker/grafana/provisioning/dashboards/dashboards.yml b/docker/grafana/provisioning/dashboards/dashboards.yml deleted file mode 100644 index 075d7e98..00000000 --- a/docker/grafana/provisioning/dashboards/dashboards.yml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: 1 - -providers: - - name: "StationAPI" - orgId: 1 - folder: "" - type: file - disableDeletion: false - editable: true - options: - path: /var/lib/grafana/dashboards - foldersFromFilesStructure: false diff --git a/docker/grafana/provisioning/datasources/prometheus.yml b/docker/grafana/provisioning/datasources/prometheus.yml deleted file mode 100644 index 1a57b69c..00000000 --- a/docker/grafana/provisioning/datasources/prometheus.yml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: 1 - -datasources: - - name: Prometheus - type: prometheus - access: proxy - url: http://prometheus:9090 - isDefault: true - editable: true diff --git a/docker/prometheus/prometheus.yml b/docker/prometheus/prometheus.yml deleted file mode 100644 index 2016775e..00000000 --- a/docker/prometheus/prometheus.yml +++ /dev/null @@ -1,11 +0,0 @@ -global: - scrape_interval: 15s - evaluation_interval: 15s - -scrape_configs: - - job_name: "stationapi" - metrics_path: /metrics - static_configs: - - targets: ["api:50052"] - labels: - service: "stationapi" diff --git a/scripts/README.md b/scripts/README.md new file mode 100644 index 00000000..c4e2ed5a --- /dev/null +++ b/scripts/README.md @@ -0,0 +1,46 @@ +# scripts/ + +データメンテナンス用のスクリプト置き場です。CI で実行されるスクリプト +(`.github/scripts/`)とは別物で、メンテナが手元で実行してデータを更新するために使います。 + +## compute_average_distance.py + +`data/2!lines.csv` の `average_distance`(路線ごとの平均駅間距離・メートル)を、 +OpenStreetMap の鉄道ルート関係(route relation)から得た**線路に沿った実距離**で再計算します。 + +従来の `average_distance` は「隣接駅の直線距離の平均 × 路線種別ごとの固定係数(1.05〜1.25)」 +という推定値でした。本スクリプトは当該路線の線路ジオメトリだけを取り出し、隣接駅間を +線路に沿って経路探索することで、より実態に近い平均駅間距離を求めます。 + +### 仕組み + +1. `data/3!stations.csv` から対象路線の稼働駅(`e_status=0`)を `e_sort` 順に取得。 +2. Overpass API で駅群のbbox内の鉄道ルート関係を検索し、**全駅が線路から200m以内に収まる** + 関係を路線名一致+カバレッジで1つ選ぶ(無関係な路線への誤マッチを防止)。 +3. 採用した関係の構成 way だけで線路グラフを構築。 +4. 各駅を半径70m以内の全グラフノードに対応付け(複線の上下線を拾うため)、隣接駅ペアごとに + 多始点・多終点ダイクストラで線路沿い距離を算出し、平均する。 +5. 経路が取れない/妥当範囲外の区間は直線距離で代替。確信できる関係が無い路線は + 旧来式(直線×係数)でフォールバックする。 + +### 使い方 + +```bash +# 既知路線で較正・精度確認(CSVは書き換えない) +python3 scripts/compute_average_distance.py --validate + +# 任意の line_cd を個別計算(CSVは書き換えない) +python3 scripts/compute_average_distance.py --lines 11302,1002 + +# 全路線を計算して data/2!lines.csv を書き換える +python3 scripts/compute_average_distance.py --apply +``` + +依存は Python 3 標準ライブラリのみ。取得した OSM データは `scripts/.osm_cache/` +にキャッシュされ、再実行が高速になります(このディレクトリは Git 管理対象外)。 + +### データソース・ライセンス + +地理データは OpenStreetMap (© OpenStreetMap contributors) を Overpass API 経由で取得しています。 +OSM データは [Open Database License (ODbL)](https://www.openstreetmap.org/copyright) の下で +提供されています。算出した距離値を再配布する際は出典表示にご留意ください。 diff --git a/scripts/compute_average_distance.py b/scripts/compute_average_distance.py new file mode 100644 index 00000000..4d75e67e --- /dev/null +++ b/scripts/compute_average_distance.py @@ -0,0 +1,572 @@ +#!/usr/bin/env python3 +""" +路線ごとの平均駅間距離 (average_distance) を OpenStreetMap の線路ジオメトリから +「線路に沿った実際の距離」として算出し、data/2!lines.csv を更新するスクリプト。 + +従来の average_distance は「駅座標の直線距離 × 路線種別ごとの固定係数(1.05〜1.25)」 +という推定値だった。本スクリプトは OSM の鉄道ルート関係(route relation)から当該路線の +線路だけを取り出し、隣接駅間を線路に沿って経路探索することで実距離を求める。 + +データソース: OpenStreetMap (c) OpenStreetMap contributors, ODbL. + https://www.openstreetmap.org/copyright + +使い方: + # 既知路線で較正・精度確認(CSVは書き換えない) + python3 scripts/compute_average_distance.py --validate + + # 任意の line_cd を個別計算(CSVは書き換えない) + python3 scripts/compute_average_distance.py --lines 11302,1002 + + # 全路線を計算して data/2!lines.csv を書き換える + python3 scripts/compute_average_distance.py --apply + +取得した OSM ジオメトリは scripts/.osm_cache/ にキャッシュされ、再実行が速くなる。 +""" +from __future__ import annotations + +import argparse +import csv +import heapq +import json +import math +import os +import sys +import time +import urllib.parse +import urllib.request + +# --------------------------------------------------------------------------- +# パス・定数 +# --------------------------------------------------------------------------- +HERE = os.path.dirname(os.path.abspath(__file__)) +ROOT = os.path.dirname(HERE) +LINES_CSV = os.path.join(ROOT, "data", "2!lines.csv") +STATIONS_CSV = os.path.join(ROOT, "data", "3!stations.csv") +CACHE_DIR = os.path.join(HERE, ".osm_cache") + +# 複数ミラーをラウンドロビン。混雑時(504)や不通時に切り替える。 +OVERPASS_ENDPOINTS = [ + "https://maps.mail.ru/osm/tools/overpass/api/interpreter", + "https://overpass-api.de/api/interpreter", + "https://overpass.kumi.systems/api/interpreter", +] +# 1リクエストあたりの最大待ち時間(秒)。不通ミラーで長時間ブロックしないよう短めに。 +HTTP_TIMEOUT = 60 +USER_AGENT = "StationAPI-average-distance/1.0 (railway data maintenance)" + +# 駅をグラフノードへ対応付ける際の半径(m)。複線(上下線)の両トラックを拾うため広めに取る。 +SNAP_RADIUS_M = 70.0 +# ルート関係を当該路線と認める最大カバレッジ(m)。全駅がこの距離以内であること。 +MATCH_MAX_M = 200.0 +# 経路探索結果の妥当範囲。直線距離に対する比がこの範囲外なら失敗扱い。 +MIN_RATIO = 0.8 +MAX_RATIO = 4.0 + +# line_type -> 旧来の固定係数(フォールバック時に使用) +FALLBACK_FACTOR = {"1": 1.05, "2": 1.15, "3": 1.10, "4": 1.25, "5": 1.10, "0": 1.15} + +# 較正用の既知路線(おおよその実営業キロ平均駅間距離・メートル) +KNOWN = { + "11302": ("山手線", 1150), + "1002": ("東海道新幹線", 32213), + "1004": ("東北新幹線", None), + "11329": ("中央線快速", None), +} + + +# --------------------------------------------------------------------------- +# 幾何ユーティリティ +# --------------------------------------------------------------------------- +def haversine(lon1: float, lat1: float, lon2: float, lat2: float) -> float: + """2点間の大圏距離(メートル)。""" + r = 6371000.0 + p1, p2 = math.radians(lat1), math.radians(lat2) + dphi = math.radians(lat2 - lat1) + dlmb = math.radians(lon2 - lon1) + a = math.sin(dphi / 2) ** 2 + math.cos(p1) * math.cos(p2) * math.sin(dlmb / 2) ** 2 + return 2 * r * math.asin(math.sqrt(a)) + + +# --------------------------------------------------------------------------- +# Overpass 取得(リトライ+エンドポイント切替+ローカルキャッシュ) +# --------------------------------------------------------------------------- +def _cache_path(key: str) -> str: + """Overpass クエリ文字列に対応するキャッシュファイルのパスを返す。""" + import hashlib + + h = hashlib.sha1(key.encode()).hexdigest() + return os.path.join(CACHE_DIR, f"{h}.json") + + +def overpass(query: str, *, tries: int = 6) -> dict: + """Overpass クエリを投げて JSON を返す。結果はキャッシュする。""" + os.makedirs(CACHE_DIR, exist_ok=True) + cp = _cache_path(query) + if os.path.exists(cp): + with open(cp, encoding="utf-8") as f: + return json.load(f) + + last_err = None + for attempt in range(tries): + endpoint = OVERPASS_ENDPOINTS[attempt % len(OVERPASS_ENDPOINTS)] + try: + data = urllib.parse.urlencode({"data": query}).encode() + req = urllib.request.Request( + endpoint, data=data, headers={"User-Agent": USER_AGENT} + ) + with urllib.request.urlopen(req, timeout=HTTP_TIMEOUT) as resp: + result = json.load(resp) + with open(cp, "w", encoding="utf-8") as f: + json.dump(result, f) + return result + except Exception as e: # noqa: BLE001 - ネットワーク系の各種例外をまとめて再試行 + last_err = e + wait = min(4 * (attempt + 1), 30) + sys.stderr.write(f" overpass retry {attempt} ({endpoint}): {e!r} -> sleep {wait}s\n") + time.sleep(wait) + raise RuntimeError(f"overpass failed after {tries} tries: {last_err!r}") + + +# --------------------------------------------------------------------------- +# データ読み込み +# --------------------------------------------------------------------------- +def load_lines() -> list[dict]: + """data/2!lines.csv を辞書のリストとして読み込む。""" + with open(LINES_CSV, newline="", encoding="utf-8") as f: + return list(csv.DictReader(f)) + + +def load_stations_by_line() -> dict[str, list[dict]]: + """稼働駅(e_status=0)を line_cd ごとにまとめた辞書を返す。""" + by_line: dict[str, list[dict]] = {} + with open(STATIONS_CSV, newline="", encoding="utf-8") as f: + for s in csv.DictReader(f): + if s["e_status"] == "0": + by_line.setdefault(s["line_cd"], []).append(s) + return by_line + + +def line_station_coords(stations: list[dict]) -> list[tuple[float, float, str]]: + """駅リストを e_sort 順に並べ、(経度, 緯度, 駅名) のリストにして返す。""" + sts = sorted(stations, key=lambda s: int(s["e_sort"])) + return [(float(s["lon"]), float(s["lat"]), s["station_name"]) for s in sts] + + +# --------------------------------------------------------------------------- +# ルート関係の取得・マッチング +# --------------------------------------------------------------------------- +ROUTE_FILTER = '["route"~"^(train|railway|subway|light_rail|monorail|tram)$"]' + + +def _name_tokens(name: str) -> str: + """路線名比較用の簡易正規化(JR 表記や全角括弧の揺れを吸収する)。""" + # 比較用に括弧書き等を緩く扱うための簡易正規化 + return name.replace("JR", "").replace("(", "(").replace(")", ")") + + +def _rel_ways(rel: dict) -> list[list[tuple[float, float]]]: + """`out geom;` で取得した関係要素から、構成way(>=2点)のジオメトリ列を取り出す。""" + ways = [ + [(p["lon"], p["lat"]) for p in m["geometry"]] + for m in rel.get("members", []) + if m["type"] == "way" and "geometry" in m + ] + return [w for w in ways if len(w) >= 2] + + +def _overpass_name_regex(line_name: str) -> str: + """路線名から Overpass の name 正規表現(メタ文字エスケープ済み部分一致)を作る。""" + import re + + base = line_name.strip() + return re.escape(base) if base else "" + + +def _pick_relation(rels: list[dict], coords, line_name: str): + """候補関係群(ジオメトリ込み)から当該路線を1つ選ぶ。 + + 誤マッチ防止のため「全駅 ≤ MATCH_MAX_M」を必須とし、名前一致を優先、 + 同条件ではカバレッジ最良を採用する。候補無しなら None。 + """ + norm_line = _name_tokens(line_name) + + def name_match(rel) -> bool: + nm = rel.get("tags", {}).get("name") or "" + nn = _name_tokens(nm) + return bool(nn) and (norm_line in nn or nn in norm_line) + + best = None + best_key = None + best_ways = best_cov = best_max = None + for rel in rels: + if rel.get("type") != "relation": + continue + ways = _rel_ways(rel) + if not ways: + continue + total = 0.0 + mx = 0.0 + for c in coords: + # 駅から線路への距離は頂点ではなく線分への投影距離で測る。 + # 頂点だけだと長い線分の途中にある駅を過大に遠いと誤判定し、 + # 有効な relation を取りこぼして不要なフォールバックを招くため。 + d = min( + _project_to_segment(c[0], c[1], w[i], w[i + 1])[0] + for w in ways + for i in range(len(w) - 1) + ) + total += d + mx = max(mx, d) + if mx > MATCH_MAX_M: + continue + cov = total / len(coords) + # 名前一致を最優先(False=0 が前)、次にカバレッジ昇順 + key = (not name_match(rel), cov) + if best_key is None or key < best_key: + best, best_key, best_ways, best_cov, best_max = rel, key, ways, cov, mx + if best is None: + return None + return best, best_ways, best_cov, best_max + + +def find_best_relation(coords: list[tuple[float, float, str]], line_name: str): + """当該路線のルート関係を1つ選び、(関係要素, 構成way群, 平均/最大カバレッジ) を返す。 + + 高速化のため1リクエストで候補関係をジオメトリ込み取得する(per-relation の再取得をしない)。 + まず路線名で絞り込み、ヒットしなければ bbox 内の全ルート関係に広げる。候補無しなら None。 + """ + lons = [c[0] for c in coords] + lats = [c[1] for c in coords] + pad = 0.005 + bb = f"{min(lats) - pad},{min(lons) - pad},{max(lats) + pad},{max(lons) + pad}" + + # 1) 路線名で絞り込み(小さく速い) + name_re = _overpass_name_regex(line_name) + if name_re: + q = ( + f"[out:json][timeout:180];" + f"relation[\"type\"=\"route\"]{ROUTE_FILTER}[\"name\"~\"{name_re}\"]({bb});" + f"out geom;" + ) + rels = [e for e in overpass(q)["elements"] if e["type"] == "relation"] + picked = _pick_relation(rels, coords, line_name) + if picked is not None: + return picked + + # 2) bbox 内の全ルート関係に広げる(ジオメトリ込み・1リクエスト) + q = ( + f"[out:json][timeout:180];" + f"relation[\"type\"=\"route\"]{ROUTE_FILTER}({bb});" + f"out geom;" + ) + rels = [e for e in overpass(q)["elements"] if e["type"] == "relation"] + return _pick_relation(rels, coords, line_name) + + +# --------------------------------------------------------------------------- +# グラフ構築 & 経路探索 +# --------------------------------------------------------------------------- +def _nid(p): + """座標を丸めてグラフのノード ID に正規化する。""" + return (round(p[0], 7), round(p[1], 7)) + + +def build_graph(ways: list[list[tuple[float, float]]]) -> dict: + """way 群から、辺重みを隣接頂点間ハバサイン距離とする無向グラフを構築する。""" + adj: dict[tuple[float, float], list[tuple[tuple[float, float], float]]] = {} + for w in ways: + for i in range(len(w) - 1): + a, b = _nid(w[i]), _nid(w[i + 1]) + if a == b: + continue + d = haversine(w[i][0], w[i][1], w[i + 1][0], w[i + 1][1]) + adj.setdefault(a, []).append((b, d)) + adj.setdefault(b, []).append((a, d)) + return adj + + +def _project_to_segment(lon0: float, lat0: float, p1, p2): + """駅(lon0,lat0)を線分 p1-p2 に投影し、(垂線距離m, 端点p1までの線路沿い距離m, + 端点p2までの線路沿い距離m) を返す。短距離なので局所平面近似で計算する。""" + coslat = math.cos(math.radians(lat0)) + + def xy(p): + return ((p[0] - lon0) * coslat * 111320.0, (p[1] - lat0) * 110540.0) + + ax, ay = xy(p1) + bx, by = xy(p2) + abx, aby = bx - ax, by - ay + l2 = abx * abx + aby * aby + if l2 == 0.0: + d = math.hypot(ax, ay) + return d, 0.0, 0.0 + # 駅を原点とした投影パラメータ t(0..1にクランプ) + t = -(ax * abx + ay * aby) / l2 + t = max(0.0, min(1.0, t)) + px, py = ax + t * abx, ay + t * aby + perp = math.hypot(px, py) + seglen = math.sqrt(l2) + return perp, t * seglen, (1.0 - t) * seglen + + +def snap_anchors(ways, lon: float, lat: float, radius: float = SNAP_RADIUS_M): + """駅を線路セグメントに投影し、到達アンカー {ノード: 投影点からの線路沿いオフセットm} + を返す。半径内のセグメントが無ければ最も近い1セグメントを採用する。 + 併せて最近傍セグメントへの垂線距離(スナップ品質)も返す。""" + anchors: dict[tuple[float, float], float] = {} + near_perp = float("inf") + near_anchor = None + for w in ways: + for i in range(len(w) - 1): + p1, p2 = w[i], w[i + 1] + perp, d1, d2 = _project_to_segment(lon, lat, p1, p2) + if perp < near_perp: + near_perp = perp + near_anchor = ((_nid(p1), d1), (_nid(p2), d2)) + if perp <= radius: + n1, n2 = _nid(p1), _nid(p2) + if d1 < anchors.get(n1, float("inf")): + anchors[n1] = d1 + if d2 < anchors.get(n2, float("inf")): + anchors[n2] = d2 + if not anchors and near_anchor is not None: + for n, off in near_anchor: + if off < anchors.get(n, float("inf")): + anchors[n] = off + return list(anchors.items()), near_perp + + +def route_anchors(adj: dict, src: list, dst: list, limit: float): + """投影アンカー間の線路沿い最短距離。src/dst は (ノード, オフセットm) のリスト。 + 各始点をオフセットで初期化し、終点到達時に終点オフセットを足した最小値を返す。""" + dist = {} + pq = [] + for n, off in src: + if off < dist.get(n, float("inf")): + dist[n] = off + heapq.heappush(pq, (off, n)) + dst_off = {} + for n, off in dst: + if off < dst_off.get(n, float("inf")): + dst_off[n] = off + best = float("inf") + while pq: + d, u = heapq.heappop(pq) + if d > dist.get(u, float("inf")) or d > limit: + continue + if d >= best: + break # d は単調増加。これ以上 best を更新できない + if u in dst_off: + best = min(best, d + dst_off[u]) + for v, w in adj.get(u, []): + nd = d + w + if nd < dist.get(v, float("inf")): + dist[v] = nd + heapq.heappush(pq, (nd, v)) + return best if best < float("inf") else None + + +# --------------------------------------------------------------------------- +# 路線ごとの平均駅間距離算出 +# --------------------------------------------------------------------------- +class LineResult: + def __init__(self, line_cd, line_name): + self.line_cd = line_cd + self.line_name = line_name + self.average = None # 採用した平均駅間距離(m) + self.method = "fallback" # "osm" or "fallback" + self.rel_id = None + self.rel_name = None + self.coverage = None + self.n_segments = 0 + self.n_failed = 0 + self.straight_avg = None + + def __repr__(self): + avg = self.average if self.average is not None else 0.0 + return ( + f"{self.line_cd} {self.line_name}: {self.method} avg={avg:.1f} " + f"rel={self.rel_name} fail={self.n_failed}/{self.n_segments}" + ) + + +def compute_line(line_cd: str, line_name: str, line_type: str, coords) -> LineResult: + """1 路線の平均駅間距離を算出する。OSM 実距離を優先し、不可なら従来式へフォールバックする。""" + res = LineResult(line_cd, line_name) + straight = [ + haversine(coords[i][0], coords[i][1], coords[i + 1][0], coords[i + 1][1]) + for i in range(len(coords) - 1) + ] + res.n_segments = len(straight) + res.straight_avg = sum(straight) / len(straight) if straight else None + + matched = None + try: + matched = find_best_relation(coords, line_name) + except Exception as e: # noqa: BLE001 + sys.stderr.write(f" {line_cd} {line_name}: relation lookup error {e!r}\n") + + if matched is not None: + rel, ways, cov, mx = matched + adj = build_graph(ways) + snapped = [snap_anchors(ways, c[0], c[1])[0] for c in coords] + seg_dist = [] + failed = 0 + for i in range(len(coords) - 1): + sd = straight[i] + rd = route_anchors( + adj, snapped[i], snapped[i + 1], max(sd * MAX_RATIO, sd + 5000) + ) + if rd is None or rd > sd * MAX_RATIO or rd < sd * MIN_RATIO: + failed += 1 + # 経路探索できない区間は旧来式(直線距離 x 固定係数)で軌道距離を推定する。 + # 直線距離をそのまま使うと実距離の下限になり、平均が過小評価されるため。 + factor = FALLBACK_FACTOR.get(line_type, 1.15) + seg_dist.append(sd * factor) + else: + # 実距離は直線距離を下回らない(駅は線路から横にずれているため + # 投影間の線路沿い距離が僅かに直線を下回ることがあるが、物理的下限で丸める) + seg_dist.append(max(rd, sd)) + # 半数以上失敗した路線は信頼できないのでフォールバック扱いにする + if seg_dist and failed <= len(seg_dist) / 2: + res.average = sum(seg_dist) / len(seg_dist) + res.method = "osm" + res.rel_id = rel["id"] + res.rel_name = rel.get("tags", {}).get("name") + res.coverage = cov + res.n_failed = failed + return res + + # --- フォールバック: 旧来式(直線距離 × 固定係数) --- + if res.straight_avg is not None: + factor = FALLBACK_FACTOR.get(line_type, 1.15) + res.average = res.straight_avg * factor + res.method = "fallback" + return res + + +# --------------------------------------------------------------------------- +# CSV 書き換え +# --------------------------------------------------------------------------- +def format_distance(value: float) -> str: + """距離値を既存 CSV と同程度の桁数の文字列に整形する。""" + # 既存CSVは小数を含む (例: 31785.47337)。同程度の桁で出力する。 + return f"{value:.5f}".rstrip("0").rstrip(".") + + +def apply_to_csv(results: dict[str, LineResult]) -> int: + """算出結果で data/2!lines.csv の average_distance 列だけを書き換え、更新セル数を返す。""" + with open(LINES_CSV, newline="", encoding="utf-8") as f: + reader = csv.reader(f) + rows = list(reader) + header = rows[0] + cd_idx = header.index("line_cd") + avg_idx = header.index("average_distance") + + changed = 0 + for row in rows[1:]: + if len(row) <= avg_idx: + continue + cd = row[cd_idx] + r = results.get(cd) + if r is None or r.average is None: + continue + new_val = format_distance(r.average) + if row[avg_idx] != new_val: + row[avg_idx] = new_val + changed += 1 + + with open(LINES_CSV, "w", newline="", encoding="utf-8") as f: + writer = csv.writer(f) + writer.writerows(rows) + return changed + + +# --------------------------------------------------------------------------- +# メイン +# --------------------------------------------------------------------------- +def run(line_cds: list[str], lines_meta: dict[str, dict], by_line: dict) -> dict[str, LineResult]: + """指定した line_cd 群を順に計算し、line_cd -> LineResult の辞書を返す。""" + results: dict[str, LineResult] = {} + total = len(line_cds) + for i, cd in enumerate(line_cds, 1): + meta = lines_meta.get(cd) + if meta is None: + continue + sts = by_line.get(cd, []) + if len(sts) < 2: + continue + coords = line_station_coords(sts) + res = compute_line(cd, meta["line_name"], meta["line_type"], coords) + results[cd] = res + sys.stderr.write( + f"[{i}/{total}] {cd} {meta['line_name']}: {res.method} " + f"avg={res.average:.1f} " + f"(straight={res.straight_avg:.1f}) " + f"rel={res.rel_name} fail={res.n_failed}/{res.n_segments}\n" + ) + sys.stderr.flush() + time.sleep(0.3) # ポライトな間隔 + return results + + +def main() -> int: + """CLI エントリポイント。--validate / --lines / --apply を切り替える。""" + ap = argparse.ArgumentParser(description=__doc__) + g = ap.add_mutually_exclusive_group() + g.add_argument("--validate", action="store_true", help="既知路線で較正のみ(CSV不変)") + g.add_argument("--apply", action="store_true", help="全路線を計算しCSVを書き換える") + g.add_argument("--lines", type=str, help="カンマ区切りの line_cd を計算(CSV不変)") + args = ap.parse_args() + + lines = load_lines() + lines_meta = {line["line_cd"]: line for line in lines} + by_line = load_stations_by_line() + + if args.validate: + targets = list(KNOWN.keys()) + results = run(targets, lines_meta, by_line) + print("\n=== 較正結果 ===") + for cd in targets: + r = results.get(cd) + if not r: + continue + known = KNOWN[cd][1] + err = "" if known is None else f" / 実測~{known} (誤差 {(r.average - known) / known * 100:+.1f}%)" + print(f"{cd} {r.line_name}: {r.method} avg={r.average:.1f}{err} fail={r.n_failed}/{r.n_segments}") + return 0 + + if args.lines: + targets = [c.strip() for c in args.lines.split(",") if c.strip()] + results = run(targets, lines_meta, by_line) + print("\n=== 結果 ===") + for cd in targets: + r = results.get(cd) + if r: + print(f"{cd} {r.line_name}: {r.method} avg={r.average:.1f} rel={r.rel_name} fail={r.n_failed}/{r.n_segments}") + return 0 + + if args.apply: + active = [ + line + for line in lines + if line["e_status"] == "0" and len(by_line.get(line["line_cd"], [])) >= 2 + ] + targets = [line["line_cd"] for line in active] + results = run(targets, lines_meta, by_line) + n_osm = sum(1 for r in results.values() if r.method == "osm") + n_fb = sum(1 for r in results.values() if r.method == "fallback") + changed = apply_to_csv(results) + print("\n=== 適用レポート ===") + print(f"対象路線: {len(results)}") + print(f" OSM実距離で算出: {n_osm}") + print(f" フォールバック(直線×係数): {n_fb}") + print(f"CSV更新セル数: {changed}") + return 0 + + ap.print_help() + return 1 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/stationapi/proto b/stationapi/proto index e688075c..bfac88b2 160000 --- a/stationapi/proto +++ b/stationapi/proto @@ -1 +1 @@ -Subproject commit e688075c99566978d3bea9ebc0e7f7ac194b566a +Subproject commit bfac88b2dfecfc27812e5c6b57d90dedca4bdddc diff --git a/stationapi/src/domain.rs b/stationapi/src/domain.rs index 87d9d08c..f8b8eddb 100644 --- a/stationapi/src/domain.rs +++ b/stationapi/src/domain.rs @@ -1,3 +1,4 @@ +pub mod arrival_estimation; pub mod entity; pub mod error; pub mod ipa; diff --git a/stationapi/src/domain/arrival_estimation.rs b/stationapi/src/domain/arrival_estimation.rs new file mode 100644 index 00000000..e3cd61cc --- /dev/null +++ b/stationapi/src/domain/arrival_estimation.rs @@ -0,0 +1,1125 @@ +//! 駅リスト始点からの予定到着時間(始点からの累積分数)を推定する純粋ロジック。 +//! +//! 公式時刻表・商用 API・実距離データが無い前提で、駅座標(直線距離)と +//! メタデータ(列車種別の停車/通過パターン、路線種別、駅間平均距離)だけから +//! 物理的に妥当な所要時間を推定する。 +//! +//! モデル概要: +//! 1. 連続駅間の直線距離(haversine)を求める。 +//! 2. 迂回係数 `α` で「みなし走行距離(軌道距離)」へ補正する。`α` は +//! `Line.average_distance`(メートル単位・実距離±10%精度)が得られる路線では +//! `average_distance / 直線平均駅間距離` で較正し、得られない路線では +//! 路線種別ベースの固定値にフォールバックする。 +//! 3. 停車駅間ごとに「加速→巡航→減速」の運動学モデルで走行時間を算出する。 +//! 停車が多いほど巡航しきれず平均速度が落ちる(各停が速達より遅い)現象が +//! 加減速ペナルティとして自然に表現される。運動学モデルは理想走行 +//! (最大加速→最高速度で巡航→最大減速)を仮定するため、実ダイヤに含まれる +//! 途中の速度制限・惰行・回復余裕のぶん系統的に速すぎる。これを走行時間への +//! 運転余裕率 `run_margin` として補正する(実路線の時刻表との較正で約 1.15)。 +//! 4. 中間停車駅に停車時間 `dwell` を加算して累積する。 +//! +//! 入力経路は運用上 `line_group_cd` を跨がない(=単一の列車・直通サービス)ため +//! 乗換時間は加算しない。直通で `line_cd` が変わる区間は `α`・最高速度の +//! 切り替えにのみ用いる。 +//! +//! IO を持たない純粋関数群なので、すべて単体テスト可能。 + +use std::collections::HashMap; + +use crate::domain::entity::gtfs::TransportType; +use crate::domain::entity::station::Station; +use crate::proto::StopCondition; + +/// 1 駅分の推定結果。 +#[derive(Clone, Debug, PartialEq)] +pub struct EstimatedStop { + pub station_cd: i32, + pub station_g_cd: i32, + /// この駅が属する経路(line_group_cd)。複数候補経路をフラットな Vec で返す際に、 + /// 呼び出し側が経路境界を復元できるようにする。line_group_cd が無い駅は line_cd。 + pub line_group_cd: Option, + /// 始点からの累積到着時間(分)。通過駅は停車駅間を速度プロファイル別に分割した + /// 走行時間の積み上げで求めた通過時刻。 + pub cumulative_minutes: f64, + /// 始点からの累積出発時刻(分)。中間停車駅では「到着 + 停車時間(dwell)」、 + /// 通過駅では通過時刻(= `cumulative_minutes`)、終点では到着時刻と同じ + /// (以降の出発が無いため)。クライアントは基準駅 k0 と任意の駅 k について + /// 「到着(k) − 出発(k0)」で基準駅発の正確な残り時間(発車基準 ETA)を計算できる。 + pub departure_cumulative_minutes: f64, + /// その駅に停車するか(false = 通過)。 + pub stops_here: bool, +} + +/// 推定で使う調整可能なパラメータ。すべて「実距離・実速度・ダイヤが無い」前提の +/// ヒューリスティックであり、後から較正・上書きできるよう一箇所に集約する。 +#[derive(Clone, Copy, Debug)] +pub struct EstimationParams { + /// 加速度 (m/s^2)。 + pub accel: f64, + /// 減速度 (m/s^2)。 + pub decel: f64, + /// 中間停車駅 1 駅あたりの停車時間(分)。ドア開閉・乗降に加え、 + /// 出発までの余裕時分も含む実効値。 + pub dwell_minutes: f64, + /// 走行時間に掛ける運転余裕率。運動学モデルの理想走行と実ダイヤの差 + /// (途中の速度制限・惰行・回復余裕)を包括する補正係数。 + pub run_margin: f64, + /// 迂回係数 `α` のクランプ下限。 + pub detour_min: f64, + /// 迂回係数 `α` のクランプ上限。 + pub detour_max: f64, +} + +impl Default for EstimationParams { + fn default() -> Self { + Self { + accel: 0.7, + decel: 0.9, + dwell_minutes: 0.6, + run_margin: 1.15, + detour_min: 1.0, + detour_max: 1.6, + } + } +} + +/// 新幹線を表す `line_type`。 +const LINE_TYPE_SHINKANSEN: i32 = 1; +/// 地下鉄を表す `line_type`。 +const LINE_TYPE_SUBWAY: i32 = 3; +/// 路面電車を表す `line_type`。 +const LINE_TYPE_TRAM: i32 = 4; +/// AGT/モノレールを表す `line_type`。 +const LINE_TYPE_AGT: i32 = 5; +/// ケーブルカーを表す `line_type`。 +const LINE_TYPE_CABLE: i32 = 0; + +/// バスの最高速度(km/h)。市街地の法定速度・信号停止を踏まえた実効上限。 +/// GTFS 由来のバス路線は `line_type` に GTFS の `route_type`(バス=3)がそのまま +/// 入っており鉄道の路線種別(3=地下鉄)と衝突するため、速度・迂回係数の判定には +/// `line_type` ではなく `transport_type` を使う。 +const BUS_MAX_SPEED_KMH: f64 = 50.0; +/// バスのフォールバック迂回係数。道路網の直線距離に対する迂回率。 +const BUS_FALLBACK_DETOUR: f64 = 1.30; + +/// 地球半径(メートル)。 +const EARTH_RADIUS_METERS: f64 = 6_371_000.0; + +/// 2 点間の距離を haversine 公式で求める。返り値はメートル。 +pub fn haversine_distance(lat1: f64, lon1: f64, lat2: f64, lon2: f64) -> f64 { + let lat1_rad = lat1.to_radians(); + let lat2_rad = lat2.to_radians(); + let delta_lat = (lat2 - lat1).to_radians(); + let delta_lon = (lon2 - lon1).to_radians(); + + let a = (delta_lat / 2.0).sin().powi(2) + + lat1_rad.cos() * lat2_rad.cos() * (delta_lon / 2.0).sin().powi(2); + let c = 2.0 * a.sqrt().asin(); + + EARTH_RADIUS_METERS * c +} + +/// 環状判定の最小駅数。実在の環状路線は最少 13 駅(富山都心線)。 +const CIRCULAR_MIN_STATIONS: usize = 6; +/// シーム(末尾駅→先頭駅)距離の、平均駅間距離に対する許容倍率。 +const CIRCULAR_SEAM_MEAN_RATIO: f64 = 2.0; +/// シーム距離の絶対上限(メートル)。実在環状路線の最大シームは山手線の約 1.4km。 +const CIRCULAR_SEAM_MAX_METERS: f64 = 3_000.0; +/// 連続駅間距離の最大値の、中央値に対する許容倍率。格納順に不連続な飛び +/// (支線を跨ぐ成田線や、別線の駅が末尾に連なる近鉄奈良線など)を持つ路線を +/// 環状と誤検出しないためのガード。 +const CIRCULAR_MAX_GAP_MEDIAN_RATIO: f64 = 3.0; + +/// 順序付き駅リストが環状(ループ)経路かどうかを座標だけから推定する。 +/// +/// スキーマに環状フラグは無いため、「末尾駅から先頭駅へ戻るシーム距離が +/// 通常の駅間距離と同程度に短い」ことをヒューリスティックに判定する。 +/// シードデータ全路線・全 line_group に対して山手線・大阪環状線(環状運転系統)・ +/// 名城線・札幌市電・富山都心線・伊予鉄環状線のみが検出され、誤検出が +/// 無いことを確認済み。 +pub fn is_circular_route(stops: &[&Station]) -> bool { + let n = stops.len(); + if n < CIRCULAR_MIN_STATIONS { + return false; + } + // 先頭駅が末尾にも重複して格納された「閉じた」ループはラップ不要 + // (ラップすると閉じ駅が二重に現れる)。 + if stops[0].station_cd == stops[n - 1].station_cd { + return false; + } + let mut gaps: Vec = (1..n) + .map(|i| { + haversine_distance( + stops[i - 1].lat, + stops[i - 1].lon, + stops[i].lat, + stops[i].lon, + ) + }) + .collect(); + let mean_gap = gaps.iter().sum::() / gaps.len() as f64; + if mean_gap <= 0.0 { + return false; + } + let seam = haversine_distance( + stops[n - 1].lat, + stops[n - 1].lon, + stops[0].lat, + stops[0].lon, + ); + if seam > CIRCULAR_SEAM_MAX_METERS || seam > CIRCULAR_SEAM_MEAN_RATIO * mean_gap { + return false; + } + gaps.sort_by(|a, b| a.total_cmp(b)); + let median_gap = gaps[gaps.len() / 2]; + let max_gap = gaps[gaps.len() - 1]; + median_gap > 0.0 && max_gap <= CIRCULAR_MAX_GAP_MEDIAN_RATIO * median_gap +} + +/// 弧の直線距離合計(メートル)。無向の弧候補の比較に使う。 +fn arc_length_meters(arc: &[&Station]) -> f64 { + (1..arc.len()) + .map(|i| haversine_distance(arc[i - 1].lat, arc[i - 1].lon, arc[i].lat, arc[i].lon)) + .sum() +} + +/// 環状経路上で `from_idx` → `to_idx` へ進む弧(arc)の駅列を返す。 +/// +/// `directed == true`(direction_id 指定あり)なら格納された向きに沿って進み、 +/// 必要ならシーム(末尾→先頭)を跨いでラップする(決して反転しない)。 +/// `directed == false` なら順方向弧と逆方向弧のうち直線距離合計が短い方を返す +/// (同値なら順方向)。駅数比較だと対蹠ペアでタイになるため距離で比べる。 +pub fn select_circular_arc<'a>( + stops: &[&'a Station], + from_idx: usize, + to_idx: usize, + directed: bool, +) -> Vec<&'a Station> { + // 順方向弧: 格納順に進み、末尾を越えたら先頭へラップする。 + let forward: Vec<&Station> = if from_idx <= to_idx { + stops[from_idx..=to_idx].to_vec() + } else { + stops[from_idx..] + .iter() + .chain(stops[..=to_idx].iter()) + .copied() + .collect() + }; + if directed { + return forward; + } + // 逆方向弧: 格納順を遡り、先頭を越えたら末尾へラップする。 + let backward: Vec<&Station> = if to_idx <= from_idx { + stops[to_idx..=from_idx].iter().rev().copied().collect() + } else { + stops[..=from_idx] + .iter() + .rev() + .chain(stops[to_idx..].iter().rev()) + .copied() + .collect() + }; + if arc_length_meters(&backward) < arc_length_meters(&forward) { + backward + } else { + forward + } +} + +/// `average_distance` が得られない路線で使う、路線種別ベースの固定迂回係数。 +fn fallback_detour_factor(line_type: Option, transport_type: TransportType) -> f64 { + if transport_type == TransportType::Bus { + return BUS_FALLBACK_DETOUR; + } + match line_type { + Some(LINE_TYPE_SHINKANSEN) => 1.15, + Some(LINE_TYPE_SUBWAY) => 1.20, + Some(LINE_TYPE_TRAM) => 1.40, + Some(LINE_TYPE_AGT) => 1.20, + Some(LINE_TYPE_CABLE) => 1.10, + _ => 1.30, + } +} + +/// 迂回係数 `α` を決める。 +/// +/// `avg_distance_km`(= `Line.average_distance` を km 換算した値、実距離±10%精度)が得られる場合は +/// `avg_distance_km / mean_straight_km` で較正し、`detour_min..=detour_max` にクランプする。 +/// 得られない(`<= 0`)場合や直線平均が 0 の場合は路線種別ベースの固定値へフォールバックする。 +pub fn detour_factor_for( + avg_distance_km: f64, + mean_straight_km: f64, + line_type: Option, + transport_type: TransportType, + params: &EstimationParams, +) -> f64 { + if avg_distance_km > 0.0 && mean_straight_km > 0.0 { + (avg_distance_km / mean_straight_km).clamp(params.detour_min, params.detour_max) + } else { + fallback_detour_factor(line_type, transport_type) + } +} + +/// 路線種別ごとの基本最高速度(km/h)。 +fn base_speed_kmh(line_type: Option) -> f64 { + match line_type { + Some(LINE_TYPE_SHINKANSEN) => 250.0, + Some(LINE_TYPE_SUBWAY) => 75.0, + Some(LINE_TYPE_TRAM) => 40.0, + Some(LINE_TYPE_AGT) => 60.0, + Some(LINE_TYPE_CABLE) => 12.0, + _ => 80.0, + } +} + +/// 路線種別・列車種別から最高速度(km/h)を決める。 +/// +/// バスは `line_type`(GTFS の route_type が混入)や `kind`(BusRoute=7 は経路 +/// マーカーであり優等種別ではない)で判定できないため、`transport_type` で +/// 先に分岐して固定の実効上限を返す。 +fn max_speed_kmh(line_type: Option, kind: Option, transport_type: TransportType) -> f64 { + if transport_type == TransportType::Bus { + return BUS_MAX_SPEED_KMH; + } + let base = base_speed_kmh(line_type); + if line_type == Some(LINE_TYPE_SHINKANSEN) { + return base; + } + match kind { + Some(k) if k != 0 => base * 1.2, + _ => base, + } +} + +/// 停車駅間の走行時間(分)を運動学モデルで求める。 +/// +/// 列車は 0→v_max 加速 → 巡航 → v_max→0 減速すると仮定する。 +/// 区間距離が短く v_max に到達できない場合は三角形プロファイルで頂点速度を解く。 +/// 理想走行と実ダイヤの差を埋めるため、結果に運転余裕率 `run_margin` を掛ける。 +pub fn segment_run_minutes(distance_m: f64, v_max_kmh: f64, params: &EstimationParams) -> f64 { + if distance_m <= 0.0 || v_max_kmh <= 0.0 { + return 0.0; + } + let v = v_max_kmh / 3.6; // m/s + let a = params.accel; + let b = params.decel; + let d_acc = v * v / (2.0 * a); + let d_dec = v * v / (2.0 * b); + + let seconds = if distance_m >= d_acc + d_dec { + // v_max に到達:加速 + 巡航 + 減速。 + v / a + v / b + (distance_m - d_acc - d_dec) / v + } else { + // 三角形プロファイル:頂点速度 v_peak で加速→減速。 + let v_peak = (2.0 * distance_m * a * b / (a + b)).sqrt(); + v_peak / a + v_peak / b + }; + seconds * params.run_margin / 60.0 +} + +/// その駅に列車が停車するか判定する。端点(始点・終点)は常に停車扱い。 +fn is_stop(station: &Station, is_endpoint: bool) -> bool { + if is_endpoint { + return true; + } + // 通過: pass == Some(1) もしくは stop_condition == Not。 + // Partial/Weekday/Holiday は MVP では停車扱い(将来は曜日入力で精緻化)。 + station.pass != Some(1) && station.stop_condition != StopCondition::Not +} + +/// `line_cd` ごとに較正した迂回係数 `α` を返すマップを作る。 +/// +/// 同一 `line_cd` が連続する駅ペアの直線距離だけを平均(直通の切れ目で生じる +/// 路線跨ぎペアは除外)して `average_distance` と比較する。 +fn detour_factors_by_line( + stops: &[&Station], + straight_km: &[f64], + params: &EstimationParams, +) -> HashMap { + // line_cd -> (直線距離の合計, ペア数, average_distance, line_type, transport_type) + let mut acc: HashMap, TransportType)> = HashMap::new(); + + for i in 1..stops.len() { + let cur = stops[i]; + let prev = stops[i - 1]; + // average_distance / line_type / transport_type は line_cd 単位で同じなので最初に見たものを採用。 + // average_distance はメートル単位で格納されているため km へ変換して直線平均と比較する。 + let entry = acc.entry(cur.line_cd).or_insert(( + 0.0, + 0, + cur.average_distance.unwrap_or(0.0) / 1000.0, + cur.line_type, + cur.transport_type, + )); + // 同一路線が連続するペアだけを直線平均の母数にする。 + if prev.line_cd == cur.line_cd { + entry.0 += straight_km[i]; + entry.1 += 1; + } + } + + acc.into_iter() + .map( + |(line_cd, (sum, count, avg_distance, line_type, transport_type))| { + let mean_straight = if count > 0 { sum / count as f64 } else { 0.0 }; + ( + line_cd, + detour_factor_for( + avg_distance, + mean_straight, + line_type, + transport_type, + params, + ), + ) + }, + ) + .collect() +} + +/// 停車駅間(`seg`)の各駅(通過駅・終点停車駅)へ到着時刻(分)を割り当てる。 +/// +/// `seg` は `(みなし走行距離 m, 最高速度 km/h, result index, 停車駅か)` のサブ区間列で、 +/// 末尾要素が次の停車駅に対応する。列車は始点停車駅で 0 から加速し終点停車駅で 0 まで減速する。 +/// 途中の通過駅では停車・加減速をしないが、直通で `line_cd` / 速度が変わるためサブ区間ごとに +/// 巡航時間を速度別に積む。単一サブ区間のときは加減速まで含む運動学モデル(短区間は三角形)で +/// 厳密に計算する。複数サブ区間の境界での速度遷移は簡易的に瞬時とみなす。 +fn assign_segment_times( + result: &mut [EstimatedStop], + seg: &[(f64, f64, usize, bool)], + departure_minutes: f64, + params: &EstimationParams, +) { + if seg.is_empty() { + return; + } + if seg.len() == 1 { + let (track_m, v_kmh, idx, _) = seg[0]; + let arrival = departure_minutes + segment_run_minutes(track_m, v_kmh, params); + result[idx].cumulative_minutes = arrival; + // 停車駅の出発時刻(dwell 加算)は呼び出し側が上書きする。 + result[idx].departure_cumulative_minutes = arrival; + return; + } + + // 複数サブ区間: 始点加速 + 各サブ区間の巡航 + 終点減速。 + let v_first = seg[0].1 / 3.6; // m/s + let v_last = seg[seg.len() - 1].1 / 3.6; + let accel_penalty_sec = v_first / (2.0 * params.accel); + let decel_penalty_sec = v_last / (2.0 * params.decel); + + let mut cruise_sec = 0.0; + for &(track_m, v_kmh, idx, is_stop) in seg.iter() { + let v = v_kmh / 3.6; + if v > 0.0 { + cruise_sec += track_m / v; + } + let seconds = if is_stop { + // 終点停車駅: 加速 + 全巡航 + 減速。 + accel_penalty_sec + cruise_sec + decel_penalty_sec + } else { + // 通過駅: 加速 + ここまでの巡航(減速はまだ)。 + accel_penalty_sec + cruise_sec + }; + let arrival = departure_minutes + seconds * params.run_margin / 60.0; + result[idx].cumulative_minutes = arrival; + // 通過駅は停車しないので出発 = 通過時刻。末尾の停車駅は呼び出し側が + // dwell を加味した出発時刻で上書きする。 + result[idx].departure_cumulative_minutes = arrival; + } +} + +/// 順序付き駅リスト(単一 `line_group_cd` の経路)に対し、始点からの累積到着時間(分)を推定する。 +/// +/// `stops` は始点→終点の順に並んでいること。返り値は入力と同じ順・同じ要素数。 +pub fn estimate_arrival_minutes( + stops: &[&Station], + params: &EstimationParams, +) -> Vec { + let n = stops.len(); + if n == 0 { + return Vec::new(); + } + + // 各駅 i について「前駅との直線距離(km)」。straight_km[0] は未使用(0)。 + let mut straight_km = vec![0.0_f64; n]; + for i in 1..n { + straight_km[i] = haversine_distance( + stops[i - 1].lat, + stops[i - 1].lon, + stops[i].lat, + stops[i].lon, + ) / 1000.0; + } + + // line_cd ごとの迂回係数。 + let detour_by_line = detour_factors_by_line(stops, &straight_km, params); + let detour_of = |station: &Station| -> f64 { + detour_by_line + .get(&station.line_cd) + .copied() + .unwrap_or_else(|| fallback_detour_factor(station.line_type, station.transport_type)) + }; + + // 各駅が停車するか。 + let stops_here: Vec = stops + .iter() + .enumerate() + .map(|(i, s)| is_stop(s, i == 0 || i == n - 1)) + .collect(); + + let line_group_of = + |station: &Station| -> Option { station.line_group_cd.or(Some(station.line_cd)) }; + + let mut result: Vec = Vec::with_capacity(n); + + // 始点。即時出発とみなすので到着・出発とも 0 分。 + result.push(EstimatedStop { + station_cd: stops[0].station_cd, + station_g_cd: stops[0].station_g_cd, + line_group_cd: line_group_of(stops[0]), + cumulative_minutes: 0.0, + departure_cumulative_minutes: 0.0, + stops_here: stops_here[0], + }); + + // 直前の停車駅を出発した時刻(分)。始点は即時出発なので 0。 + let mut last_departure = 0.0_f64; + // 現在の停車間セグメントに溜めるサブ区間。 + // (みなし走行距離 m, 最高速度 km/h, result index, 停車駅か) + let mut seg: Vec<(f64, f64, usize, bool)> = Vec::new(); + + for i in 1..n { + let track_m = straight_km[i] * detour_of(stops[i]) * 1000.0; + let v_kmh = max_speed_kmh(stops[i].line_type, stops[i].kind, stops[i].transport_type); + + let idx = result.len(); + result.push(EstimatedStop { + station_cd: stops[i].station_cd, + station_g_cd: stops[i].station_g_cd, + line_group_cd: line_group_of(stops[i]), + cumulative_minutes: 0.0, + departure_cumulative_minutes: 0.0, + stops_here: stops_here[i], + }); + seg.push((track_m, v_kmh, idx, stops_here[i])); + + if stops_here[i] { + // 停車駅に到達 → 速度プロファイル別サブ区間で走行時間を積み上げ、 + // 区間内の各駅(通過駅・終点停車駅)へ到着時刻を割り当てる。 + assign_segment_times(&mut result, &seg, last_departure, params); + + let arrival = result[idx].cumulative_minutes; + // 中間停車駅(終点以外)では停車時間を加えて次区間の出発時刻にする。 + last_departure = if i == n - 1 { + arrival + } else { + arrival + params.dwell_minutes + }; + result[idx].departure_cumulative_minutes = last_departure; + + seg.clear(); + } + } + + result +} + +#[cfg(test)] +mod tests { + use super::*; + + /// テスト用の最小 Station を作る(座標・路線情報・停車情報のみ意味を持つ)。 + fn station( + station_cd: i32, + line_cd: i32, + lat: f64, + lon: f64, + average_distance: Option, + ) -> Station { + Station { + station_cd, + station_g_cd: station_cd, + station_name: String::new(), + station_name_k: String::new(), + station_name_r: None, + station_name_zh: None, + station_name_ko: None, + station_numbers: vec![], + station_number1: None, + station_number2: None, + station_number3: None, + station_number4: None, + three_letter_code: None, + line_cd, + line: None, + lines: vec![], + pref_cd: 13, + post: String::new(), + address: String::new(), + lon, + lat, + open_ymd: String::new(), + close_ymd: String::new(), + e_status: 0, + e_sort: station_cd, + stop_condition: StopCondition::All, + distance: None, + has_train_types: false, + train_type: None, + company_cd: Some(1), + line_name: None, + line_name_k: None, + line_name_h: None, + line_name_r: None, + line_name_zh: None, + line_name_ko: None, + line_color_c: None, + line_type: Some(2), + line_symbol1: None, + line_symbol2: None, + line_symbol3: None, + line_symbol4: None, + line_symbol1_color: None, + line_symbol2_color: None, + line_symbol3_color: None, + line_symbol4_color: None, + line_symbol1_shape: None, + line_symbol2_shape: None, + line_symbol3_shape: None, + line_symbol4_shape: None, + average_distance, + type_id: None, + sst_id: None, + type_cd: None, + line_group_cd: Some(1000), + pass: None, + type_name: None, + type_name_k: None, + type_name_r: None, + type_name_zh: None, + type_name_ko: None, + color: None, + direction: None, + kind: None, + transport_type: TransportType::Rail, + } + } + + fn approx(a: f64, b: f64) { + assert!((a - b).abs() < 1e-3, "expected {b}, got {a}"); + } + + #[test] + fn haversine_same_point_is_zero() { + approx(haversine_distance(35.0, 139.0, 35.0, 139.0), 0.0); + } + + #[test] + fn segment_run_reaches_vmax_for_long_distance() { + let p = EstimationParams::default(); + // 10km を 80km/h で。巡航支配。 + let t = segment_run_minutes(10_000.0, 80.0, &p); + // 巡航のみなら 10km / 80km/h × 余裕率 1.15 = 8.625 分。加減速分だけ少し増える。 + assert!(t > 8.6 && t < 10.0, "got {t}"); + } + + #[test] + fn run_margin_scales_run_time_but_not_dwell() { + let mut p = EstimationParams::default(); + p.run_margin = 1.0; + let base = segment_run_minutes(5_000.0, 80.0, &p); + p.run_margin = 1.15; + let with_margin = segment_run_minutes(5_000.0, 80.0, &p); + approx(with_margin, base * 1.15); + } + + #[test] + fn segment_run_uses_triangular_profile_for_short_distance() { + let p = EstimationParams::default(); + // ごく短い区間では v_max に到達しない(三角形プロファイル)。 + let short = segment_run_minutes(100.0, 250.0, &p); + // v_max=250 で台形を仮定した場合よりは時間がかかる(頂点速度が低い)。 + assert!(short > 0.0); + // 同じ距離なら v_max を上げても結果は変わらない(到達しないため)。 + let short_slow = segment_run_minutes(100.0, 80.0, &p); + approx(short, short_slow); + } + + #[test] + fn detour_factor_calibrates_then_clamps() { + let p = EstimationParams::default(); + // average 1.3km / 直線 1.0km = 1.3。 + approx( + detour_factor_for(1.3, 1.0, Some(2), TransportType::Rail, &p), + 1.3, + ); + // 上限 1.6 でクランプ。 + approx( + detour_factor_for(5.0, 1.0, Some(2), TransportType::Rail, &p), + 1.6, + ); + // average_distance 無し → 在来線フォールバック 1.30。 + approx( + detour_factor_for(0.0, 1.0, Some(2), TransportType::Rail, &p), + 1.30, + ); + // 新幹線フォールバック 1.15。 + approx( + detour_factor_for(0.0, 1.0, Some(1), TransportType::Rail, &p), + 1.15, + ); + // バスは line_type=3(GTFS の route_type)でも地下鉄 1.20 ではなく道路 1.30。 + approx( + detour_factor_for(0.0, 1.0, Some(3), TransportType::Bus, &p), + 1.30, + ); + } + + /// 緯度方向に約 1.8km 間隔で並ぶ直線 3 駅。全駅停車。 + fn three_collinear_stations() -> Vec { + // 0.016 度 ≈ 1.78km。 + vec![ + station(1, 100, 35.000, 139.0, None), + station(2, 100, 35.016, 139.0, None), + station(3, 100, 35.032, 139.0, None), + ] + } + + #[test] + fn cumulative_times_increase_with_dwell() { + let p = EstimationParams::default(); + let stations = three_collinear_stations(); + let refs: Vec<&Station> = stations.iter().collect(); + let est = estimate_arrival_minutes(&refs, &p); + + assert_eq!(est.len(), 3); + // 始点は 0 分。 + approx(est[0].cumulative_minutes, 0.0); + assert!(est.iter().all(|e| e.stops_here)); + // 単調増加。 + assert!(est[1].cumulative_minutes > est[0].cumulative_minutes); + assert!(est[2].cumulative_minutes > est[1].cumulative_minutes); + // 中間駅で dwell(0.4分)が入るので、2区間目の到着は + // 「1区間の所要 × 2 + dwell」付近になる。 + let leg = est[1].cumulative_minutes; + approx(est[2].cumulative_minutes, leg * 2.0 + p.dwell_minutes); + } + + #[test] + fn departure_minutes_add_dwell_at_intermediate_stops_only() { + let p = EstimationParams::default(); + let stations = three_collinear_stations(); + let refs: Vec<&Station> = stations.iter().collect(); + let est = estimate_arrival_minutes(&refs, &p); + + // 始点: 即時出発なので到着・出発とも 0 分。 + approx(est[0].cumulative_minutes, 0.0); + approx(est[0].departure_cumulative_minutes, 0.0); + // 中間停車駅: 出発 = 到着 + dwell。 + approx( + est[1].departure_cumulative_minutes, + est[1].cumulative_minutes + p.dwell_minutes, + ); + // 終点: 以降の出発が無いので出発 = 到着。 + approx( + est[2].departure_cumulative_minutes, + est[2].cumulative_minutes, + ); + // クライアント側の発車基準 ETA: 到着(終点) − 出発(中間駅) = 1 区間の走行時間。 + let leg = est[1].cumulative_minutes; + approx( + est[2].cumulative_minutes - est[1].departure_cumulative_minutes, + leg, + ); + } + + #[test] + fn departure_minutes_equal_pass_time_at_passed_stations() { + let p = EstimationParams::default(); + let mut stations = three_collinear_stations(); + stations[1].pass = Some(1); + let refs: Vec<&Station> = stations.iter().collect(); + let est = estimate_arrival_minutes(&refs, &p); + + // 通過駅は停車しないので出発 = 通過時刻(dwell 加算なし)。 + assert!(!est[1].stops_here); + approx( + est[1].departure_cumulative_minutes, + est[1].cumulative_minutes, + ); + } + + #[test] + fn passed_station_skips_dwell_and_is_interpolated() { + let p = EstimationParams::default(); + let mut stations = three_collinear_stations(); + // 中間駅を通過にする。 + stations[1].pass = Some(1); + let refs: Vec<&Station> = stations.iter().collect(); + let est = estimate_arrival_minutes(&refs, &p); + + // 通過駅は stops_here=false。 + assert!(!est[1].stops_here); + assert!(est[0].stops_here && est[2].stops_here); + + // 通過駅の通過時刻は区間内に収まり、終点より手前。 + assert!(est[1].cumulative_minutes > 0.0); + assert!(est[1].cumulative_minutes < est[2].cumulative_minutes); + + // 全区間が 1 つの停車間セグメントになり、dwell が入らないぶん、 + // 全駅停車のときより終点到着が早い。 + let all_stop_stations = three_collinear_stations(); + let all_stop_refs: Vec<&Station> = all_stop_stations.iter().collect(); + let all_stop = estimate_arrival_minutes(&all_stop_refs, &p); + assert!(est[2].cumulative_minutes < all_stop[2].cumulative_minutes); + } + + #[test] + fn line_group_cd_is_propagated() { + let p = EstimationParams::default(); + let mut stations = three_collinear_stations(); + for s in stations.iter_mut() { + s.line_group_cd = Some(777); + } + let refs: Vec<&Station> = stations.iter().collect(); + let est = estimate_arrival_minutes(&refs, &p); + assert!(est.iter().all(|e| e.line_group_cd == Some(777))); + + // line_group_cd が無い場合は line_cd にフォールバック。 + let mut no_group = three_collinear_stations(); + for s in no_group.iter_mut() { + s.line_group_cd = None; + } + let refs2: Vec<&Station> = no_group.iter().collect(); + let est2 = estimate_arrival_minutes(&refs2, &p); + assert!(est2.iter().all(|e| e.line_group_cd == Some(100))); + } + + #[test] + fn speed_profile_splits_within_pass_through_segment() { + let p = EstimationParams::default(); + + // 始点→通過→終点。通過駅で line_cd が変わる直通区間。 + // どちらも在来線(普通)。 + let mut slow = three_collinear_stations(); + slow[1].pass = Some(1); + slow[2].line_cd = 200; // 直通で line_cd が変わる + let slow_refs: Vec<&Station> = slow.iter().collect(); + let slow_est = estimate_arrival_minutes(&slow_refs, &p); + + // 後半サブ区間(通過→終点)だけ高速種別(kind != 0 → 100km/h)にする。 + let mut fast = three_collinear_stations(); + fast[1].pass = Some(1); + fast[2].line_cd = 200; + fast[2].kind = Some(1); // 速達種別 → 後半サブ区間の v_max を上げる + let fast_refs: Vec<&Station> = fast.iter().collect(); + let fast_est = estimate_arrival_minutes(&fast_refs, &p); + + // 後半サブ区間が速くなったぶん、終点到着が早くなる(=区間ごとに速度が効いている)。 + assert!( + fast_est[2].cumulative_minutes < slow_est[2].cumulative_minutes, + "fast {} should be < slow {}", + fast_est[2].cumulative_minutes, + slow_est[2].cumulative_minutes + ); + // 通過駅(前半サブ区間のみ)の通過時刻は速度を変えていないので不変。 + approx( + fast_est[1].cumulative_minutes, + slow_est[1].cumulative_minutes, + ); + } + + #[test] + fn average_distance_meters_calibrates_detour_instead_of_clamping() { + let p = EstimationParams::default(); + // 両毛線 伊勢崎→国定 相当: 直線約 5.65km、average_distance = 4866.8(メートル)。 + // メートルを km と誤解釈すると α が 4866.8/5.65 → 上限 1.6 に張り付き、 + // 実乗車時間(5〜6分)より大幅に長い約 6.9 分と推定されてしまう。 + let a = station(1, 11341, 36.326849, 139.193704, Some(4866.8)); + let b = station(2, 11341, 36.359018, 139.242463, Some(4866.8)); + let stations = vec![a, b]; + let refs: Vec<&Station> = stations.iter().collect(); + let est = estimate_arrival_minutes(&refs, &p); + + // km 換算後は α = 4.8668 / 5.65 < 1 → detour_min の 1.0 でクランプされ、 + // みなし走行距離は直線距離そのものになる。 + let straight_m = haversine_distance(36.326849, 139.193704, 36.359018, 139.242463); + let v_kmh = 80.0; // 在来線・普通(kind=None) + let expected = segment_run_minutes(straight_m, v_kmh, &p); + approx(est[1].cumulative_minutes, expected); + // 実乗車時間は 5〜6 分。 + assert!( + est[1].cumulative_minutes > 4.5 && est[1].cumulative_minutes < 6.5, + "got {}", + est[1].cumulative_minutes + ); + } + + #[test] + fn oedo_line_segment_matches_real_travel_time() { + let p = EstimationParams::default(); + // 都営大江戸線 落合南長崎→光が丘(各駅停車のみの区間)。 + // 実座標・実データ値(average_distance = 1066.84m、地下鉄 line_type=3)。 + // 実乗車時間: 新江古田 2分 / 練馬 5分 / 豊島園 7分 / 練馬春日町 9分 / 光が丘 11分。 + let coords = [ + (35.723608, 139.683303), // 落合南長崎 + (35.732538, 139.670653), // 新江古田 + (35.737404, 139.65477), // 練馬 + (35.742567043044, 139.64894845621), // 豊島園 + (35.751452, 139.640236), // 練馬春日町 + (35.758526, 139.628603), // 光が丘 + ]; + let stations: Vec = coords + .iter() + .enumerate() + .map(|(i, &(lat, lon))| { + let mut s = station(i as i32 + 1, 99301, lat, lon, Some(1066.84)); + s.line_type = Some(LINE_TYPE_SUBWAY); + s + }) + .collect(); + let refs: Vec<&Station> = stations.iter().collect(); + let est = estimate_arrival_minutes(&refs, &p); + + let real = [2.0, 5.0, 7.0, 9.0, 11.0]; + for (e, r) in est[1..].iter().zip(real.iter()) { + assert!( + (e.cumulative_minutes - r).abs() < 1.0, + "station_cd {}: est {} vs real {}", + e.station_cd, + e.cumulative_minutes, + r + ); + } + } + + /// GTFS インポート後のバス停を再現する(line_type=3 は GTFS route_type のバス、 + /// kind=7 は TrainTypeKind::BusRoute、average_distance は無し)。 + fn bus_station(station_cd: i32, line_cd: i32, lat: f64, lon: f64) -> Station { + let mut s = station(station_cd, line_cd, lat, lon, None); + s.transport_type = TransportType::Bus; + s.line_type = Some(3); + s.kind = Some(7); + s + } + + #[test] + fn bus_ike65_dense_stops_match_real_travel_time() { + let p = EstimationParams::default(); + // 都営バス池65 落合南長崎駅前→目白駅前相当: 停留所間隔約 300m × 7 区間。 + // 実乗車時間は約 10 分(表定速度 約13km/h)。0.0027 度 ≈ 300m。 + let stations: Vec = (0..8) + .map(|i| bus_station(i + 1, 100_000_001, 35.72 + 0.0027 * i as f64, 139.69)) + .collect(); + let refs: Vec<&Station> = stations.iter().collect(); + let est = estimate_arrival_minutes(&refs, &p); + + let total = est[7].cumulative_minutes; + assert!(total > 9.0 && total < 11.0, "got {total}"); + } + + #[test] + fn bus_long_segment_does_not_cruise_at_rail_speed() { + let p = EstimationParams::default(); + // 停留所間隔 3km の直行区間。地下鉄扱い(75km/h × 1.2 = 90km/h)のままだと + // 約 3.4 分と過小評価される。バス上限 50km/h では約 5.7 分。 + let stations = vec![ + bus_station(1, 100_000_001, 35.72, 139.69), + bus_station(2, 100_000_001, 35.747, 139.69), // 0.027 度 ≈ 3km + ]; + let refs: Vec<&Station> = stations.iter().collect(); + let est = estimate_arrival_minutes(&refs, &p); + + let t = est[1].cumulative_minutes; + assert!((4.5..7.5).contains(&t), "got {t}"); + } + + #[test] + fn bus_kind_does_not_get_express_multiplier() { + let p = EstimationParams::default(); + // kind=7(BusRoute) は優等種別ではないので ×1.2 が掛かってはいけない。 + let make = |kind: Option| -> f64 { + let mut a = bus_station(1, 100_000_001, 35.72, 139.69); + let mut b = bus_station(2, 100_000_001, 35.747, 139.69); + a.kind = kind; + b.kind = kind; + let stations = vec![a, b]; + let refs: Vec<&Station> = stations.iter().collect(); + estimate_arrival_minutes(&refs, &p)[1].cumulative_minutes + }; + approx(make(Some(7)), make(None)); + } + + /// 半径約 1.1km の円周上に等間隔で並ぶ n 駅の合成環状路線を作る(station_cd は 1..=n)。 + fn ring_stations(n: usize) -> Vec { + (0..n) + .map(|i| { + let theta = 2.0 * std::f64::consts::PI * i as f64 / n as f64; + let lat = 35.0 + 0.01 * theta.cos(); + let lon = 139.0 + 0.01 * theta.sin() / 35.0_f64.to_radians().cos(); + station(i as i32 + 1, 500, lat, lon, None) + }) + .collect() + } + + /// 山手線 line_group_cd 363 の格納順(大崎→…→高輪ゲートウェイ→品川)と実座標。 + /// average_distance は実データ値(1093.74m)。 + fn yamanote_stations() -> Vec { + let coords = [ + (1130201, 35.619772, 139.728439), // 大崎 + (1130202, 35.625974, 139.723822), // 五反田 + (1130203, 35.633923, 139.715775), // 目黒 + (1130204, 35.646685, 139.71007), // 恵比寿 + (1130205, 35.658871, 139.701238), // 渋谷 + (1130206, 35.670646, 139.702592), // 原宿 + (1130207, 35.683061, 139.702042), // 代々木 + (1130208, 35.689729, 139.700464), // 新宿 + (1130209, 35.700875, 139.700261), // 新大久保 + (1130210, 35.712677, 139.703715), // 高田馬場 + (1130211, 35.720476, 139.706228), // 目白 + (1130212, 35.730256, 139.711086), // 池袋 + (1130213, 35.731412, 139.728584), // 大塚 + (1130214, 35.733445, 139.739303), // 巣鴨 + (1130215, 35.736825, 139.748053), // 駒込 + (1130216, 35.737781, 139.761229), // 田端 + (1130217, 35.731954, 139.766857), // 西日暮里 + (1130218, 35.727908, 139.771287), // 日暮里 + (1130219, 35.721484, 139.778015), // 鶯谷 + (1130220, 35.71379, 139.777043), // 上野 + (1130221, 35.707282, 139.774727), // 御徒町 + (1130222, 35.698619, 139.773288), // 秋葉原 + (1130223, 35.691173, 139.770641), // 神田 + (1130224, 35.681391, 139.766103), // 東京 + (1130225, 35.675441, 139.763806), // 有楽町 + (1130226, 35.666195, 139.758587), // 新橋 + (1130227, 35.655391, 139.757135), // 浜松町 + (1130228, 35.645736, 139.747575), // 田町 + (1130230, 35.6355, 139.7407), // 高輪ゲートウェイ + (1130229, 35.62876, 139.738999), // 品川 + ]; + coords + .iter() + .map(|&(cd, lat, lon)| { + let mut s = station(cd, 11302, lat, lon, Some(1093.73663)); + s.line_group_cd = Some(363); + s + }) + .collect() + } + + #[test] + fn is_circular_route_detects_yamanote_ring() { + let stations = yamanote_stations(); + let refs: Vec<&Station> = stations.iter().collect(); + assert!(is_circular_route(&refs)); + } + + #[test] + fn is_circular_route_rejects_linear_line() { + // 直線 8 駅(約 1.8km 間隔)。端点間 12km 超なので環状ではない。 + let stations: Vec = (0..8) + .map(|i| station(i + 1, 100, 35.0 + 0.016 * i as f64, 139.0, None)) + .collect(); + let refs: Vec<&Station> = stations.iter().collect(); + assert!(!is_circular_route(&refs)); + } + + #[test] + fn is_circular_route_rejects_small_ring() { + // 幾何的には環状でも最小駅数未満なら対象外。 + let stations = ring_stations(5); + let refs: Vec<&Station> = stations.iter().collect(); + assert!(!is_circular_route(&refs)); + } + + #[test] + fn is_circular_route_rejects_closed_loop_with_duplicate_endpoint() { + // 先頭駅が末尾にも重複格納された「閉じた」ループ(Port Liner 型)は + // ラップすると閉じ駅が二重になるため環状扱いしない。 + let mut stations = ring_stations(10); + let mut closing = stations[0].clone(); + closing.e_sort = 11; + stations.push(closing); + let refs: Vec<&Station> = stations.iter().collect(); + assert!(!is_circular_route(&refs)); + } + + #[test] + fn is_circular_route_rejects_discontinuous_order() { + // 近鉄奈良線型: 直線に進んだ後、格納順の末尾に始点近くの別線駅が連なる。 + // シームは短いが内部に巨大な飛びがあるため環状ではない。 + let mut stations: Vec = (0..8) + .map(|i| station(i + 1, 100, 35.0, 139.0 + 0.011 * i as f64, None)) + .collect(); + // 始点から約 200m の位置に「飛び」で戻ってくる駅を追加。 + stations.push(station(9, 100, 35.0018, 139.0, None)); + let refs: Vec<&Station> = stations.iter().collect(); + assert!(!is_circular_route(&refs)); + } + + #[test] + fn circular_arc_directed_wraps_seam() { + let stations = ring_stations(10); + let refs: Vec<&Station> = stations.iter().collect(); + + // 格納順の向きのままシームを跨いでラップする(反転しない)。 + let arc = select_circular_arc(&refs, 8, 2, true); + let cds: Vec = arc.iter().map(|s| s.station_cd).collect(); + assert_eq!(cds, vec![9, 10, 1, 2, 3]); + + // シームを跨がない場合は通常のスライス。 + let arc = select_circular_arc(&refs, 2, 8, true); + let cds: Vec = arc.iter().map(|s| s.station_cd).collect(); + assert_eq!(cds, vec![3, 4, 5, 6, 7, 8, 9]); + } + + #[test] + fn circular_arc_undirected_picks_shorter_arc() { + let stations = ring_stations(10); + let refs: Vec<&Station> = stations.iter().collect(); + + // 順方向にラップする 3 駅の弧が最短(逆方向は 9 駅)。 + let arc = select_circular_arc(&refs, 9, 1, false); + let cds: Vec = arc.iter().map(|s| s.station_cd).collect(); + assert_eq!(cds, vec![10, 1, 2]); + + // 対称ケース: 逆方向にラップする 3 駅の弧が最短。 + let arc = select_circular_arc(&refs, 1, 9, false); + let cds: Vec = arc.iter().map(|s| s.station_cd).collect(); + assert_eq!(cds, vec![2, 1, 10]); + } + + #[test] + fn yamanote_tamachi_to_shibuya_crosses_seam() { + // バグ再現回帰: 外回り 田町→渋谷 は品川・大崎経由の 8 駅(実乗車時間 約15分)。 + // 修正前は格納順の継ぎ目(品川⇔大崎)を跨げず、東京・池袋経由の + // 24 駅の逆側の弧が返っていた。 + let p = EstimationParams::default(); + let stations = yamanote_stations(); + let refs: Vec<&Station> = stations.iter().collect(); + assert!(is_circular_route(&refs)); + + let tamachi = 27; // 田町 + let shibuya = 4; // 渋谷 + let arc = select_circular_arc(&refs, tamachi, shibuya, true); + let cds: Vec = arc.iter().map(|s| s.station_cd).collect(); + assert_eq!( + cds, + vec![1130228, 1130230, 1130229, 1130201, 1130202, 1130203, 1130204, 1130205], + ); + + let est = estimate_arrival_minutes(&arc, &p); + assert!(est + .windows(2) + .all(|w| w[1].cumulative_minutes > w[0].cumulative_minutes)); + let total = est.last().unwrap().cumulative_minutes; + assert!((12.0..18.0).contains(&total), "got {total}"); + } + + #[test] + fn empty_input_returns_empty() { + let p = EstimationParams::default(); + assert!(estimate_arrival_minutes(&[], &p).is_empty()); + } +} diff --git a/stationapi/src/domain/repository/station_repository.rs b/stationapi/src/domain/repository/station_repository.rs index 0e624cc3..a2544c18 100644 --- a/stationapi/src/domain/repository/station_repository.rs +++ b/stationapi/src/domain/repository/station_repository.rs @@ -1,544 +1,560 @@ -use async_trait::async_trait; - -use crate::domain::{ - entity::{gtfs::TransportType, station::Station}, - error::DomainError, -}; - -#[async_trait] -pub trait StationRepository: Send + Sync + 'static { - async fn find_by_id(&self, id: u32) -> Result, DomainError>; - async fn get_by_id_vec(&self, ids: &[u32]) -> Result, DomainError>; - async fn get_by_line_id( - &self, - line_id: u32, - station_id: Option, - direction_id: Option, - ) -> Result, DomainError>; - async fn get_by_line_id_vec(&self, line_ids: &[u32]) -> Result, DomainError>; - async fn get_by_line_id_vec_with_group_stations( - &self, - line_ids: &[u32], - ) -> Result, DomainError>; - async fn get_by_station_group_id( - &self, - station_group_id: u32, - ) -> Result, DomainError>; - async fn get_by_station_group_id_vec( - &self, - station_group_id_vec: &[u32], - ) -> Result, DomainError>; - async fn get_by_station_group_id_vec_no_types( - &self, - station_group_id_vec: &[u32], - ) -> Result, DomainError>; - async fn get_by_coordinates( - &self, - latitude: f64, - longitude: f64, - limit: Option, - transport_type: Option, - ) -> Result, DomainError>; - async fn get_by_name( - &self, - station_name: String, - limit: Option, - from_station_group_id: Option, - transport_type: Option, - ) -> Result, DomainError>; - async fn get_by_line_group_id(&self, line_group_id: u32) -> Result, DomainError>; - async fn get_by_line_group_id_vec( - &self, - line_group_ids: &[u32], - ) -> Result, DomainError>; - async fn get_bus_stops_near_stations( - &self, - coords: &[(u32, f64, f64)], // (station_g_cd, lat, lon) - limit_per_station: u32, - ) -> Result, DomainError>; - async fn get_route_stops( - &self, - from_station_id: u32, - to_station_id: u32, - via_line_id: Option, - ) -> Result, DomainError>; -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::proto::StopCondition; - use std::collections::HashMap; - - // モック実装 - pub struct MockStationRepository { - stations: HashMap, - } - - impl MockStationRepository { - pub fn new() -> Self { - let mut stations = HashMap::new(); - - // テストデータを作成 - let station1 = create_test_station(1, "東京駅", 1001, 35.681236, 139.767125); - let station2 = create_test_station(2, "新宿駅", 1002, 35.690921, 139.700258); - let station3 = create_test_station(3, "渋谷駅", 1003, 35.659518, 139.700464); - let station4 = create_test_station(4, "品川駅", 1001, 35.630152, 139.740570); - - stations.insert(1, station1); - stations.insert(2, station2); - stations.insert(3, station3); - stations.insert(4, station4); - - Self { stations } - } - } - - #[async_trait] - impl StationRepository for MockStationRepository { - async fn find_by_id(&self, id: u32) -> Result, DomainError> { - Ok(self.stations.get(&id).cloned()) - } - - async fn get_by_id_vec(&self, ids: &[u32]) -> Result, DomainError> { - let mut result = Vec::new(); - for id in ids { - if let Some(station) = self.stations.get(id) { - result.push(station.clone()); - } - } - Ok(result) - } - - async fn get_by_line_id( - &self, - line_id: u32, - _station_id: Option, - _direction_id: Option, - ) -> Result, DomainError> { - let result: Vec = self - .stations - .values() - .filter(|station| station.line_cd == line_id as i32) - .cloned() - .collect(); - Ok(result) - } - - async fn get_by_line_id_vec(&self, line_ids: &[u32]) -> Result, DomainError> { - let result: Vec = self - .stations - .values() - .filter(|station| line_ids.contains(&(station.line_cd as u32))) - .cloned() - .collect(); - Ok(result) - } - - async fn get_by_line_id_vec_with_group_stations( - &self, - line_ids: &[u32], - ) -> Result, DomainError> { - let group_ids: Vec = self - .stations - .values() - .filter(|s| line_ids.contains(&(s.line_cd as u32))) - .map(|s| s.station_g_cd) - .collect(); - let result: Vec = self - .stations - .values() - .filter(|s| group_ids.contains(&s.station_g_cd)) - .cloned() - .collect(); - Ok(result) - } - - async fn get_by_station_group_id( - &self, - station_group_id: u32, - ) -> Result, DomainError> { - let result: Vec = self - .stations - .values() - .filter(|station| station.station_g_cd == station_group_id as i32) - .cloned() - .collect(); - Ok(result) - } - - async fn get_by_station_group_id_vec( - &self, - station_group_id_vec: &[u32], - ) -> Result, DomainError> { - let result: Vec = self - .stations - .values() - .filter(|station| station_group_id_vec.contains(&(station.station_g_cd as u32))) - .cloned() - .collect(); - Ok(result) - } - - async fn get_by_station_group_id_vec_no_types( - &self, - station_group_id_vec: &[u32], - ) -> Result, DomainError> { - self.get_by_station_group_id_vec(station_group_id_vec).await - } - - async fn get_by_coordinates( - &self, - latitude: f64, - longitude: f64, - limit: Option, - transport_type: Option, - ) -> Result, DomainError> { - let mut result: Vec = self - .stations - .values() - .filter(|station| { - transport_type - .as_ref() - .map_or(true, |tt| station.transport_type == *tt) - }) - .map(|station| { - let mut s = station.clone(); - let distance = ((station.lat - latitude).powi(2) - + (station.lon - longitude).powi(2)) - .sqrt(); - s.distance = Some(distance); - s - }) - .collect(); - - // 距離でソート - result.sort_by(|a, b| a.distance.partial_cmp(&b.distance).unwrap()); - - // 制限があれば適用 - if let Some(limit) = limit { - result.truncate(limit as usize); - } - - Ok(result) - } - - async fn get_bus_stops_near_stations( - &self, - coords: &[(u32, f64, f64)], - limit_per_station: u32, - ) -> Result, DomainError> { - let mut result = Vec::new(); - for &(source_g_cd, lat, lon) in coords { - let stops = self - .get_by_coordinates(lat, lon, Some(limit_per_station), Some(TransportType::Bus)) - .await?; - for stop in stops { - result.push((source_g_cd, stop)); - } - } - Ok(result) - } - - async fn get_by_name( - &self, - station_name: String, - limit: Option, - _from_station_group_id: Option, - transport_type: Option, - ) -> Result, DomainError> { - let mut result: Vec = self - .stations - .values() - .filter(|station| { - station.station_name.contains(&station_name) - && transport_type - .as_ref() - .map_or(true, |tt| station.transport_type == *tt) - }) - .cloned() - .collect(); - - if let Some(limit) = limit { - result.truncate(limit as usize); - } - - Ok(result) - } - - async fn get_by_line_group_id( - &self, - line_group_id: u32, - ) -> Result, DomainError> { - let result: Vec = self - .stations - .values() - .filter(|station| station.line_group_cd == Some(line_group_id as i32)) - .cloned() - .collect(); - Ok(result) - } - - async fn get_by_line_group_id_vec( - &self, - line_group_ids: &[u32], - ) -> Result, DomainError> { - let result: Vec = self - .stations - .values() - .filter(|station| { - station - .line_group_cd - .map(|v| line_group_ids.contains(&(v as u32))) - .unwrap_or(false) - }) - .cloned() - .collect(); - Ok(result) - } - - async fn get_route_stops( - &self, - from_station_id: u32, - to_station_id: u32, - via_line_id: Option, - ) -> Result, DomainError> { - // シンプルなルート検索のモック実装。via_line_id が指定されている場合は - // 両駅がその路線に属していることを条件にする。 - let mut result = Vec::new(); - - let from_station = self.stations.get(&from_station_id); - let to_station = self.stations.get(&to_station_id); - - if let Some(required_line) = via_line_id { - let line_match = |s: &Station| s.line_cd as u32 == required_line; - if !from_station.map_or(false, line_match) || !to_station.map_or(false, line_match) - { - return Ok(result); - } - } - - if let Some(from_station) = from_station { - result.push(from_station.clone()); - } - - if let Some(to_station) = to_station { - if from_station_id != to_station_id { - result.push(to_station.clone()); - } - } - - Ok(result) - } - } - - // テスト用のStation作成ヘルパー関数 - fn create_test_station( - station_cd: i32, - station_name: &str, - line_cd: i32, - lat: f64, - lon: f64, - ) -> Station { - Station::new( - station_cd, - station_cd, // station_g_cd - station_name.to_string(), - format!("{station_name}_k"), - Some(format!("{station_name}_r")), - Some(format!("{station_name}_zh")), - Some(format!("{station_name}_ko")), - vec![], - None, - None, - None, - None, - None, - line_cd, - None, - vec![], - 13, // 東京都 - "100-0000".to_string(), - "東京都".to_string(), - lon, - lat, - "20000101".to_string(), - "99991231".to_string(), - 0, - 0, - StopCondition::All, - None, - false, - None, - Some(1), - Some("山手線".to_string()), - Some("やまのてせん".to_string()), - Some("Yamanote Line".to_string()), - Some("Yamanote Line".to_string()), - Some("山手线".to_string()), - Some("야마노테선".to_string()), - Some("#00AC9A".to_string()), - Some(1), - Some("JY".to_string()), - None, - None, - None, - Some("#00AC9A".to_string()), - None, - None, - None, - Some("circle".to_string()), - None, - None, - None, - Some(1000), - Some(5.5), - Some(0), - Some(1), - Some(1), - Some(1), - Some("普通".to_string()), - Some("ふつう".to_string()), - Some("Local".to_string()), - Some("普通".to_string()), - Some("보통".to_string()), - Some("#000000".to_string()), - Some(0), - Some(1), - TransportType::Rail, - ) - } - - #[tokio::test] - async fn test_find_by_id_existing() { - let repo = MockStationRepository::new(); - let result = repo.find_by_id(1).await.unwrap(); - assert!(result.is_some()); - let station = result.unwrap(); - assert_eq!(station.station_cd, 1); - assert_eq!(station.station_name, "東京駅"); - } - - #[tokio::test] - async fn test_find_by_id_not_found() { - let repo = MockStationRepository::new(); - let result = repo.find_by_id(999).await.unwrap(); - assert!(result.is_none()); - } - - #[tokio::test] - async fn test_get_by_id_vec() { - let repo = MockStationRepository::new(); - let ids = vec![1, 3, 999]; // 999は存在しない - let result = repo.get_by_id_vec(&ids).await.unwrap(); - assert_eq!(result.len(), 2); - assert!(result.iter().any(|s| s.station_cd == 1)); - assert!(result.iter().any(|s| s.station_cd == 3)); - } - - #[tokio::test] - async fn test_get_by_line_id() { - let repo = MockStationRepository::new(); - let result = repo.get_by_line_id(1001, None, None).await.unwrap(); - assert_eq!(result.len(), 2); // 東京駅と品川駅 - assert!(result.iter().all(|s| s.line_cd == 1001)); - } - - #[tokio::test] - async fn test_get_by_station_group_id() { - let repo = MockStationRepository::new(); - let result = repo.get_by_station_group_id(1).await.unwrap(); - assert_eq!(result.len(), 1); - assert_eq!(result[0].station_cd, 1); - } - - #[tokio::test] - async fn test_get_by_station_group_id_vec() { - let repo = MockStationRepository::new(); - let group_ids = vec![1, 2]; - let result = repo.get_by_station_group_id_vec(&group_ids).await.unwrap(); - assert_eq!(result.len(), 2); - } - - #[tokio::test] - async fn test_get_by_coordinates() { - let repo = MockStationRepository::new(); - // 東京駅付近の座標 - let result = repo - .get_by_coordinates(35.681236, 139.767125, Some(2), None) - .await - .unwrap(); - assert!(result.len() <= 2); - assert!(result[0].distance.is_some()); - } - - #[tokio::test] - async fn test_get_by_name() { - let repo = MockStationRepository::new(); - let result = repo - .get_by_name("東京".to_string(), None, None, None) - .await - .unwrap(); - assert_eq!(result.len(), 1); - assert_eq!(result[0].station_name, "東京駅"); - } - - #[tokio::test] - async fn test_get_by_name_with_limit() { - let repo = MockStationRepository::new(); - let result = repo - .get_by_name("駅".to_string(), Some(2), None, None) - .await - .unwrap(); - assert!(result.len() <= 2); - } - - #[tokio::test] - async fn test_get_by_line_group_id() { - let repo = MockStationRepository::new(); - let result = repo.get_by_line_group_id(1000).await.unwrap(); - assert_eq!(result.len(), 4); // すべての駅がline_group_cd = 1000に設定されている - } - - #[tokio::test] - async fn test_get_route_stops() { - let repo = MockStationRepository::new(); - let result = repo.get_route_stops(1, 2, None).await.unwrap(); - assert_eq!(result.len(), 2); - assert_eq!(result[0].station_cd, 1); - assert_eq!(result[1].station_cd, 2); - } - - #[tokio::test] - async fn test_get_route_stops_same_station() { - let repo = MockStationRepository::new(); - let result = repo.get_route_stops(1, 1, None).await.unwrap(); - assert_eq!(result.len(), 1); - assert_eq!(result[0].station_cd, 1); - } - - #[tokio::test] - async fn test_get_route_stops_not_found() { - let repo = MockStationRepository::new(); - let result = repo.get_route_stops(999, 1000, None).await.unwrap(); - assert_eq!(result.len(), 0); - } - - #[tokio::test] - async fn test_get_route_stops_with_via_line_id_match() { - let repo = MockStationRepository::new(); - // 東京駅(1) と 品川駅(4) は line_cd=1001 で一致する - let result = repo.get_route_stops(1, 4, Some(1001)).await.unwrap(); - assert_eq!(result.len(), 2); - assert_eq!(result[0].station_cd, 1); - assert_eq!(result[1].station_cd, 4); - } - - #[tokio::test] - async fn test_get_route_stops_with_via_line_id_mismatch() { - let repo = MockStationRepository::new(); - // line_cd が一致しないためルートは返さない - let result = repo.get_route_stops(1, 2, Some(1001)).await.unwrap(); - assert!(result.is_empty()); - } -} +use async_trait::async_trait; + +use crate::domain::{ + entity::{gtfs::TransportType, station::Station}, + error::DomainError, +}; + +#[async_trait] +pub trait StationRepository: Send + Sync + 'static { + async fn find_by_id(&self, id: u32) -> Result, DomainError>; + async fn get_by_id_vec(&self, ids: &[u32]) -> Result, DomainError>; + async fn get_by_line_id( + &self, + line_id: u32, + station_id: Option, + direction_id: Option, + ) -> Result, DomainError>; + async fn get_by_line_id_vec(&self, line_ids: &[u32]) -> Result, DomainError>; + async fn get_by_line_id_vec_with_group_stations( + &self, + line_ids: &[u32], + ) -> Result, DomainError>; + async fn get_by_station_group_id( + &self, + station_group_id: u32, + ) -> Result, DomainError>; + async fn get_by_station_group_id_vec( + &self, + station_group_id_vec: &[u32], + ) -> Result, DomainError>; + async fn get_by_station_group_id_vec_no_types( + &self, + station_group_id_vec: &[u32], + ) -> Result, DomainError>; + async fn get_by_coordinates( + &self, + latitude: f64, + longitude: f64, + limit: Option, + transport_type: Option, + ) -> Result, DomainError>; + async fn get_by_name( + &self, + station_name: String, + limit: Option, + from_station_group_id: Option, + transport_type: Option, + ) -> Result, DomainError>; + async fn get_by_line_group_id(&self, line_group_id: u32) -> Result, DomainError>; + async fn get_by_line_group_id_vec( + &self, + line_group_ids: &[u32], + ) -> Result, DomainError>; + async fn get_bus_stops_near_stations( + &self, + coords: &[(u32, f64, f64)], // (station_g_cd, lat, lon) + limit_per_station: u32, + ) -> Result, DomainError>; + async fn get_route_stops( + &self, + from_station_id: u32, + to_station_id: u32, + via_line_ids: &[u32], + ) -> Result, DomainError>; + async fn get_route_stops_by_station_cd( + &self, + from_station_cd: u32, + to_station_cd: u32, + via_line_ids: &[u32], + direction_id: Option, + ) -> Result, DomainError>; +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::proto::StopCondition; + use std::collections::HashMap; + + // モック実装 + pub struct MockStationRepository { + stations: HashMap, + } + + impl MockStationRepository { + pub fn new() -> Self { + let mut stations = HashMap::new(); + + // テストデータを作成 + let station1 = create_test_station(1, "東京駅", 1001, 35.681236, 139.767125); + let station2 = create_test_station(2, "新宿駅", 1002, 35.690921, 139.700258); + let station3 = create_test_station(3, "渋谷駅", 1003, 35.659518, 139.700464); + let station4 = create_test_station(4, "品川駅", 1001, 35.630152, 139.740570); + + stations.insert(1, station1); + stations.insert(2, station2); + stations.insert(3, station3); + stations.insert(4, station4); + + Self { stations } + } + } + + #[async_trait] + impl StationRepository for MockStationRepository { + async fn find_by_id(&self, id: u32) -> Result, DomainError> { + Ok(self.stations.get(&id).cloned()) + } + + async fn get_by_id_vec(&self, ids: &[u32]) -> Result, DomainError> { + let mut result = Vec::new(); + for id in ids { + if let Some(station) = self.stations.get(id) { + result.push(station.clone()); + } + } + Ok(result) + } + + async fn get_by_line_id( + &self, + line_id: u32, + _station_id: Option, + _direction_id: Option, + ) -> Result, DomainError> { + let result: Vec = self + .stations + .values() + .filter(|station| station.line_cd == line_id as i32) + .cloned() + .collect(); + Ok(result) + } + + async fn get_by_line_id_vec(&self, line_ids: &[u32]) -> Result, DomainError> { + let result: Vec = self + .stations + .values() + .filter(|station| line_ids.contains(&(station.line_cd as u32))) + .cloned() + .collect(); + Ok(result) + } + + async fn get_by_line_id_vec_with_group_stations( + &self, + line_ids: &[u32], + ) -> Result, DomainError> { + let group_ids: Vec = self + .stations + .values() + .filter(|s| line_ids.contains(&(s.line_cd as u32))) + .map(|s| s.station_g_cd) + .collect(); + let result: Vec = self + .stations + .values() + .filter(|s| group_ids.contains(&s.station_g_cd)) + .cloned() + .collect(); + Ok(result) + } + + async fn get_by_station_group_id( + &self, + station_group_id: u32, + ) -> Result, DomainError> { + let result: Vec = self + .stations + .values() + .filter(|station| station.station_g_cd == station_group_id as i32) + .cloned() + .collect(); + Ok(result) + } + + async fn get_by_station_group_id_vec( + &self, + station_group_id_vec: &[u32], + ) -> Result, DomainError> { + let result: Vec = self + .stations + .values() + .filter(|station| station_group_id_vec.contains(&(station.station_g_cd as u32))) + .cloned() + .collect(); + Ok(result) + } + + async fn get_by_station_group_id_vec_no_types( + &self, + station_group_id_vec: &[u32], + ) -> Result, DomainError> { + self.get_by_station_group_id_vec(station_group_id_vec).await + } + + async fn get_by_coordinates( + &self, + latitude: f64, + longitude: f64, + limit: Option, + transport_type: Option, + ) -> Result, DomainError> { + let mut result: Vec = self + .stations + .values() + .filter(|station| { + transport_type + .as_ref() + .map_or(true, |tt| station.transport_type == *tt) + }) + .map(|station| { + let mut s = station.clone(); + let distance = ((station.lat - latitude).powi(2) + + (station.lon - longitude).powi(2)) + .sqrt(); + s.distance = Some(distance); + s + }) + .collect(); + + // 距離でソート + result.sort_by(|a, b| a.distance.partial_cmp(&b.distance).unwrap()); + + // 制限があれば適用 + if let Some(limit) = limit { + result.truncate(limit as usize); + } + + Ok(result) + } + + async fn get_bus_stops_near_stations( + &self, + coords: &[(u32, f64, f64)], + limit_per_station: u32, + ) -> Result, DomainError> { + let mut result = Vec::new(); + for &(source_g_cd, lat, lon) in coords { + let stops = self + .get_by_coordinates(lat, lon, Some(limit_per_station), Some(TransportType::Bus)) + .await?; + for stop in stops { + result.push((source_g_cd, stop)); + } + } + Ok(result) + } + + async fn get_by_name( + &self, + station_name: String, + limit: Option, + _from_station_group_id: Option, + transport_type: Option, + ) -> Result, DomainError> { + let mut result: Vec = self + .stations + .values() + .filter(|station| { + station.station_name.contains(&station_name) + && transport_type + .as_ref() + .map_or(true, |tt| station.transport_type == *tt) + }) + .cloned() + .collect(); + + if let Some(limit) = limit { + result.truncate(limit as usize); + } + + Ok(result) + } + + async fn get_by_line_group_id( + &self, + line_group_id: u32, + ) -> Result, DomainError> { + let result: Vec = self + .stations + .values() + .filter(|station| station.line_group_cd == Some(line_group_id as i32)) + .cloned() + .collect(); + Ok(result) + } + + async fn get_by_line_group_id_vec( + &self, + line_group_ids: &[u32], + ) -> Result, DomainError> { + let result: Vec = self + .stations + .values() + .filter(|station| { + station + .line_group_cd + .map(|v| line_group_ids.contains(&(v as u32))) + .unwrap_or(false) + }) + .cloned() + .collect(); + Ok(result) + } + + async fn get_route_stops( + &self, + from_station_id: u32, + to_station_id: u32, + via_line_ids: &[u32], + ) -> Result, DomainError> { + let mut result = Vec::new(); + + let from_station = self.stations.get(&from_station_id); + let to_station = self.stations.get(&to_station_id); + + if !via_line_ids.is_empty() { + let line_match = |s: &Station| via_line_ids.contains(&(s.line_cd as u32)); + if !from_station.map_or(false, line_match) || !to_station.map_or(false, line_match) + { + return Ok(result); + } + } + + if let Some(from_station) = from_station { + result.push(from_station.clone()); + } + + if let Some(to_station) = to_station { + if from_station_id != to_station_id { + result.push(to_station.clone()); + } + } + + Ok(result) + } + + async fn get_route_stops_by_station_cd( + &self, + from_station_cd: u32, + to_station_cd: u32, + via_line_ids: &[u32], + _direction_id: Option, + ) -> Result, DomainError> { + self.get_route_stops(from_station_cd, to_station_cd, via_line_ids) + .await + } + } + + // テスト用のStation作成ヘルパー関数 + fn create_test_station( + station_cd: i32, + station_name: &str, + line_cd: i32, + lat: f64, + lon: f64, + ) -> Station { + Station::new( + station_cd, + station_cd, // station_g_cd + station_name.to_string(), + format!("{station_name}_k"), + Some(format!("{station_name}_r")), + Some(format!("{station_name}_zh")), + Some(format!("{station_name}_ko")), + vec![], + None, + None, + None, + None, + None, + line_cd, + None, + vec![], + 13, // 東京都 + "100-0000".to_string(), + "東京都".to_string(), + lon, + lat, + "20000101".to_string(), + "99991231".to_string(), + 0, + 0, + StopCondition::All, + None, + false, + None, + Some(1), + Some("山手線".to_string()), + Some("やまのてせん".to_string()), + Some("Yamanote Line".to_string()), + Some("Yamanote Line".to_string()), + Some("山手线".to_string()), + Some("야마노테선".to_string()), + Some("#00AC9A".to_string()), + Some(1), + Some("JY".to_string()), + None, + None, + None, + Some("#00AC9A".to_string()), + None, + None, + None, + Some("circle".to_string()), + None, + None, + None, + Some(1000), + Some(5.5), + Some(0), + Some(1), + Some(1), + Some(1), + Some("普通".to_string()), + Some("ふつう".to_string()), + Some("Local".to_string()), + Some("普通".to_string()), + Some("보통".to_string()), + Some("#000000".to_string()), + Some(0), + Some(1), + TransportType::Rail, + ) + } + + #[tokio::test] + async fn test_find_by_id_existing() { + let repo = MockStationRepository::new(); + let result = repo.find_by_id(1).await.unwrap(); + assert!(result.is_some()); + let station = result.unwrap(); + assert_eq!(station.station_cd, 1); + assert_eq!(station.station_name, "東京駅"); + } + + #[tokio::test] + async fn test_find_by_id_not_found() { + let repo = MockStationRepository::new(); + let result = repo.find_by_id(999).await.unwrap(); + assert!(result.is_none()); + } + + #[tokio::test] + async fn test_get_by_id_vec() { + let repo = MockStationRepository::new(); + let ids = vec![1, 3, 999]; // 999は存在しない + let result = repo.get_by_id_vec(&ids).await.unwrap(); + assert_eq!(result.len(), 2); + assert!(result.iter().any(|s| s.station_cd == 1)); + assert!(result.iter().any(|s| s.station_cd == 3)); + } + + #[tokio::test] + async fn test_get_by_line_id() { + let repo = MockStationRepository::new(); + let result = repo.get_by_line_id(1001, None, None).await.unwrap(); + assert_eq!(result.len(), 2); // 東京駅と品川駅 + assert!(result.iter().all(|s| s.line_cd == 1001)); + } + + #[tokio::test] + async fn test_get_by_station_group_id() { + let repo = MockStationRepository::new(); + let result = repo.get_by_station_group_id(1).await.unwrap(); + assert_eq!(result.len(), 1); + assert_eq!(result[0].station_cd, 1); + } + + #[tokio::test] + async fn test_get_by_station_group_id_vec() { + let repo = MockStationRepository::new(); + let group_ids = vec![1, 2]; + let result = repo.get_by_station_group_id_vec(&group_ids).await.unwrap(); + assert_eq!(result.len(), 2); + } + + #[tokio::test] + async fn test_get_by_coordinates() { + let repo = MockStationRepository::new(); + // 東京駅付近の座標 + let result = repo + .get_by_coordinates(35.681236, 139.767125, Some(2), None) + .await + .unwrap(); + assert!(result.len() <= 2); + assert!(result[0].distance.is_some()); + } + + #[tokio::test] + async fn test_get_by_name() { + let repo = MockStationRepository::new(); + let result = repo + .get_by_name("東京".to_string(), None, None, None) + .await + .unwrap(); + assert_eq!(result.len(), 1); + assert_eq!(result[0].station_name, "東京駅"); + } + + #[tokio::test] + async fn test_get_by_name_with_limit() { + let repo = MockStationRepository::new(); + let result = repo + .get_by_name("駅".to_string(), Some(2), None, None) + .await + .unwrap(); + assert!(result.len() <= 2); + } + + #[tokio::test] + async fn test_get_by_line_group_id() { + let repo = MockStationRepository::new(); + let result = repo.get_by_line_group_id(1000).await.unwrap(); + assert_eq!(result.len(), 4); // すべての駅がline_group_cd = 1000に設定されている + } + + #[tokio::test] + async fn test_get_route_stops() { + let repo = MockStationRepository::new(); + let result = repo.get_route_stops(1, 2, &[]).await.unwrap(); + assert_eq!(result.len(), 2); + assert_eq!(result[0].station_cd, 1); + assert_eq!(result[1].station_cd, 2); + } + + #[tokio::test] + async fn test_get_route_stops_same_station() { + let repo = MockStationRepository::new(); + let result = repo.get_route_stops(1, 1, &[]).await.unwrap(); + assert_eq!(result.len(), 1); + assert_eq!(result[0].station_cd, 1); + } + + #[tokio::test] + async fn test_get_route_stops_not_found() { + let repo = MockStationRepository::new(); + let result = repo.get_route_stops(999, 1000, &[]).await.unwrap(); + assert_eq!(result.len(), 0); + } + + #[tokio::test] + async fn test_get_route_stops_with_via_line_ids_match() { + let repo = MockStationRepository::new(); + // 東京駅(1) と 品川駅(4) は line_cd=1001 で一致する + let result = repo.get_route_stops(1, 4, &[1001]).await.unwrap(); + assert_eq!(result.len(), 2); + assert_eq!(result[0].station_cd, 1); + assert_eq!(result[1].station_cd, 4); + } + + #[tokio::test] + async fn test_get_route_stops_with_via_line_ids_mismatch() { + let repo = MockStationRepository::new(); + // line_cd が一致しないためルートは返さない + let result = repo.get_route_stops(1, 2, &[1001]).await.unwrap(); + assert!(result.is_empty()); + } +} diff --git a/stationapi/src/infrastructure/station_repository.rs b/stationapi/src/infrastructure/station_repository.rs index e7917477..99868af0 100644 --- a/stationapi/src/infrastructure/station_repository.rs +++ b/stationapi/src/infrastructure/station_repository.rs @@ -447,13 +447,31 @@ impl StationRepository for MyStationRepository { &self, from_station_id: u32, to_station_id: u32, - via_line_id: Option, + via_line_ids: &[u32], ) -> Result, DomainError> { let mut conn = self.pool.acquire().await?; InternalStationRepository::get_route_stops( from_station_id, to_station_id, - via_line_id, + via_line_ids, + &mut conn, + ) + .await + } + + async fn get_route_stops_by_station_cd( + &self, + from_station_cd: u32, + to_station_cd: u32, + via_line_ids: &[u32], + direction_id: Option, + ) -> Result, DomainError> { + let mut conn = self.pool.acquire().await?; + InternalStationRepository::get_route_stops_by_station_cd( + from_station_cd, + to_station_cd, + via_line_ids, + direction_id, &mut conn, ) .await @@ -533,19 +551,19 @@ impl InternalStationRepository { l.line_symbol3_shape, l.line_symbol4_shape, COALESCE(l.average_distance, 0.0)::DOUBLE PRECISION AS average_distance, - t.id AS type_id, - sst.id AS sst_id, - sst.type_cd, - sst.line_group_cd, - sst.pass, - t.type_name, - t.type_name_k, - t.type_name_r, - t.type_name_zh, - t.type_name_ko, - t.color, - t.direction, - t.kind, + t.id AS "type_id?", + sst.id AS "sst_id?", + sst.type_cd AS "type_cd?", + sst.line_group_cd AS "line_group_cd?", + sst.pass AS "pass?", + t.type_name AS "type_name?", + t.type_name_k AS "type_name_k?", + t.type_name_r AS "type_name_r?", + t.type_name_zh AS "type_name_zh?", + t.type_name_ko AS "type_name_ko?", + t.color AS "color?", + t.direction AS "direction?", + t.kind AS "kind?", s.transport_type FROM stations AS s JOIN lines AS l ON l.line_cd = s.line_cd @@ -1149,19 +1167,19 @@ impl InternalStationRepository { COALESCE(NULLIF(COALESCE(a.line_name_zh, l.line_name_zh), ''), NULL) AS line_name_zh, COALESCE(NULLIF(COALESCE(a.line_name_ko, l.line_name_ko), ''), NULL) AS line_name_ko, COALESCE(NULLIF(COALESCE(a.line_color_c, l.line_color_c), ''), NULL) AS line_color_c, - sst.id AS sst_id, - sst.type_cd, - sst.line_group_cd, - sst.pass, - t.id AS type_id, - t.type_name, - t.type_name_k, - t.type_name_r, - t.type_name_zh, - t.type_name_ko, - t.color, - t.direction, - t.kind, + sst.id AS "sst_id?", + sst.type_cd AS "type_cd?", + sst.line_group_cd AS "line_group_cd?", + sst.pass AS "pass?", + t.id AS "type_id?", + t.type_name AS "type_name?", + t.type_name_k AS "type_name_k?", + t.type_name_r AS "type_name_r?", + t.type_name_zh AS "type_name_zh?", + t.type_name_ko AS "type_name_ko?", + t.color AS "color?", + t.direction AS "direction?", + t.kind AS "kind?", s.transport_type FROM stations AS s @@ -1928,10 +1946,10 @@ impl InternalStationRepository { async fn get_route_stops( from_station_id: u32, to_station_id: u32, - via_line_id: Option, + via_line_ids: &[u32], conn: &mut PgConnection, ) -> Result, DomainError> { - let via_line_id = via_line_id.map(|id| id as i32); + let via_line_ids_i32: Vec = via_line_ids.iter().map(|&id| id as i32).collect(); let mut rows = sqlx::query_as!( StationRow, r#"WITH @@ -1958,7 +1976,7 @@ impl InternalStationRepository { FROM stations s1 WHERE s1.station_g_cd = $3 AND s1.e_status = 0 - AND ($5::int IS NULL OR s1.line_cd = $5) + AND (array_length($5::int[], 1) IS NULL OR s1.line_cd = ANY($5)) AND EXISTS ( SELECT 1 FROM stations s2 @@ -2074,7 +2092,7 @@ impl InternalStationRepository { to_station_id as i32, from_station_id as i32, to_station_id as i32, - via_line_id, + &via_line_ids_i32, ) .fetch_all(&mut *conn) .await?; @@ -2201,11 +2219,11 @@ impl InternalStationRepository { LEFT JOIN aliases AS a ON a.id = la.alias_cd WHERE sta.e_status = 0 - AND ($3::int IS NULL OR sta.line_cd = $3) + AND (array_length($3::int[], 1) IS NULL OR sta.line_cd = ANY($3)) ORDER BY sst.id"#, from_station_id as i32, to_station_id as i32, - via_line_id, + &via_line_ids_i32, ) .fetch_all(conn) .await?; @@ -2215,6 +2233,314 @@ impl InternalStationRepository { Ok(stations) } + + async fn get_route_stops_by_station_cd( + from_station_cd: u32, + to_station_cd: u32, + via_line_ids: &[u32], + direction_id: Option, + conn: &mut PgConnection, + ) -> Result, DomainError> { + // direction_id = 1 (上り) の場合、並び順を反転する + let reverse = matches!(direction_id, Some(1)); + let via_line_ids_i32: Vec = via_line_ids.iter().map(|&id| id as i32).collect(); + let untyped_order = if reverse { + "ORDER BY sta.e_sort DESC, sta.station_cd DESC" + } else { + "ORDER BY sta.e_sort ASC, sta.station_cd ASC" + }; + + let untyped_query = format!( + r#"WITH + from_cte AS ( + SELECT + s.station_cd, + s.line_cd + FROM + stations AS s + WHERE + s.station_cd = $1 + ), + to_cte AS ( + SELECT + s.station_cd, + s.line_cd + FROM + stations AS s + WHERE + s.station_cd = $2 + ), + common_lines AS ( + SELECT DISTINCT s1.line_cd + FROM stations s1 + WHERE s1.station_cd = $3 + AND s1.e_status = 0 + AND (array_length($5::int[], 1) IS NULL OR s1.line_cd = ANY($5)) + AND EXISTS ( + SELECT 1 + FROM stations s2 + WHERE s2.station_cd = $4 + AND s2.e_status = 0 + AND s2.line_cd = s1.line_cd + ) + ), + sst_cte_c1 AS ( + SELECT + sst.line_group_cd + FROM + station_station_types AS sst + JOIN from_cte ON sst.station_cd = from_cte.station_cd + WHERE + sst.pass <> 1 + ), + sst_cte_c2 AS ( + SELECT + sst.line_group_cd + FROM + station_station_types AS sst + JOIN to_cte ON sst.station_cd = to_cte.station_cd + WHERE + sst.pass <> 1 + ), + sst_cte AS ( + SELECT + sst.id, + sst.station_cd, + sst.type_cd, + sst.line_group_cd, + sst.pass + FROM + station_station_types AS sst + JOIN sst_cte_c1 ON sst.line_group_cd = sst_cte_c1.line_group_cd + JOIN sst_cte_c2 ON sst.line_group_cd = sst_cte_c2.line_group_cd + ) + SELECT + sta.station_cd, + sta.station_g_cd, + sta.station_name, + sta.station_name_k, + sta.station_name_r, + sta.station_name_rn, + sta.station_name_zh, + sta.station_name_ko, + sta.station_number1, + sta.station_number2, + sta.station_number3, + sta.station_number4, + sta.three_letter_code, + sta.line_cd, + sta.pref_cd, + sta.post, + sta.address, + sta.lon, + sta.lat, + sta.open_ymd, + sta.close_ymd, + sta.e_status, + sta.e_sort, + lin.company_cd, + COALESCE(NULLIF(COALESCE(a.line_name, lin.line_name), ''), NULL) AS line_name, + COALESCE(NULLIF(COALESCE(a.line_name_k, lin.line_name_k), ''), NULL) AS line_name_k, + COALESCE(NULLIF(COALESCE(a.line_name_h, lin.line_name_h), ''), NULL) AS line_name_h, + COALESCE(NULLIF(COALESCE(a.line_name_r, lin.line_name_r), ''), NULL) AS line_name_r, + COALESCE(NULLIF(COALESCE(a.line_name_zh, lin.line_name_zh), ''), NULL) AS line_name_zh, + COALESCE(NULLIF(COALESCE(a.line_name_ko, lin.line_name_ko), ''), NULL) AS line_name_ko, + COALESCE(NULLIF(COALESCE(a.line_color_c, lin.line_color_c), ''), NULL) AS line_color_c, + lin.line_type, + lin.line_symbol1, + lin.line_symbol2, + lin.line_symbol3, + lin.line_symbol4, + lin.line_symbol1_color, + lin.line_symbol2_color, + lin.line_symbol3_color, + lin.line_symbol4_color, + lin.line_symbol1_shape, + lin.line_symbol2_shape, + lin.line_symbol3_shape, + lin.line_symbol4_shape, + COALESCE(lin.average_distance, 0.0)::DOUBLE PRECISION AS average_distance, + COALESCE(sst.line_group_cd, NULL)::int AS line_group_cd, + NULL::int AS type_id, + NULL::int AS sst_id, + NULL::int AS type_cd, + NULL::int AS pass, + NULL::text AS type_name, + NULL::text AS type_name_k, + NULL::text AS type_name_r, + NULL::text AS type_name_zh, + NULL::text AS type_name_ko, + NULL::text AS color, + NULL::int AS direction, + NULL::int AS kind, + sta.transport_type + FROM + stations AS sta + JOIN common_lines AS cl ON sta.line_cd = cl.line_cd + JOIN lines AS lin ON lin.line_cd = cl.line_cd + LEFT JOIN sst_cte AS sst ON sst.station_cd = sta.station_cd + LEFT JOIN types AS tt ON tt.type_cd = sst.type_cd + LEFT JOIN line_aliases AS la ON la.station_cd = sta.station_cd + LEFT JOIN aliases AS a ON a.id = la.alias_cd + WHERE + sst.line_group_cd IS NULL + AND lin.e_status = 0 + AND sta.e_status = 0 + {untyped_order}"# + ); + + let mut rows = sqlx::query_as::<_, StationRow>(&untyped_query) + .bind(from_station_cd as i32) + .bind(to_station_cd as i32) + .bind(from_station_cd as i32) + .bind(to_station_cd as i32) + .bind(&via_line_ids_i32) + .fetch_all(&mut *conn) + .await?; + + let typed_order = if reverse { + "ORDER BY sst.id DESC" + } else { + "ORDER BY sst.id ASC" + }; + + let typed_query = format!( + r#"WITH + from_cte AS ( + SELECT + s.station_cd, + s.line_cd + FROM + stations AS s + WHERE + s.station_cd = $1 + AND s.e_status = 0 + ), + to_cte AS ( + SELECT + s.station_cd, + s.line_cd + FROM + stations AS s + WHERE + s.station_cd = $2 + AND s.e_status = 0 + ), + sst_cte_c1 AS ( + SELECT + sst.line_group_cd + FROM + station_station_types AS sst + JOIN from_cte ON sst.station_cd = from_cte.station_cd + WHERE + sst.pass <> 1 + ), + sst_cte_c2 AS ( + SELECT + sst.line_group_cd + FROM + station_station_types AS sst + JOIN to_cte ON sst.station_cd = to_cte.station_cd + WHERE + sst.pass <> 1 + ), + sst_cte AS ( + SELECT + sst.id, + sst.station_cd, + sst.type_cd, + sst.line_group_cd, + sst.pass + FROM + station_station_types AS sst + JOIN sst_cte_c1 ON sst.line_group_cd = sst_cte_c1.line_group_cd + JOIN sst_cte_c2 ON sst.line_group_cd = sst_cte_c2.line_group_cd + ) + SELECT + sta.station_cd, + sta.station_g_cd, + sta.station_name, + sta.station_name_k, + sta.station_name_r, + sta.station_name_rn, + sta.station_name_zh, + sta.station_name_ko, + sta.station_number1, + sta.station_number2, + sta.station_number3, + sta.station_number4, + sta.three_letter_code, + sta.line_cd, + sta.pref_cd, + sta.post, + sta.address, + sta.lon, + sta.lat, + sta.open_ymd, + sta.close_ymd, + sta.e_status, + sta.e_sort, + lin.company_cd, + COALESCE(NULLIF(COALESCE(a.line_name, lin.line_name), ''), NULL) AS line_name, + COALESCE(NULLIF(COALESCE(a.line_name_k, lin.line_name_k), ''), NULL) AS line_name_k, + COALESCE(NULLIF(COALESCE(a.line_name_h, lin.line_name_h), ''), NULL) AS line_name_h, + COALESCE(NULLIF(COALESCE(a.line_name_r, lin.line_name_r), ''), NULL) AS line_name_r, + COALESCE(NULLIF(COALESCE(a.line_name_zh, lin.line_name_zh), ''), NULL) AS line_name_zh, + COALESCE(NULLIF(COALESCE(a.line_name_ko, lin.line_name_ko), ''), NULL) AS line_name_ko, + COALESCE(NULLIF(COALESCE(a.line_color_c, lin.line_color_c), ''), NULL) AS line_color_c, + lin.line_type, + lin.line_symbol1, + lin.line_symbol2, + lin.line_symbol3, + lin.line_symbol4, + lin.line_symbol1_color, + lin.line_symbol2_color, + lin.line_symbol3_color, + lin.line_symbol4_color, + lin.line_symbol1_shape, + lin.line_symbol2_shape, + lin.line_symbol3_shape, + lin.line_symbol4_shape, + COALESCE(lin.average_distance, 0.0)::DOUBLE PRECISION AS average_distance, + tt.id AS type_id, + sst.id AS sst_id, + sst.type_cd, + sst.line_group_cd, + sst.pass, + tt.type_name, + tt.type_name_k, + tt.type_name_r, + tt.type_name_zh, + tt.type_name_ko, + tt.color, + tt.direction, + tt.kind, + sta.transport_type + FROM + stations AS sta + LEFT JOIN sst_cte AS sst ON sst.station_cd = sta.station_cd + JOIN types AS tt ON tt.type_cd = sst.type_cd + JOIN lines AS lin ON lin.line_cd = sta.line_cd AND lin.e_status = 0 + LEFT JOIN line_aliases AS la ON la.station_cd = sta.station_cd + LEFT JOIN aliases AS a ON a.id = la.alias_cd + WHERE + sta.e_status = 0 + AND (array_length($3::int[], 1) IS NULL OR sta.line_cd = ANY($3)) + {typed_order}"# + ); + + let mut typed_rows = sqlx::query_as::<_, StationRow>(&typed_query) + .bind(from_station_cd as i32) + .bind(to_station_cd as i32) + .bind(&via_line_ids_i32) + .fetch_all(conn) + .await?; + + rows.append(&mut typed_rows); + let stations: Vec = rows.into_iter().map(|row| row.into()).collect(); + + Ok(stations) + } } #[cfg(test)] @@ -2542,4 +2868,16 @@ mod tests { async fn test_get_by_line_group_id_station_order() { // 返される駅がsst.idの順序でソートされていることを確認 } + + #[tokio::test] + #[ignore] // Requires actual database setup + async fn test_get_route_stops_by_station_cd_default_order() { + // direction_id未指定時にデフォルト(ASC)順で駅が返されることを確認 + } + + #[tokio::test] + #[ignore] // Requires actual database setup + async fn test_get_route_stops_by_station_cd_reverse_order() { + // direction_id=1または2で駅の並び順がDESCに反転されることを確認 + } } diff --git a/stationapi/src/presentation/controller/grpc.rs b/stationapi/src/presentation/controller/grpc.rs index c0c0b9c0..ca6a92c2 100644 --- a/stationapi/src/presentation/controller/grpc.rs +++ b/stationapi/src/presentation/controller/grpc.rs @@ -6,15 +6,16 @@ use crate::{ }, presentation::error::PresentationalError, proto::{ - station_api_server::StationApi, GetConnectedStationsRequest, GetLineByIdRequest, - GetLinesByIdListRequest, GetLinesByNameRequest, GetRouteRequest, + station_api_server::StationApi, EstimateArrivalTimesRequest, EstimatedArrivalResponse, + EstimatedArrivalRoute, EstimatedArrivalStop, GetConnectedStationsRequest, + GetLineByIdRequest, GetLinesByIdListRequest, GetLinesByNameRequest, GetRouteRequest, GetStationByCoordinatesRequest, GetStationByGroupIdRequest, GetStationByIdListRequest, GetStationByIdRequest, GetStationByLineIdListRequest, GetStationByLineIdRequest, GetStationsByLineGroupIdListRequest, GetStationsByLineGroupIdRequest, - GetStationsByNameRequest, GetTrainTypesByStationIdRequest, MultipleLineResponse, - MultipleStationResponse, MultipleTrainTypeResponse, Route, RouteMinimalResponse, - RouteResponse, RouteTypeResponse, SingleLineResponse, SingleStationResponse, - TransportType as GrpcTransportType, + GetStationsByNameRequest, GetTrainRouteRequest, GetTrainTypesByStationIdRequest, + MultipleLineResponse, MultipleStationResponse, MultipleTrainTypeResponse, Route, + RouteMinimalResponse, RouteResponse, RouteTypeResponse, SingleLineResponse, + SingleStationResponse, TrainRouteResponse, TransportType as GrpcTransportType, }, use_case::{interactor::query::QueryInteractor, traits::query::QueryUseCase}, }; @@ -425,15 +426,88 @@ impl StationApi for MyApi { } } } + + async fn get_train_route( + &self, + request: tonic::Request, + ) -> Result, tonic::Status> { + let req = request.get_ref(); + let from_id = req.from_station_group_id; + let to_id = req.to_station_group_id; + let line_group_id = req + .line_group_id + .ok_or_else(|| tonic::Status::invalid_argument("line_group_id is required"))?; + + match self + .query_use_case + .get_train_route(from_id, to_id, line_group_id) + .await + { + Ok(segments) => Ok(Response::new(TrainRouteResponse { segments })), + Err(err) => Err(PresentationalError::from(err).into()), + } + } + + async fn estimate_arrival_times( + &self, + request: tonic::Request, + ) -> Result, tonic::Status> { + let from_id = request.get_ref().from_station_id; + let to_id = request.get_ref().to_station_id; + let via_line_ids = &request.get_ref().via_line_ids; + let direction_id = request.get_ref().direction_id; + + match self + .query_use_case + .estimate_route_arrival_times(from_id, to_id, via_line_ids, direction_id) + .await + { + Ok(estimated_stops) => { + let mut routes: Vec = Vec::new(); + + for stop in &estimated_stops { + let proto_stop = EstimatedArrivalStop { + station_id: stop.station_cd as u32, + station_group_id: stop.station_g_cd as u32, + cumulative_minutes: stop.cumulative_minutes, + departure_cumulative_minutes: stop.departure_cumulative_minutes, + stops_here: stop.stops_here, + }; + + let route_id = stop.line_group_cd.unwrap_or(0) as u32; + let merge = stop.line_group_cd.is_some() + && routes.last().is_some_and(|r| r.id == route_id); + + if merge { + routes.last_mut().unwrap().stops.push(proto_stop); + } else { + routes.push(EstimatedArrivalRoute { + id: route_id, + stops: vec![proto_stop], + }); + } + } + + Ok(Response::new(EstimatedArrivalResponse { + routes, + next_page_token: "".to_string(), + })) + } + Err(err) => Err(PresentationalError::from(err).into()), + } + } } #[cfg(test)] mod tests { use super::*; use crate::{ - domain::entity::{ - company::Company, gtfs::TransportType, line::Line, line_symbol::LineSymbol, - station::Station, station_number::StationNumber, train_type::TrainType, + domain::{ + arrival_estimation::EstimatedStop, + entity::{ + company::Company, gtfs::TransportType, line::Line, line_symbol::LineSymbol, + station::Station, station_number::StationNumber, train_type::TrainType, + }, }, proto::RouteMinimalResponse, use_case::{error::UseCaseError, traits::query::QueryUseCase}, @@ -831,6 +905,15 @@ mod tests { Ok(vec![]) } + async fn get_train_route( + &self, + _from_station_group_id: u32, + _to_station_group_id: u32, + _line_group_id: u32, + ) -> Result, UseCaseError> { + Ok(vec![]) + } + async fn find_line_by_id(&self, _line_id: u32) -> Result, UseCaseError> { Ok(None) } @@ -854,6 +937,16 @@ mod tests { ) -> Result, UseCaseError> { Ok(vec![]) } + + async fn estimate_route_arrival_times( + &self, + _from_station_id: u32, + _to_station_id: u32, + _via_line_ids: &[u32], + _direction_id: Option, + ) -> Result, UseCaseError> { + Ok(vec![]) + } } // ============================================ diff --git a/stationapi/src/use_case/dto.rs b/stationapi/src/use_case/dto.rs index 3b019c8a..813c4073 100644 --- a/stationapi/src/use_case/dto.rs +++ b/stationapi/src/use_case/dto.rs @@ -1,7 +1,8 @@ -pub mod company; -pub mod line; -pub mod line_symbol; -pub mod station; -pub mod station_number; -pub mod train_type; -pub mod tts; +pub mod company; +pub mod line; +pub mod line_symbol; +pub mod simulation; +pub mod station; +pub mod station_number; +pub mod train_type; +pub mod tts; diff --git a/stationapi/src/use_case/dto/simulation.rs b/stationapi/src/use_case/dto/simulation.rs new file mode 100644 index 00000000..812a5df3 --- /dev/null +++ b/stationapi/src/use_case/dto/simulation.rs @@ -0,0 +1,123 @@ +use crate::proto::{LineType, TrainTypeKind}; + +#[derive(Debug, Clone, Copy, PartialEq)] +pub struct SpeedProfile { + pub max_speed: f64, + pub max_acceleration: f64, + pub max_deceleration: f64, +} + +const BUS_MAX_SPEED: f64 = 11.111_111_111_11; // 40 km/h +const BUS_MAX_ACCEL: f64 = 1.2; +const BUS_MAX_DECEL: f64 = 1.3; + +const BULLET_TRAIN_MAX_SPEED: f64 = 88.888_888_89; // 320 km/h +const MONORAIL_OR_AGT_MAX_SPEED: f64 = 22.222_222_222_22; // 80 km/h +const SUBWAY_MAX_SPEED: f64 = 22.222_222_222_22; // 80 km/h +const NORMAL_MAX_SPEED: f64 = 25.0; // 90 km/h +const TRAM_MAX_SPEED: f64 = 11.111_111_111_11; // 40 km/h + +const LIMITED_EXPRESS_KIND_MAX_SPEED: f64 = 36.111_111_111_1; // 130 km/h + +pub fn resolve_speed_profile( + line_type: Option, + is_bus: bool, + kind: Option, +) -> SpeedProfile { + if is_bus { + return SpeedProfile { + max_speed: BUS_MAX_SPEED, + max_acceleration: BUS_MAX_ACCEL, + max_deceleration: BUS_MAX_DECEL, + }; + } + + let (line_max_speed, accel, decel) = match line_type.and_then(|v| LineType::try_from(v).ok()) { + Some(LineType::BulletTrain) => (BULLET_TRAIN_MAX_SPEED, 0.72, 0.56), + Some(LineType::Subway) => (SUBWAY_MAX_SPEED, 0.83, 0.83), + Some(LineType::MonorailOrAgt) => (MONORAIL_OR_AGT_MAX_SPEED, 0.97, 0.69), + Some(LineType::Tram) => (TRAM_MAX_SPEED, 0.83, 0.69), + _ => (NORMAL_MAX_SPEED, 0.83, 0.69), + }; + + let max_speed = match kind.and_then(|v| TrainTypeKind::try_from(v).ok()) { + Some(TrainTypeKind::LimitedExpress) | Some(TrainTypeKind::HighSpeedRapid) => { + LIMITED_EXPRESS_KIND_MAX_SPEED + } + _ => line_max_speed, + }; + + SpeedProfile { + max_speed, + max_acceleration: accel, + max_deceleration: decel, + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn bus_overrides_line_type() { + let p = resolve_speed_profile(Some(LineType::BulletTrain as i32), true, None); + assert_eq!(p.max_speed, BUS_MAX_SPEED); + assert_eq!(p.max_acceleration, BUS_MAX_ACCEL); + assert_eq!(p.max_deceleration, BUS_MAX_DECEL); + } + + #[test] + fn bullet_train_profile() { + let p = resolve_speed_profile(Some(LineType::BulletTrain as i32), false, None); + assert_eq!(p.max_speed, BULLET_TRAIN_MAX_SPEED); + assert_eq!(p.max_acceleration, 0.72); + assert_eq!(p.max_deceleration, 0.56); + } + + #[test] + fn subway_has_stronger_deceleration() { + let p = resolve_speed_profile(Some(LineType::Subway as i32), false, None); + assert_eq!(p.max_speed, SUBWAY_MAX_SPEED); + assert_eq!(p.max_deceleration, 0.83); + } + + #[test] + fn unknown_line_type_falls_back_to_normal() { + let p = resolve_speed_profile(None, false, None); + assert_eq!(p.max_speed, NORMAL_MAX_SPEED); + assert_eq!(p.max_acceleration, 0.83); + assert_eq!(p.max_deceleration, 0.69); + } + + #[test] + fn limited_express_kind_caps_speed_over_line_type() { + let p = resolve_speed_profile( + Some(LineType::Normal as i32), + false, + Some(TrainTypeKind::LimitedExpress as i32), + ); + assert_eq!(p.max_speed, LIMITED_EXPRESS_KIND_MAX_SPEED); + assert_eq!(p.max_acceleration, 0.83); + assert_eq!(p.max_deceleration, 0.69); + } + + #[test] + fn high_speed_rapid_kind_caps_speed() { + let p = resolve_speed_profile( + Some(LineType::Normal as i32), + false, + Some(TrainTypeKind::HighSpeedRapid as i32), + ); + assert_eq!(p.max_speed, LIMITED_EXPRESS_KIND_MAX_SPEED); + } + + #[test] + fn default_kind_keeps_line_type_speed() { + let p = resolve_speed_profile( + Some(LineType::Normal as i32), + false, + Some(TrainTypeKind::Default as i32), + ); + assert_eq!(p.max_speed, NORMAL_MAX_SPEED); + } +} diff --git a/stationapi/src/use_case/interactor/query.rs b/stationapi/src/use_case/interactor/query.rs index 35f4ed5a..1fb8a977 100644 --- a/stationapi/src/use_case/interactor/query.rs +++ b/stationapi/src/use_case/interactor/query.rs @@ -23,6 +23,10 @@ fn filter_to_db_type(filter: TransportTypeFilter) -> Option { use crate::{ domain::{ + arrival_estimation::{ + estimate_arrival_minutes, is_circular_route, select_circular_arc, EstimatedStop, + EstimationParams, + }, entity::{ company::Company, gtfs::{TransportType, TransportTypeFilter}, @@ -39,7 +43,9 @@ use crate::{ }, }, proto::{self, Route}, - use_case::{error::UseCaseError, traits::query::QueryUseCase}, + use_case::{ + dto::simulation::resolve_speed_profile, error::UseCaseError, traits::query::QueryUseCase, + }, }; use async_trait::async_trait; @@ -623,9 +629,10 @@ where to_station_id: u32, via_line_id: Option, ) -> Result, UseCaseError> { + let via_ids: Vec = via_line_id.into_iter().collect(); let stops = self .station_repository - .get_route_stops(from_station_id, to_station_id, via_line_id) + .get_route_stops(from_station_id, to_station_id, &via_ids) .await?; let route_row_tree_map = self.build_route_tree_map(&stops); @@ -727,9 +734,10 @@ where to_station_id: u32, via_line_id: Option, ) -> Result { + let via_ids: Vec = via_line_id.into_iter().collect(); let stops = self .station_repository - .get_route_stops(from_station_id, to_station_id, via_line_id) + .get_route_stops(from_station_id, to_station_id, &via_ids) .await?; let route_row_tree_map = self.build_route_tree_map(&stops); @@ -841,9 +849,10 @@ where to_station_id: u32, via_line_id: Option, ) -> Result, UseCaseError> { + let via_ids: Vec = via_line_id.into_iter().collect(); let stops = self .station_repository - .get_route_stops(from_station_id, to_station_id, via_line_id) + .get_route_stops(from_station_id, to_station_id, &via_ids) .await?; let line_group_id_vec: Vec = stops @@ -893,7 +902,7 @@ where let dedup_stops: &[Station] = if via_line_id.is_some() { dedup_stops_storage = self .station_repository - .get_route_stops(from_station_id, to_station_id, None) + .get_route_stops(from_station_id, to_station_id, &[]) .await?; &dedup_stops_storage } else { @@ -989,6 +998,68 @@ where Ok(result) } + async fn get_train_route( + &self, + from_station_group_id: u32, + to_station_group_id: u32, + line_group_id: u32, + ) -> Result, UseCaseError> { + let stations = self + .get_stations_by_line_group_id(line_group_id, TransportTypeFilter::RailAndBus) + .await?; + + let from_idx = stations + .iter() + .position(|s| s.station_g_cd as u32 == from_station_group_id) + .ok_or_else(|| UseCaseError::NotFound { + entity_type: "station in line group", + entity_id: from_station_group_id.to_string(), + })?; + let to_idx = stations + .iter() + .position(|s| s.station_g_cd as u32 == to_station_group_id) + .ok_or_else(|| UseCaseError::NotFound { + entity_type: "station in line group", + entity_id: to_station_group_id.to_string(), + })?; + + let sliced: Vec = if from_idx <= to_idx { + stations[from_idx..=to_idx].to_vec() + } else { + let mut v = stations[to_idx..=from_idx].to_vec(); + v.reverse(); + v + }; + + let mut segments: Vec = Vec::with_capacity(sliced.len()); + let mut prev_coord: Option<(f64, f64)> = None; + for station in sliced { + let stops = station.stop_condition != proto::StopCondition::Not; + + let distance_from_previous = match prev_coord { + Some((plat, plon)) => haversine_distance(plat, plon, station.lat, station.lon), + None => 0.0, + }; + prev_coord = Some((station.lat, station.lon)); + + let is_bus = station.transport_type == TransportType::Bus; + let kind = station.train_type.as_ref().and_then(|tt| tt.kind); + let profile = resolve_speed_profile(station.line_type, is_bus, kind); + + let grpc_station: proto::Station = station.into(); + segments.push(proto::TrainRouteSegment { + station: Some(grpc_station), + stops, + distance_from_previous, + max_speed: profile.max_speed, + max_acceleration: profile.max_acceleration, + max_deceleration: profile.max_deceleration, + }); + } + + Ok(segments) + } + async fn find_line_by_id(&self, line_id: u32) -> Result, UseCaseError> { let line = self.line_repository.find_by_id(line_id).await?; Ok(line) @@ -1019,6 +1090,75 @@ where ) -> Result, UseCaseError> { Ok(vec![]) } + + /// `from_station_id` から `to_station_id` までの区間の各駅について、始点からの + /// 推定到着時間(分)を返す。経路候補ごとに両端が含まれる区間だけへ絞り込み、 + /// `direction_id` の有無に関わらず from→to 順になるよう並べ替える。 + async fn estimate_route_arrival_times( + &self, + from_station_id: u32, + to_station_id: u32, + via_line_ids: &[u32], + direction_id: Option, + ) -> Result, UseCaseError> { + let stops = self + .station_repository + .get_route_stops_by_station_cd( + from_station_id, + to_station_id, + via_line_ids, + direction_id, + ) + .await?; + + let route_row_tree_map = self.build_route_tree_map(&stops); + let params = EstimationParams::default(); + + let mut result: Vec = Vec::new(); + for (_line_group_cd, group_stops) in route_row_tree_map.iter() { + // 先頭駅が末尾にも重複格納された「閉じた」環状データ(ポートライナー等)は、 + // そのままだとラップ時に閉じ駅が二重になるため重複終端を除いてから + // 環状判定・弧選択する。 + let mut route_stops: &[&Station] = group_stops.as_slice(); + if route_stops.len() > 1 + && route_stops[0].station_cd == route_stops[route_stops.len() - 1].station_cd + { + route_stops = &route_stops[..route_stops.len() - 1]; + } + + let from_pos = route_stops + .iter() + .position(|s| s.station_cd as u32 == from_station_id); + let to_pos = route_stops + .iter() + .position(|s| s.station_cd as u32 == to_station_id); + + // 始点・終点の両方がこの経路候補に含まれない、または同一駅の場合は対象外。 + let (Some(fi), Some(ti)) = (from_pos, to_pos) else { + continue; + }; + if fi == ti { + continue; + } + + // 経路全体ではなく、始点→終点の区間だけに絞り込んで推定する。 + // 環状経路(山手線・大阪環状線など)は線形スライスだと格納順の + // 継ぎ目(例: 品川⇔大崎)を跨ぐ乗車で逆側の弧を返してしまうため、 + // シームをラップする弧を選択する。 + if is_circular_route(route_stops) { + let arc = select_circular_arc(route_stops, fi, ti, direction_id.is_some()); + result.extend(estimate_arrival_minutes(&arc, ¶ms)); + } else if fi < ti { + result.extend(estimate_arrival_minutes(&route_stops[fi..=ti], ¶ms)); + } else { + let mut segment: Vec<&Station> = route_stops[ti..=fi].to_vec(); + segment.reverse(); + result.extend(estimate_arrival_minutes(&segment, ¶ms)); + } + } + + Ok(result) + } } impl QueryInteractor @@ -1485,20 +1625,10 @@ fn segment_stop_signature( } /// Calculate the distance between two points on Earth using the Haversine formula. -/// Returns the distance in meters. +/// Returns the distance in meters. Delegates to the shared domain implementation to +/// avoid duplicating the formula. fn haversine_distance(lat1: f64, lon1: f64, lat2: f64, lon2: f64) -> f64 { - const EARTH_RADIUS_METERS: f64 = 6_371_000.0; - - let lat1_rad = lat1.to_radians(); - let lat2_rad = lat2.to_radians(); - let delta_lat = (lat2 - lat1).to_radians(); - let delta_lon = (lon2 - lon1).to_radians(); - - let a = (delta_lat / 2.0).sin().powi(2) - + lat1_rad.cos() * lat2_rad.cos() * (delta_lon / 2.0).sin().powi(2); - let c = 2.0 * a.sqrt().asin(); - - EARTH_RADIUS_METERS * c + crate::domain::arrival_estimation::haversine_distance(lat1, lon1, lat2, lon2) } #[cfg(test)] @@ -1817,9 +1947,9 @@ mod tests { &self, _: u32, _: u32, - via_line_id: Option, + via_line_ids: &[u32], ) -> Result, DomainError> { - if via_line_id.is_some() { + if !via_line_ids.is_empty() { Ok(self.stops_via.clone()) } else { Ok(self.stops_unrestricted.clone()) @@ -1897,6 +2027,15 @@ mod tests { ) -> Result, DomainError> { Ok(vec![]) } + async fn get_route_stops_by_station_cd( + &self, + from: u32, + to: u32, + via: &[u32], + _direction_id: Option, + ) -> Result, DomainError> { + self.get_route_stops(from, to, via).await + } } struct DedupMockLineRepository { @@ -2201,6 +2340,239 @@ mod tests { assert_eq!(result.len(), 2); assert_eq!(line_group_cds(&result), vec![100, 300]); } + + /// Build a stop on a given line group with explicit coordinates, line, and pass. + fn create_geo_stop( + station_g_cd: i32, + line_cd: i32, + line_group_cd: i32, + lat: f64, + lon: f64, + pass: Option, + ) -> Station { + let mut station = + create_test_station(station_g_cd, station_g_cd, line_cd, Some(line_group_cd)); + station.lat = lat; + station.lon = lon; + station.pass = pass; + station + } + + #[tokio::test] + async fn test_estimate_route_arrival_times_through_service_and_pass() { + // 単一 line_group_cd の経路。途中で line_cd が 100→200 に変わる直通サービス。 + // 緯度方向に約 1.78km 間隔で 4 駅。3 駅目を通過にする。 + let stops = vec![ + create_geo_stop(1, 100, 500, 35.000, 139.0, Some(0)), + create_geo_stop(2, 100, 500, 35.016, 139.0, Some(0)), + create_geo_stop(3, 200, 500, 35.032, 139.0, Some(1)), // 通過 + create_geo_stop(4, 200, 500, 35.048, 139.0, Some(0)), + ]; + + let interactor = build_interactor(stops, vec![], vec![], vec![]); + let est = interactor + .estimate_route_arrival_times(1, 4, &[], None) + .await + .unwrap(); + + assert_eq!(est.len(), 4); + // 始点は 0 分。 + assert!((est[0].cumulative_minutes - 0.0).abs() < 1e-9); + // 通過駅は stops_here=false、その他は停車。 + assert!(est[0].stops_here && est[1].stops_here && est[3].stops_here); + assert!(!est[2].stops_here); + // 累積到着時間は単調増加。 + assert!(est[1].cumulative_minutes > est[0].cumulative_minutes); + assert!(est[2].cumulative_minutes > est[1].cumulative_minutes); + assert!(est[3].cumulative_minutes > est[2].cumulative_minutes); + // 全駅が同一経路(line_group_cd=500)に属する。 + assert!(est.iter().all(|e| e.line_group_cd == Some(500))); + } + + #[tokio::test] + async fn test_estimate_route_arrival_times_multiple_candidates_filtered_and_ordered() { + // 候補経路が 3 つ返るケース: + // - group 500 / 600 は始点(g_cd=1)・終点(g_cd=4)を含む → 対象 + // - group 700 は無関係な駅(g_cd=5,6)のみ → get_routes 同様に除外される + let stops = vec![ + // group 600(あえて 500 より先に積み、連結順が走査順ではなく + // line_group_cd 昇順で決定的になることを確認する) + create_geo_stop(1, 100, 600, 35.000, 139.0, Some(0)), + create_geo_stop(4, 100, 600, 35.048, 139.0, Some(0)), + // group 500 + create_geo_stop(1, 100, 500, 35.000, 139.0, Some(0)), + create_geo_stop(4, 100, 500, 35.048, 139.0, Some(0)), + // group 700(始点・終点を含まない → 除外) + create_geo_stop(5, 100, 700, 35.100, 139.0, Some(0)), + create_geo_stop(6, 100, 700, 35.116, 139.0, Some(0)), + ]; + + let interactor = build_interactor(stops, vec![], vec![], vec![]); + let est = interactor + .estimate_route_arrival_times(1, 4, &[], None) + .await + .unwrap(); + + // 700 は除外、500 と 600 の各 2 駅で計 4 件。 + assert_eq!(est.len(), 4); + // 連結順は line_group_cd 昇順(BTreeMap)で決定的: 500 → 600。 + let groups: Vec> = est.iter().map(|e| e.line_group_cd).collect(); + assert_eq!(groups, vec![Some(500), Some(500), Some(600), Some(600)]); + // 除外された 700 の駅は含まれない。 + assert!(est + .iter() + .all(|e| e.station_g_cd != 5 && e.station_g_cd != 6)); + // 各経路の始点は 0 分から始まる。 + assert!((est[0].cumulative_minutes - 0.0).abs() < 1e-9); + assert!((est[2].cumulative_minutes - 0.0).abs() < 1e-9); + } + + #[tokio::test] + async fn test_estimate_route_arrival_times_excludes_stations_outside_requested_range() { + // station_cd(101-105)と station_g_cd(1-5)をあえて別値にし、ルックアップが + // station_cd を正しく参照していることを検証できるようにする。 + let make_stop = |station_cd: i32, station_g_cd: i32, lat: f64, lon: f64| { + let mut station = create_test_station(station_cd, station_g_cd, 100, Some(500)); + station.lat = lat; + station.lon = lon; + station.pass = Some(0); + station + }; + + // 同一 line_group_cd に、要求範囲(station_cd=102〜104)の外側の駅 + // (station_cd=101, 105)も含まれるケース。範囲外の駅は結果に含まれてはならない。 + let stops = vec![ + make_stop(101, 1, 35.000, 139.0), + make_stop(102, 2, 35.016, 139.0), + make_stop(103, 3, 35.032, 139.0), + make_stop(104, 4, 35.048, 139.0), + make_stop(105, 5, 35.064, 139.0), + ]; + + let interactor = build_interactor(stops, vec![], vec![], vec![]); + let est = interactor + .estimate_route_arrival_times(102, 104, &[], None) + .await + .unwrap(); + + // 範囲内の station_g_cd=2,3,4 の 3 駅のみが返る。 + assert_eq!(est.len(), 3); + assert_eq!( + est.iter().map(|e| e.station_g_cd).collect::>(), + vec![2, 3, 4] + ); + // 範囲外の駅(g_cd=1, 5)は含まれない。 + assert!(est + .iter() + .all(|e| e.station_g_cd != 1 && e.station_g_cd != 5)); + // 区間の始点は 0 分から始まる。 + assert!((est[0].cumulative_minutes - 0.0).abs() < 1e-9); + } + + #[tokio::test] + async fn test_estimate_route_arrival_times_reversed_range_with_direction_id() { + // direction_id が指定されていても(=is_none() ガードを通らなくても)、 + // 範囲外の駅は除外され、fi > ti の場合は from→to 順に反転される。 + let stops = vec![ + create_geo_stop(1, 100, 500, 35.000, 139.0, Some(0)), + create_geo_stop(2, 100, 500, 35.016, 139.0, Some(0)), + create_geo_stop(3, 100, 500, 35.032, 139.0, Some(0)), + create_geo_stop(4, 100, 500, 35.048, 139.0, Some(0)), + create_geo_stop(5, 100, 500, 35.064, 139.0, Some(0)), + ]; + + let interactor = build_interactor(stops, vec![], vec![], vec![]); + // from=4, to=2: リスト内では from が to より後ろに現れる。 + let est = interactor + .estimate_route_arrival_times(4, 2, &[], Some(1)) + .await + .unwrap(); + + assert_eq!(est.len(), 3); + // from(4) → to(2) の順に並び、範囲外の 1,5 は含まれない。 + assert_eq!( + est.iter().map(|e| e.station_g_cd).collect::>(), + vec![4, 3, 2] + ); + assert!((est[0].cumulative_minutes - 0.0).abs() < 1e-9); + } + + /// 半径約 1.1km の円周上に等間隔で並ぶ n 駅の環状経路(g_cd は 1..=n)。 + fn ring_stops(n: usize, line_group_cd: i32) -> Vec { + (0..n) + .map(|i| { + let theta = 2.0 * std::f64::consts::PI * i as f64 / n as f64; + let lat = 35.0 + 0.01 * theta.cos(); + let lon = 139.0 + 0.01 * theta.sin() / 35.0_f64.to_radians().cos(); + create_geo_stop(i as i32 + 1, 100, line_group_cd, lat, lon, Some(0)) + }) + .collect() + } + + #[tokio::test] + async fn test_estimate_route_arrival_times_circular_wraps_seam() { + // 環状経路で direction_id 指定あり: 格納順の継ぎ目(末尾→先頭)を + // 跨ぐ乗車では、逆側の弧に反転せずシームをラップして進む。 + let interactor = build_interactor(ring_stops(8, 500), vec![], vec![], vec![]); + let est = interactor + .estimate_route_arrival_times(7, 2, &[], Some(0)) + .await + .unwrap(); + + // 7 → 8 → (シーム) → 1 → 2 の 4 駅。修正前は 2〜7 の逆順 6 駅が返っていた。 + assert_eq!( + est.iter().map(|e| e.station_g_cd).collect::>(), + vec![7, 8, 1, 2] + ); + assert!((est[0].cumulative_minutes - 0.0).abs() < 1e-9); + assert!(est + .windows(2) + .all(|w| w[1].cumulative_minutes > w[0].cumulative_minutes)); + } + + #[tokio::test] + async fn test_estimate_route_arrival_times_circular_shorter_arc_without_direction_id() { + // 環状経路で direction_id 未指定: 継ぎ目を挟んだ近接ペアには + // 遠回りの弧ではなく短い方の弧を返す。 + let interactor = build_interactor(ring_stops(8, 500), vec![], vec![], vec![]); + let est = interactor + .estimate_route_arrival_times(8, 2, &[], None) + .await + .unwrap(); + + // 8 → (シーム) → 1 → 2 の 3 駅(逆方向だと 7 駅の遠回り)。 + assert_eq!( + est.iter().map(|e| e.station_g_cd).collect::>(), + vec![8, 1, 2] + ); + assert!((est[0].cumulative_minutes - 0.0).abs() < 1e-9); + } + + #[tokio::test] + async fn test_estimate_route_arrival_times_circular_closed_loop_dedups_endpoint() { + // 先頭駅が末尾にも重複格納された「閉じた」環状データ(ポートライナー等)。 + // 重複終端を除いた上で環状と判定され、継ぎ目をラップした弧が返る + // (閉じ駅が二重に現れない)。 + let mut stops = ring_stops(8, 500); + let mut closing = stops[0].clone(); + closing.e_sort = 9; + stops.push(closing); + + let interactor = build_interactor(stops, vec![], vec![], vec![]); + let est = interactor + .estimate_route_arrival_times(7, 2, &[], Some(0)) + .await + .unwrap(); + + assert_eq!( + est.iter().map(|e| e.station_g_cd).collect::>(), + vec![7, 8, 1, 2] + ); + assert!((est[0].cumulative_minutes - 0.0).abs() < 1e-9); + assert!(est + .windows(2) + .all(|w| w[1].cumulative_minutes > w[0].cumulative_minutes)); + } } // ======================================== @@ -2301,6 +2673,15 @@ mod tests { &self, _: u32, _: u32, + _: &[u32], + ) -> Result, DomainError> { + Ok(vec![]) + } + async fn get_route_stops_by_station_cd( + &self, + _: u32, + _: u32, + _: &[u32], _: Option, ) -> Result, DomainError> { Ok(vec![]) @@ -2774,6 +3155,15 @@ mod tests { &self, _: u32, _: u32, + _: &[u32], + ) -> Result, DomainError> { + Ok(vec![]) + } + async fn get_route_stops_by_station_cd( + &self, + _: u32, + _: u32, + _: &[u32], _: Option, ) -> Result, DomainError> { Ok(vec![]) diff --git a/stationapi/src/use_case/traits/query.rs b/stationapi/src/use_case/traits/query.rs index 165e2cd7..7d71eba6 100644 --- a/stationapi/src/use_case/traits/query.rs +++ b/stationapi/src/use_case/traits/query.rs @@ -1,11 +1,14 @@ use async_trait::async_trait; use crate::{ - domain::entity::{ - company::Company, gtfs::TransportTypeFilter, line::Line, line_symbol::LineSymbol, - station::Station, station_number::StationNumber, train_type::TrainType, + domain::{ + arrival_estimation::EstimatedStop, + entity::{ + company::Company, gtfs::TransportTypeFilter, line::Line, line_symbol::LineSymbol, + station::Station, station_number::StationNumber, train_type::TrainType, + }, }, - proto::{Route, RouteMinimalResponse}, + proto::{Route, RouteMinimalResponse, TrainRouteSegment}, use_case::error::UseCaseError, }; @@ -108,6 +111,12 @@ pub trait QueryUseCase: Send + Sync + 'static { to_station_id: u32, via_line_id: Option, ) -> Result, UseCaseError>; + async fn get_train_route( + &self, + from_station_group_id: u32, + to_station_group_id: u32, + line_group_id: u32, + ) -> Result, UseCaseError>; async fn find_line_by_id(&self, line_id: u32) -> Result, UseCaseError>; async fn get_lines_by_id_vec(&self, line_ids: &[u32]) -> Result, UseCaseError>; async fn get_lines_by_name( @@ -120,4 +129,11 @@ pub trait QueryUseCase: Send + Sync + 'static { from_station_id: u32, to_station_id: u32, ) -> Result, UseCaseError>; + async fn estimate_route_arrival_times( + &self, + from_station_id: u32, + to_station_id: u32, + via_line_ids: &[u32], + direction_id: Option, + ) -> Result, UseCaseError>; }