Merge remote-tracking branch 'origin/sub_laptop_2' into main_laptop_1
This commit is contained in:
@@ -0,0 +1 @@
|
||||
{"project_id":"dad81824-4bb7-41df-ad9c-95c870c2a0dc","route_id":370,"filter_key":"classification","method":"dtm","smooth":true,"crs_epsg":5176,"road_type":"main","defaults":{"station_interval_m":20.0,"cross_half_width_m":20.0,"cross_sample_interval_m":0.5,"long_sample_interval_m":1.0,"vertical_exaggeration":1.0},"standard_cross_section":{"soil":{"road_width_m":3.0,"shoulder_left_m":0.5,"shoulder_right_m":0.5,"ditch":{"top_width_m":0.9,"bottom_width_m":0.3,"depth_m":0.3},"cross_slope_pct":{"min":3.0,"max":5.0},"fill_slope_ratio":1.2,"cut_slope_ratio":1.0},"rock":{"road_width_m":3.0,"shoulder_left_m":0.5,"shoulder_right_m":0.5,"ditch":{"top_width_m":0.69,"bottom_width_m":0.3,"depth_m":0.3},"ditch_l_type":{"width_m":0.5,"depth_m":0.1},"cross_slope_pct":{"min":3.0,"max":3.0},"fill_slope_ratio":1.2,"cut_slope_ratio":0.4},"paved":{"road_width_m":3.0,"shoulder_left_m":0.5,"shoulder_right_m":0.5,"ditch":{"top_width_m":0.9,"bottom_width_m":0.3,"depth_m":0.3},"cross_slope_pct":{"min":1.5,"max":2.0},"fill_slope_ratio":1.2,"cut_slope_ratio":1.0,"pavement_thickness_m":0.2}},"stored_standard_cross_section":null,"rock_boundary_default_offset_m":-0.5,"rock_boundary_step_m":0.1,"earthwork_conversion":{"soil":{"loose":1.25,"compacted":0.9},"ripping_rock":{"loose":1.35,"compacted":1.1649999999999998},"blasting_rock":{"loose":1.6,"compacted":1.1649999999999998}},"haul_equipment_limits":[{"key":"free_haul","max_distance_m":20.0},{"key":"dozer","max_distance_m":60.0},{"key":"dump_truck","max_distance_m":null}],"natural_spoil_min_ground_slope":0.6666666666666666}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1 @@
|
||||
{"pipe_points":[{"chainage_m":351.0,"source":"stream","id":"p35100","options":{"pipe_kind":"파형강관","pipe_diameter_mm":"1000","inlet_type":"집수정","inlet_basin_length_m":2,"inlet_basin_before_m":1,"inlet_basin_after_m":1,"inlet_revet_form":"돌쌓기(찰)","inlet_revet_length_m":10,"inlet_revet_before_m":5,"inlet_revet_after_m":5,"outlet_type":"기슭막이","outlet_revet_form":"돌쌓기(찰)","outlet_revet_length_m":10,"outlet_revet_before_m":5,"outlet_revet_after_m":5,"inlet_structure":"L","inlet_revet_height_m":1.7,"outlet_revet_height_m":1.5,"inlet_basin_height_m":1.5},"lonlat":[129.0969624,36.8109679],"x":208597.117,"y":367731.865}]}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
{"status":"success","chainages":[]}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"route_signature": "181-c94cb897d6ed0270",
|
||||
"points": [
|
||||
{
|
||||
"chainage_m": 351.0,
|
||||
"source": "stream",
|
||||
"id": "p35100",
|
||||
"options": {
|
||||
"pipe_kind": "파형강관",
|
||||
"pipe_diameter_mm": "1000",
|
||||
"inlet_type": "집수정",
|
||||
"inlet_basin_length_m": 2,
|
||||
"inlet_basin_before_m": 1,
|
||||
"inlet_basin_after_m": 1,
|
||||
"inlet_revet_form": "돌쌓기(찰)",
|
||||
"inlet_revet_length_m": 10,
|
||||
"inlet_revet_before_m": 5,
|
||||
"inlet_revet_after_m": 5,
|
||||
"outlet_type": "기슭막이",
|
||||
"outlet_revet_form": "돌쌓기(찰)",
|
||||
"outlet_revet_length_m": 10,
|
||||
"outlet_revet_before_m": 5,
|
||||
"outlet_revet_after_m": 5,
|
||||
"inlet_structure": "L",
|
||||
"inlet_revet_height_m": 1.7,
|
||||
"outlet_revet_height_m": 1.5,
|
||||
"inlet_basin_height_m": 1.5
|
||||
},
|
||||
"x": 208597.117,
|
||||
"y": 367731.865
|
||||
}
|
||||
]
|
||||
}
|
||||
BIN
Binary file not shown.
+182
@@ -0,0 +1,182 @@
|
||||
sequence,x,y
|
||||
0,208403.2001,367920.7514
|
||||
1,208406.4928,367842.927
|
||||
2,208406.5836,367841.8768
|
||||
3,208406.7662,367840.8386
|
||||
4,208407.0392,367839.8205
|
||||
5,208407.4004,367838.8302
|
||||
6,208426.7855,367792.1712
|
||||
7,208427.2313,367791.2183
|
||||
8,208427.7588,367790.3082
|
||||
9,208428.364,367789.4478
|
||||
10,208429.0423,367788.6436
|
||||
11,208429.7883,367787.902
|
||||
12,208430.5965,367787.2286
|
||||
13,208431.4605,367786.6285
|
||||
14,208432.3738,367786.1064
|
||||
15,208433.3292,367785.6663
|
||||
16,208434.3196,367785.3115
|
||||
17,208435.3372,367785.0449
|
||||
18,208436.3743,367784.8684
|
||||
19,208437.4228,367784.7834
|
||||
20,208438.4747,367784.7906
|
||||
21,208468.2344,367786.2993
|
||||
22,208473.877,367786.9659
|
||||
23,208505.117,367792.7962
|
||||
24,208510.3423,367794.063
|
||||
25,208515.4031,367795.8789
|
||||
26,208527.5021,367800.9636
|
||||
27,208528.9177,367801.4569
|
||||
28,208530.3839,367801.7699
|
||||
29,208545.3106,367803.9926
|
||||
30,208546.4412,367804.1065
|
||||
31,208547.5774,367804.113
|
||||
32,208548.7092,367804.012
|
||||
33,208549.8264,367803.8044
|
||||
34,208550.9189,367803.4921
|
||||
35,208551.977,367803.0778
|
||||
36,208562.6578,367798.3011
|
||||
37,208563.629,367797.8128
|
||||
38,208564.5521,367797.2387
|
||||
39,208565.4194,367796.5833
|
||||
40,208566.2238,367795.8521
|
||||
41,208566.9588,367795.0512
|
||||
42,208567.6183,367794.187
|
||||
43,208568.1969,367793.2666
|
||||
44,208568.6898,367792.2977
|
||||
45,208569.0929,367791.2882
|
||||
46,208580.1819,367759.4003
|
||||
47,208580.6952,367758.1545
|
||||
48,208581.345,367756.9741
|
||||
49,208596.5507,367732.6861
|
||||
50,208597.1476,367731.8196
|
||||
51,208597.8181,367731.0088
|
||||
52,208598.557,367730.2598
|
||||
53,208599.3587,367729.5784
|
||||
54,208600.217,367728.9698
|
||||
55,208601.1253,367728.4388
|
||||
56,208602.0767,367727.9894
|
||||
57,208603.0637,367727.625
|
||||
58,208604.0789,367727.3485
|
||||
59,208605.1144,367727.162
|
||||
60,208606.1622,367727.0669
|
||||
61,208607.2144,367727.0639
|
||||
62,208608.2627,367727.1532
|
||||
63,208609.2993,367727.3339
|
||||
64,208610.316,367727.6047
|
||||
65,208611.305,367727.9635
|
||||
66,208612.2589,367728.4076
|
||||
67,208613.1701,367728.9336
|
||||
68,208614.0318,367729.5373
|
||||
69,208636.9831,367747.167
|
||||
70,208637.7986,367747.8532
|
||||
71,208638.5501,367748.609
|
||||
72,208663.7219,367776.2823
|
||||
73,208664.6721,367777.4703
|
||||
74,208665.4644,367778.7689
|
||||
75,208682.8222,367811.7566
|
||||
76,208683.4357,367812.7928
|
||||
77,208684.15,367813.7623
|
||||
78,208692.1195,367823.514
|
||||
79,208699.2384,367833.6567
|
||||
80,208704.0665,367841.7335
|
||||
81,208704.6739,367842.6512
|
||||
82,208705.3628,367843.5095
|
||||
83,208706.1275,367844.3009
|
||||
84,208706.9614,367845.0191
|
||||
85,208707.8576,367845.6578
|
||||
86,208708.8086,367846.2117
|
||||
87,208709.8063,367846.6761
|
||||
88,208710.8423,367847.0472
|
||||
89,208716.1671,367848.6831
|
||||
90,208721.0309,367849.9023
|
||||
91,208725.9956,367850.6052
|
||||
92,208731.0066,367850.7841
|
||||
93,208736.0087,367850.4371
|
||||
94,208781.4797,367844.8739
|
||||
95,208782.6655,367844.7882
|
||||
96,208783.854,367844.8202
|
||||
97,208785.0334,367844.9697
|
||||
98,208786.1923,367845.2351
|
||||
99,208787.3193,367845.614
|
||||
100,208788.4032,367846.1024
|
||||
101,208789.4335,367846.6958
|
||||
102,208809.7708,367859.7909
|
||||
103,208816.0718,367864.3322
|
||||
104,208821.8631,367869.5079
|
||||
105,208827.081,367875.2613
|
||||
106,208840.6889,367891.9449
|
||||
107,208841.3869,367892.7282
|
||||
108,208842.1508,367893.4475
|
||||
109,208842.9746,367894.0974
|
||||
110,208843.852,367894.6728
|
||||
111,208844.7763,367895.1694
|
||||
112,208845.7404,367895.5833
|
||||
113,208846.737,367895.9115
|
||||
114,208847.7585,367896.1513
|
||||
115,208848.797,367896.3009
|
||||
116,208849.8446,367896.3593
|
||||
117,208850.8933,367896.326
|
||||
118,208851.9351,367896.2011
|
||||
119,208852.962,367895.9858
|
||||
120,208899.1319,367884.1744
|
||||
121,208900.2135,367883.9502
|
||||
122,208901.3112,367883.8264
|
||||
123,208902.4156,367883.804
|
||||
124,208903.5174,367883.8833
|
||||
125,208904.6072,367884.0636
|
||||
126,208905.6759,367884.3433
|
||||
127,208906.7143,367884.7201
|
||||
128,208907.7136,367885.1908
|
||||
129,208908.6654,367885.7514
|
||||
130,208909.5617,367886.3972
|
||||
131,208934.2094,367905.9409
|
||||
132,208935.8546,367907.1026
|
||||
133,208937.6185,367908.0747
|
||||
134,208939.4793,367908.8451
|
||||
135,208966.8587,367918.4372
|
||||
136,208967.8753,367918.7436
|
||||
137,208968.9151,367918.9589
|
||||
138,208969.9698,367919.0815
|
||||
139,208971.0312,367919.1103
|
||||
140,208972.091,367919.0452
|
||||
141,208973.1409,367918.8867
|
||||
142,208974.1727,367918.636
|
||||
143,208975.1783,367918.2951
|
||||
144,208976.1498,367917.8666
|
||||
145,208977.0797,367917.3539
|
||||
146,208977.9605,367916.7611
|
||||
147,208978.7856,367916.0926
|
||||
148,208979.5483,367915.3539
|
||||
149,208980.2427,367914.5506
|
||||
150,208980.8634,367913.6891
|
||||
151,208995.3496,367891.5822
|
||||
152,208995.92,367890.616
|
||||
153,208996.3977,367889.6007
|
||||
154,208996.7785,367888.5453
|
||||
155,208997.059,367887.4589
|
||||
156,208997.2368,367886.3511
|
||||
157,208997.3104,367885.2315
|
||||
158,208997.2791,367884.1099
|
||||
159,208997.1432,367882.9962
|
||||
160,208996.9038,367881.9
|
||||
161,208996.5632,367880.8309
|
||||
162,208987.32,367855.9177
|
||||
163,208986.5266,367853.4357
|
||||
164,208985.9642,367850.8915
|
||||
165,208985.6375,367848.3063
|
||||
166,208985.5491,367845.7021
|
||||
167,208985.6999,367843.1008
|
||||
168,208986.0885,367840.5242
|
||||
169,208991.8532,367811.4317
|
||||
170,208992.1634,367810.2078
|
||||
171,208992.6005,367809.0232
|
||||
172,208993.1597,367807.8912
|
||||
173,208993.8347,367806.8241
|
||||
174,209025.4112,367762.2823
|
||||
175,209026.0307,367761.313
|
||||
176,209026.5546,367760.2889
|
||||
177,209026.978,367759.2194
|
||||
178,209027.297,367758.1142
|
||||
179,209027.5088,367756.9836
|
||||
180,209038.0798,367680.426
|
||||
|
+1
File diff suppressed because one or more lines are too long
+28
@@ -0,0 +1,28 @@
|
||||
sequence,x,y
|
||||
0,208403.2001,367920.7514
|
||||
1,208406.5829,367840.798
|
||||
2,208430.0297,367784.3624
|
||||
3,208471.078,367786.4435
|
||||
4,208510.4251,367793.7869
|
||||
5,208528.8923,367801.5478
|
||||
6,208548.7774,367804.5088
|
||||
7,208567.3902,367796.1847
|
||||
8,208580.6266,367758.1216
|
||||
9,208603.5586,367721.4924
|
||||
10,208637.8308,367747.8182
|
||||
11,208664.7517,367777.4145
|
||||
12,208683.3851,367812.8263
|
||||
13,208696.0508,367828.3244
|
||||
14,208706.4332,367845.6926
|
||||
15,208725.9011,367851.6737
|
||||
16,208785.7859,367844.3471
|
||||
17,208819.6524,367866.1537
|
||||
18,208845.5346,367897.8859
|
||||
19,208904.898,367882.6993
|
||||
20,208936.6,367907.8364
|
||||
21,208975.7182,367921.541
|
||||
22,208998.6713,367886.513
|
||||
23,208984.5289,367848.395
|
||||
24,208992.3516,367808.9162
|
||||
25,209027.1076,367759.8893
|
||||
26,209038.0798,367680.426
|
||||
|
@@ -0,0 +1,914 @@
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
208403.2,
|
||||
367920.751,
|
||||
879.138
|
||||
],
|
||||
[
|
||||
208406.493,
|
||||
367842.927,
|
||||
864.405
|
||||
],
|
||||
[
|
||||
208406.584,
|
||||
367841.877,
|
||||
864.787
|
||||
],
|
||||
[
|
||||
208406.766,
|
||||
367840.839,
|
||||
864.597
|
||||
],
|
||||
[
|
||||
208407.039,
|
||||
367839.82,
|
||||
864.415
|
||||
],
|
||||
[
|
||||
208407.4,
|
||||
367838.83,
|
||||
864.372
|
||||
],
|
||||
[
|
||||
208426.785,
|
||||
367792.171,
|
||||
858.919
|
||||
],
|
||||
[
|
||||
208427.231,
|
||||
367791.218,
|
||||
859.26
|
||||
],
|
||||
[
|
||||
208427.759,
|
||||
367790.308,
|
||||
859.48
|
||||
],
|
||||
[
|
||||
208428.364,
|
||||
367789.448,
|
||||
859.322
|
||||
],
|
||||
[
|
||||
208429.042,
|
||||
367788.644,
|
||||
859.34
|
||||
],
|
||||
[
|
||||
208429.788,
|
||||
367787.902,
|
||||
859.184
|
||||
],
|
||||
[
|
||||
208430.597,
|
||||
367787.229,
|
||||
859.096
|
||||
],
|
||||
[
|
||||
208431.46,
|
||||
367786.628,
|
||||
858.932
|
||||
],
|
||||
[
|
||||
208432.374,
|
||||
367786.106,
|
||||
858.791
|
||||
],
|
||||
[
|
||||
208433.329,
|
||||
367785.666,
|
||||
858.435
|
||||
],
|
||||
[
|
||||
208434.32,
|
||||
367785.312,
|
||||
858.212
|
||||
],
|
||||
[
|
||||
208435.337,
|
||||
367785.045,
|
||||
858.089
|
||||
],
|
||||
[
|
||||
208436.374,
|
||||
367784.868,
|
||||
857.432
|
||||
],
|
||||
[
|
||||
208437.423,
|
||||
367784.783,
|
||||
857.18
|
||||
],
|
||||
[
|
||||
208438.475,
|
||||
367784.791,
|
||||
856.833
|
||||
],
|
||||
[
|
||||
208468.234,
|
||||
367786.299,
|
||||
849.434
|
||||
],
|
||||
[
|
||||
208473.877,
|
||||
367786.966,
|
||||
849.2
|
||||
],
|
||||
[
|
||||
208505.117,
|
||||
367792.796,
|
||||
841.946
|
||||
],
|
||||
[
|
||||
208510.342,
|
||||
367794.063,
|
||||
841.338
|
||||
],
|
||||
[
|
||||
208515.403,
|
||||
367795.879,
|
||||
840.214
|
||||
],
|
||||
[
|
||||
208527.502,
|
||||
367800.964,
|
||||
838.315
|
||||
],
|
||||
[
|
||||
208528.918,
|
||||
367801.457,
|
||||
837.999
|
||||
],
|
||||
[
|
||||
208530.384,
|
||||
367801.77,
|
||||
838.144
|
||||
],
|
||||
[
|
||||
208545.311,
|
||||
367803.993,
|
||||
838.552
|
||||
],
|
||||
[
|
||||
208546.441,
|
||||
367804.106,
|
||||
838.299
|
||||
],
|
||||
[
|
||||
208547.577,
|
||||
367804.113,
|
||||
837.705
|
||||
],
|
||||
[
|
||||
208548.709,
|
||||
367804.012,
|
||||
837.398
|
||||
],
|
||||
[
|
||||
208549.826,
|
||||
367803.804,
|
||||
836.911
|
||||
],
|
||||
[
|
||||
208550.919,
|
||||
367803.492,
|
||||
836.234
|
||||
],
|
||||
[
|
||||
208551.977,
|
||||
367803.078,
|
||||
835.66
|
||||
],
|
||||
[
|
||||
208562.658,
|
||||
367798.301,
|
||||
830.929
|
||||
],
|
||||
[
|
||||
208563.629,
|
||||
367797.813,
|
||||
830.249
|
||||
],
|
||||
[
|
||||
208564.552,
|
||||
367797.239,
|
||||
829.333
|
||||
],
|
||||
[
|
||||
208565.419,
|
||||
367796.583,
|
||||
828.839
|
||||
],
|
||||
[
|
||||
208566.224,
|
||||
367795.852,
|
||||
828.786
|
||||
],
|
||||
[
|
||||
208566.959,
|
||||
367795.051,
|
||||
828.499
|
||||
],
|
||||
[
|
||||
208567.618,
|
||||
367794.187,
|
||||
828.406
|
||||
],
|
||||
[
|
||||
208568.197,
|
||||
367793.267,
|
||||
828.319
|
||||
],
|
||||
[
|
||||
208568.69,
|
||||
367792.298,
|
||||
828.093
|
||||
],
|
||||
[
|
||||
208569.093,
|
||||
367791.288,
|
||||
829.541
|
||||
],
|
||||
[
|
||||
208580.182,
|
||||
367759.4,
|
||||
831.257
|
||||
],
|
||||
[
|
||||
208580.695,
|
||||
367758.155,
|
||||
832.034
|
||||
],
|
||||
[
|
||||
208581.345,
|
||||
367756.974,
|
||||
832.16
|
||||
],
|
||||
[
|
||||
208596.551,
|
||||
367732.686,
|
||||
834.536
|
||||
],
|
||||
[
|
||||
208597.148,
|
||||
367731.82,
|
||||
834.892
|
||||
],
|
||||
[
|
||||
208597.818,
|
||||
367731.009,
|
||||
835.06
|
||||
],
|
||||
[
|
||||
208598.557,
|
||||
367730.26,
|
||||
835.092
|
||||
],
|
||||
[
|
||||
208599.359,
|
||||
367729.578,
|
||||
835.243
|
||||
],
|
||||
[
|
||||
208600.217,
|
||||
367728.97,
|
||||
835.762
|
||||
],
|
||||
[
|
||||
208601.125,
|
||||
367728.439,
|
||||
835.842
|
||||
],
|
||||
[
|
||||
208602.077,
|
||||
367727.989,
|
||||
835.647
|
||||
],
|
||||
[
|
||||
208603.064,
|
||||
367727.625,
|
||||
835.296
|
||||
],
|
||||
[
|
||||
208604.079,
|
||||
367727.349,
|
||||
835.329
|
||||
],
|
||||
[
|
||||
208605.114,
|
||||
367727.162,
|
||||
835.357
|
||||
],
|
||||
[
|
||||
208606.162,
|
||||
367727.067,
|
||||
835.683
|
||||
],
|
||||
[
|
||||
208607.214,
|
||||
367727.064,
|
||||
836.126
|
||||
],
|
||||
[
|
||||
208608.263,
|
||||
367727.153,
|
||||
836.12
|
||||
],
|
||||
[
|
||||
208609.299,
|
||||
367727.334,
|
||||
836.055
|
||||
],
|
||||
[
|
||||
208610.316,
|
||||
367727.605,
|
||||
836.457
|
||||
],
|
||||
[
|
||||
208611.305,
|
||||
367727.964,
|
||||
836.862
|
||||
],
|
||||
[
|
||||
208612.259,
|
||||
367728.408,
|
||||
836.6
|
||||
],
|
||||
[
|
||||
208613.17,
|
||||
367728.934,
|
||||
836.145
|
||||
],
|
||||
[
|
||||
208614.032,
|
||||
367729.537,
|
||||
835.925
|
||||
],
|
||||
[
|
||||
208636.983,
|
||||
367747.167,
|
||||
834.412
|
||||
],
|
||||
[
|
||||
208637.799,
|
||||
367747.853,
|
||||
834.377
|
||||
],
|
||||
[
|
||||
208638.55,
|
||||
367748.609,
|
||||
834.275
|
||||
],
|
||||
[
|
||||
208663.722,
|
||||
367776.282,
|
||||
840.491
|
||||
],
|
||||
[
|
||||
208664.672,
|
||||
367777.47,
|
||||
840.779
|
||||
],
|
||||
[
|
||||
208665.464,
|
||||
367778.769,
|
||||
841.052
|
||||
],
|
||||
[
|
||||
208682.822,
|
||||
367811.757,
|
||||
840.601
|
||||
],
|
||||
[
|
||||
208683.436,
|
||||
367812.793,
|
||||
840.136
|
||||
],
|
||||
[
|
||||
208684.15,
|
||||
367813.762,
|
||||
840.401
|
||||
],
|
||||
[
|
||||
208692.12,
|
||||
367823.514,
|
||||
841.362
|
||||
],
|
||||
[
|
||||
208699.238,
|
||||
367833.657,
|
||||
842.384
|
||||
],
|
||||
[
|
||||
208704.066,
|
||||
367841.733,
|
||||
842.267
|
||||
],
|
||||
[
|
||||
208704.674,
|
||||
367842.651,
|
||||
841.992
|
||||
],
|
||||
[
|
||||
208705.363,
|
||||
367843.509,
|
||||
842.264
|
||||
],
|
||||
[
|
||||
208706.128,
|
||||
367844.301,
|
||||
842.644
|
||||
],
|
||||
[
|
||||
208706.961,
|
||||
367845.019,
|
||||
842.988
|
||||
],
|
||||
[
|
||||
208707.858,
|
||||
367845.658,
|
||||
842.964
|
||||
],
|
||||
[
|
||||
208708.809,
|
||||
367846.212,
|
||||
843.198
|
||||
],
|
||||
[
|
||||
208709.806,
|
||||
367846.676,
|
||||
843.236
|
||||
],
|
||||
[
|
||||
208710.842,
|
||||
367847.047,
|
||||
842.565
|
||||
],
|
||||
[
|
||||
208716.167,
|
||||
367848.683,
|
||||
839.588
|
||||
],
|
||||
[
|
||||
208721.031,
|
||||
367849.902,
|
||||
837.138
|
||||
],
|
||||
[
|
||||
208725.996,
|
||||
367850.605,
|
||||
834.492
|
||||
],
|
||||
[
|
||||
208731.007,
|
||||
367850.784,
|
||||
832.855
|
||||
],
|
||||
[
|
||||
208736.009,
|
||||
367850.437,
|
||||
832.177
|
||||
],
|
||||
[
|
||||
208781.48,
|
||||
367844.874,
|
||||
836.645
|
||||
],
|
||||
[
|
||||
208782.666,
|
||||
367844.788,
|
||||
837.311
|
||||
],
|
||||
[
|
||||
208783.854,
|
||||
367844.82,
|
||||
837.844
|
||||
],
|
||||
[
|
||||
208785.033,
|
||||
367844.97,
|
||||
838.022
|
||||
],
|
||||
[
|
||||
208786.192,
|
||||
367845.235,
|
||||
837.994
|
||||
],
|
||||
[
|
||||
208787.319,
|
||||
367845.614,
|
||||
837.882
|
||||
],
|
||||
[
|
||||
208788.403,
|
||||
367846.102,
|
||||
837.728
|
||||
],
|
||||
[
|
||||
208789.434,
|
||||
367846.696,
|
||||
837.716
|
||||
],
|
||||
[
|
||||
208809.771,
|
||||
367859.791,
|
||||
836.452
|
||||
],
|
||||
[
|
||||
208816.072,
|
||||
367864.332,
|
||||
837.15
|
||||
],
|
||||
[
|
||||
208821.863,
|
||||
367869.508,
|
||||
837.11
|
||||
],
|
||||
[
|
||||
208827.081,
|
||||
367875.261,
|
||||
835.924
|
||||
],
|
||||
[
|
||||
208840.689,
|
||||
367891.945,
|
||||
840.651
|
||||
],
|
||||
[
|
||||
208841.387,
|
||||
367892.728,
|
||||
840.762
|
||||
],
|
||||
[
|
||||
208842.151,
|
||||
367893.448,
|
||||
840.867
|
||||
],
|
||||
[
|
||||
208842.975,
|
||||
367894.097,
|
||||
841.553
|
||||
],
|
||||
[
|
||||
208843.852,
|
||||
367894.673,
|
||||
842.473
|
||||
],
|
||||
[
|
||||
208844.776,
|
||||
367895.169,
|
||||
843.279
|
||||
],
|
||||
[
|
||||
208845.74,
|
||||
367895.583,
|
||||
843.863
|
||||
],
|
||||
[
|
||||
208846.737,
|
||||
367895.911,
|
||||
844.457
|
||||
],
|
||||
[
|
||||
208847.758,
|
||||
367896.151,
|
||||
844.415
|
||||
],
|
||||
[
|
||||
208848.797,
|
||||
367896.301,
|
||||
842.684
|
||||
],
|
||||
[
|
||||
208849.845,
|
||||
367896.359,
|
||||
841.776
|
||||
],
|
||||
[
|
||||
208850.893,
|
||||
367896.326,
|
||||
841.129
|
||||
],
|
||||
[
|
||||
208851.935,
|
||||
367896.201,
|
||||
840.86
|
||||
],
|
||||
[
|
||||
208852.962,
|
||||
367895.986,
|
||||
840.151
|
||||
],
|
||||
[
|
||||
208899.132,
|
||||
367884.174,
|
||||
831.066
|
||||
],
|
||||
[
|
||||
208900.214,
|
||||
367883.95,
|
||||
831.285
|
||||
],
|
||||
[
|
||||
208901.311,
|
||||
367883.826,
|
||||
831.501
|
||||
],
|
||||
[
|
||||
208902.416,
|
||||
367883.804,
|
||||
831.685
|
||||
],
|
||||
[
|
||||
208903.517,
|
||||
367883.883,
|
||||
832.09
|
||||
],
|
||||
[
|
||||
208904.607,
|
||||
367884.064,
|
||||
832.134
|
||||
],
|
||||
[
|
||||
208905.676,
|
||||
367884.343,
|
||||
832.166
|
||||
],
|
||||
[
|
||||
208906.714,
|
||||
367884.72,
|
||||
831.968
|
||||
],
|
||||
[
|
||||
208907.714,
|
||||
367885.191,
|
||||
831.463
|
||||
],
|
||||
[
|
||||
208908.665,
|
||||
367885.751,
|
||||
830.814
|
||||
],
|
||||
[
|
||||
208909.562,
|
||||
367886.397,
|
||||
831.28
|
||||
],
|
||||
[
|
||||
208934.209,
|
||||
367905.941,
|
||||
835.37
|
||||
],
|
||||
[
|
||||
208935.855,
|
||||
367907.103,
|
||||
835.855
|
||||
],
|
||||
[
|
||||
208937.619,
|
||||
367908.075,
|
||||
836.345
|
||||
],
|
||||
[
|
||||
208939.479,
|
||||
367908.845,
|
||||
837.618
|
||||
],
|
||||
[
|
||||
208966.859,
|
||||
367918.437,
|
||||
839.674
|
||||
],
|
||||
[
|
||||
208967.875,
|
||||
367918.744,
|
||||
839.231
|
||||
],
|
||||
[
|
||||
208968.915,
|
||||
367918.959,
|
||||
838.481
|
||||
],
|
||||
[
|
||||
208969.97,
|
||||
367919.081,
|
||||
838.152
|
||||
],
|
||||
[
|
||||
208971.031,
|
||||
367919.11,
|
||||
837.728
|
||||
],
|
||||
[
|
||||
208972.091,
|
||||
367919.045,
|
||||
837.351
|
||||
],
|
||||
[
|
||||
208973.141,
|
||||
367918.887,
|
||||
837.032
|
||||
],
|
||||
[
|
||||
208974.173,
|
||||
367918.636,
|
||||
836.809
|
||||
],
|
||||
[
|
||||
208975.178,
|
||||
367918.295,
|
||||
836.747
|
||||
],
|
||||
[
|
||||
208976.15,
|
||||
367917.867,
|
||||
836.272
|
||||
],
|
||||
[
|
||||
208977.08,
|
||||
367917.354,
|
||||
835.905
|
||||
],
|
||||
[
|
||||
208977.96,
|
||||
367916.761,
|
||||
835.644
|
||||
],
|
||||
[
|
||||
208978.786,
|
||||
367916.093,
|
||||
835.451
|
||||
],
|
||||
[
|
||||
208979.548,
|
||||
367915.354,
|
||||
835.276
|
||||
],
|
||||
[
|
||||
208980.243,
|
||||
367914.551,
|
||||
835.053
|
||||
],
|
||||
[
|
||||
208980.863,
|
||||
367913.689,
|
||||
834.763
|
||||
],
|
||||
[
|
||||
208995.35,
|
||||
367891.582,
|
||||
835.441
|
||||
],
|
||||
[
|
||||
208995.92,
|
||||
367890.616,
|
||||
835.898
|
||||
],
|
||||
[
|
||||
208996.398,
|
||||
367889.601,
|
||||
836.402
|
||||
],
|
||||
[
|
||||
208996.778,
|
||||
367888.545,
|
||||
836.989
|
||||
],
|
||||
[
|
||||
208997.059,
|
||||
367887.459,
|
||||
837.416
|
||||
],
|
||||
[
|
||||
208997.237,
|
||||
367886.351,
|
||||
837.913
|
||||
],
|
||||
[
|
||||
208997.31,
|
||||
367885.231,
|
||||
838.623
|
||||
],
|
||||
[
|
||||
208997.279,
|
||||
367884.11,
|
||||
839.509
|
||||
],
|
||||
[
|
||||
208997.143,
|
||||
367882.996,
|
||||
840.394
|
||||
],
|
||||
[
|
||||
208996.904,
|
||||
367881.9,
|
||||
840.934
|
||||
],
|
||||
[
|
||||
208996.563,
|
||||
367880.831,
|
||||
841.838
|
||||
],
|
||||
[
|
||||
208987.32,
|
||||
367855.918,
|
||||
839.561
|
||||
],
|
||||
[
|
||||
208986.527,
|
||||
367853.436,
|
||||
839.032
|
||||
],
|
||||
[
|
||||
208985.964,
|
||||
367850.892,
|
||||
838.242
|
||||
],
|
||||
[
|
||||
208985.638,
|
||||
367848.306,
|
||||
837.704
|
||||
],
|
||||
[
|
||||
208985.549,
|
||||
367845.702,
|
||||
836.2
|
||||
],
|
||||
[
|
||||
208985.7,
|
||||
367843.101,
|
||||
835.884
|
||||
],
|
||||
[
|
||||
208986.089,
|
||||
367840.524,
|
||||
835.409
|
||||
],
|
||||
[
|
||||
208991.853,
|
||||
367811.432,
|
||||
827.88
|
||||
],
|
||||
[
|
||||
208992.163,
|
||||
367810.208,
|
||||
828.585
|
||||
],
|
||||
[
|
||||
208992.601,
|
||||
367809.023,
|
||||
828.562
|
||||
],
|
||||
[
|
||||
208993.16,
|
||||
367807.891,
|
||||
827.848
|
||||
],
|
||||
[
|
||||
208993.835,
|
||||
367806.824,
|
||||
827.463
|
||||
],
|
||||
[
|
||||
209025.411,
|
||||
367762.282,
|
||||
830.904
|
||||
],
|
||||
[
|
||||
209026.031,
|
||||
367761.313,
|
||||
830.97
|
||||
],
|
||||
[
|
||||
209026.555,
|
||||
367760.289,
|
||||
831.407
|
||||
],
|
||||
[
|
||||
209026.978,
|
||||
367759.219,
|
||||
831.105
|
||||
],
|
||||
[
|
||||
209027.297,
|
||||
367758.114,
|
||||
831.941
|
||||
],
|
||||
[
|
||||
209027.509,
|
||||
367756.984,
|
||||
831.658
|
||||
],
|
||||
[
|
||||
209038.08,
|
||||
367680.426,
|
||||
833.018
|
||||
]
|
||||
]
|
||||
},
|
||||
"properties": {}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
{"status":"success","project_id":"dad81824-4bb7-41df-ad9c-95c870c2a0dc","revision":0,"structures":[],"definition_version":null}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
{"status":"success","project_id":"dad81824-4bb7-41df-ad9c-95c870c2a0dc","sources":["las","sheet"],"design":"las","grid":{"model_id":624,"smooth":true,"signature":"d5004159dc8bf8b6.cf47fc9738101ba1"}}
|
||||
@@ -0,0 +1,154 @@
|
||||
/* 472-1 헬퍼 — 브라우저 길 기준값(진짜 단계 함수 · vite ssr 묶음 · helper_472_1_browser_entry.ts).
|
||||
* node helper_472_1_browser.mjs <묶음.mjs> <고정 자료 폴더> <격자 .bin>
|
||||
* 페이지 묶음(`design_pipeline_page`)과 같은 단계 붙임 — 저장 노선 · 초안 없음 · 세션 = 메모리 가짜 · fetch 없음 ·
|
||||
* 격자 = 서버 `dtm_grid_bytes` 가 고정 npz 로 지은 이진. 묶음 출력 → 새 노선 상세(`draftSectionDetail`) → 구조물
|
||||
* 면적 얹기 → 누가토량. 표준출력 JSON 한 벌(값 꼴 = test_472_1_golden.py `values_of`). */
|
||||
import { readFileSync } from "node:fs";
|
||||
import { join } from "node:path";
|
||||
import { pathToFileURL } from "node:url";
|
||||
|
||||
const storage = () => {
|
||||
const m = new Map();
|
||||
return {
|
||||
getItem: (k) => (m.has(k) ? m.get(k) : null),
|
||||
setItem: (k, v) => m.set(k, String(v)),
|
||||
removeItem: (k) => m.delete(k),
|
||||
key: (i) => [...m.keys()][i] ?? null,
|
||||
get length() {
|
||||
return m.size;
|
||||
},
|
||||
clear: () => m.clear(),
|
||||
};
|
||||
};
|
||||
globalThis.window = globalThis;
|
||||
globalThis.sessionStorage = storage();
|
||||
globalThis.localStorage = storage();
|
||||
const any = new Proxy(function () {}, {
|
||||
get: (_t, k) => (k === Symbol.toPrimitive ? () => 0 : any),
|
||||
apply: () => any,
|
||||
construct: () => any,
|
||||
});
|
||||
globalThis.document = any;
|
||||
globalThis.requestAnimationFrame = (run) => setTimeout(run, 0);
|
||||
globalThis.fetch = () => Promise.reject(new Error("서버 없음"));
|
||||
|
||||
const [bundle, dir, gridPath] = process.argv.slice(2);
|
||||
const m = await import(pathToFileURL(bundle).href);
|
||||
const read = (name) => JSON.parse(readFileSync(join(dir, name), "utf8"));
|
||||
const detail = read("detail.json");
|
||||
const plan = read("plan.json");
|
||||
const context = read("context.json");
|
||||
const pipes = read("pipes.json").pipe_points.map(({ lonlat: _l, ...pipe }) => pipe);
|
||||
const structures = read("structures.json").structures;
|
||||
const types = read("structure_types.json").types;
|
||||
const plus = read("plus_stations.json").chainages;
|
||||
const P = context.project_id;
|
||||
const R = context.route_id;
|
||||
const bin = readFileSync(gridPath);
|
||||
const grid = m.parseDtmGrid(bin.buffer.slice(bin.byteOffset, bin.byteOffset + bin.byteLength));
|
||||
|
||||
// 페이지가 열 때 세션에 두는 것 — 표준 · 암 경계 기본 · 저장 상세(design_view_profile · 상세 가게)
|
||||
localStorage.setItem("frd_current_project_id", P);
|
||||
m.writeState("std-cross-default", context.standard_cross_section, P);
|
||||
m.writeStateRaw("rock-boundary-default", String(context.rock_boundary_default_offset_m), P);
|
||||
m.writeState("section-detail", detail, P, R);
|
||||
|
||||
const interval = m.SECTION_STATION_INTERVAL_M;
|
||||
const enabled = types.filter((type) => type.enabled !== false);
|
||||
const savedLine = () => plan.planned.map(([x, y]) => [x, y]);
|
||||
const savedCurves = () =>
|
||||
(plan.curves ?? []).map(({ start, apex, end, radius_m }) => ({ start, apex, end, radius_m }));
|
||||
const savedStations = m.buildStations(savedLine(), savedCurves(), pipes, structures, {
|
||||
intervalM: interval,
|
||||
types: enabled,
|
||||
stationSnap: plan.station_snap ?? false,
|
||||
stationSnapStep: plan.station_snap_step,
|
||||
});
|
||||
const crossSource = m.pipelineCrossSource(P, detail, savedStations, R);
|
||||
const edits = m.readAlignment(detail.longitudinal).edits;
|
||||
const status = m.shapeStatus(pipes, structures, types);
|
||||
const bermAt = (list) => {
|
||||
const spans = m.bermSpansFromStructures(Array.isArray(list) ? list : []);
|
||||
return (chainageM) => m.bermSpecAt(spans, chainageM);
|
||||
};
|
||||
const crossStage = m.createCrossStage({ grid: () => ({ grid }) });
|
||||
const pipe = m.createDesignPipeline({
|
||||
stages: {
|
||||
route: m.createRouteStage({
|
||||
minRadiusM: () => plan.min_radius_m ?? 0,
|
||||
savedLine: () => ({ line: savedLine(), curves: savedCurves() }),
|
||||
}),
|
||||
follow: m.createFollowStage({
|
||||
savedLine,
|
||||
saved: () => ({ pipes, structures, alignment: edits }),
|
||||
}),
|
||||
stations: m.createStationsStage({
|
||||
intervalM: interval,
|
||||
types: () => enabled,
|
||||
saved: () => plan,
|
||||
}),
|
||||
ground: m.createGroundStage({
|
||||
grid: () => ({ grid, design: "las" }),
|
||||
remote: () => Promise.reject(new Error("서버 없음")),
|
||||
}),
|
||||
planline: m.createPlanlineStage({
|
||||
savedBase: (at) => m.plantedBase({ base: null, detail }, at, types),
|
||||
savedLine,
|
||||
}),
|
||||
profile: m.profileStage,
|
||||
cross: (ctx) =>
|
||||
crossStage.stage({
|
||||
...ctx,
|
||||
inputs: {
|
||||
...ctx.inputs,
|
||||
cross: m.crossWithContext(
|
||||
ctx.inputs.cross,
|
||||
ctx.out.ground?.stations ?? [],
|
||||
m.shapeStatus(ctx.inputs.pipes, ctx.inputs.structures, types),
|
||||
bermAt(ctx.inputs.structures),
|
||||
),
|
||||
},
|
||||
}),
|
||||
footprint: m.footprintStage,
|
||||
},
|
||||
});
|
||||
const record = await pipe.start({
|
||||
route: null,
|
||||
alignment: edits,
|
||||
cross: crossSource?.input ?? null,
|
||||
pipes,
|
||||
structures,
|
||||
plusStations: plus,
|
||||
});
|
||||
await pipe.settled();
|
||||
if (record.outcome !== "done") throw new Error(`묶음 ${record.outcome}`);
|
||||
|
||||
const ground = pipe.output("ground");
|
||||
const profile = pipe.output("profile");
|
||||
const shown = m.draftSectionDetail(
|
||||
detail,
|
||||
ground,
|
||||
profile,
|
||||
pipe.output("cross"),
|
||||
crossSource?.specs ?? new Map(),
|
||||
interval,
|
||||
status,
|
||||
);
|
||||
m.applyStructureAreaRows(shown.cross_sections, m.structureAreaRows(shown.cross_sections));
|
||||
const haul = m.computeMassHaul(
|
||||
shown.cross_sections,
|
||||
context.earthwork_conversion,
|
||||
context.natural_spoil_min_ground_slope ?? undefined,
|
||||
);
|
||||
process.stdout.write(
|
||||
JSON.stringify({
|
||||
keys: ground.stations.map((station) => station.key),
|
||||
sections: shown.cross_sections,
|
||||
mass_haul: haul,
|
||||
warnings: profile.warnings ?? [],
|
||||
violations: profile.violations ?? [],
|
||||
footprint_records: pipe.output("footprint")?.records?.length ?? 0,
|
||||
skipped: record.skipped,
|
||||
}),
|
||||
);
|
||||
process.exit(0);
|
||||
@@ -0,0 +1,36 @@
|
||||
/* 472-1 기준값 시험 묶음 진입점 — 브라우저 길(진짜 단계 함수 · 묶음 · 상세 · 면적 · 누가토량 · vite ssr).
|
||||
* 짝 = `helper_472_1_browser.mjs` · `test_472_1_golden.py`. */
|
||||
export { createDesignPipeline } from "../../A00_Common/design/logic/design_pipeline";
|
||||
export { createStationsStage } from "../../A00_Common/design/logic/design_pipeline_stations";
|
||||
export { pipelineCrossSource } from "../../A00_Common/design/design_pipeline_cross";
|
||||
export { plantedBase } from "../../A00_Common/design/design_pipeline_base";
|
||||
export {
|
||||
createGroundStage,
|
||||
createRouteStage,
|
||||
} from "../../B05_Profile/logic/B05_Profile_Pipeline_RouteGround";
|
||||
export {
|
||||
createFollowStage,
|
||||
createPlanlineStage,
|
||||
profileStage,
|
||||
} from "../../B05_Profile/logic/B05_Profile_Pipeline_Grade";
|
||||
export {
|
||||
crossWithContext,
|
||||
draftSectionDetail,
|
||||
shapeStatus,
|
||||
} from "../../B05_Profile/logic/B05_Profile_Pipeline_Detail";
|
||||
export {
|
||||
buildStations,
|
||||
SECTION_STATION_INTERVAL_M,
|
||||
} from "../../B05_Profile/logic/B05_Profile_Sections_Stations";
|
||||
export { footprintStage } from "../../B05_Profile/logic/B05_Profile_Footprint_Stage";
|
||||
export { readAlignment } from "../../B05_Profile/logic/B05_Profile_UI_Profile_Data";
|
||||
export { planElevationAt } from "../../B05_Profile/logic/B05_Profile_UI_Profile_Alignment";
|
||||
export { createCrossStage } from "../../B06_Section/logic/B06_Section_Cross_Stage";
|
||||
export {
|
||||
applyStructureAreaRows,
|
||||
structureAreaRows,
|
||||
} from "../../B06_Section/B06_Section_Structure_Layouts";
|
||||
export { bermSpansFromStructures, bermSpecAt } from "../../B06_Section/B06_Section_UI_Page_Persist";
|
||||
export { parseDtmGrid } from "../../common_util/common_util_surface_sampler";
|
||||
export { computeMassHaul } from "../../common_util/common_util_mass_haul";
|
||||
export { writeState, writeStateRaw } from "../../A00_Common/b_page_state";
|
||||
@@ -0,0 +1,99 @@
|
||||
"""472-1 고정 자료 · 값 다시 뜨기(사용자 · 브레인 승인 때만 손으로 돌림 — 시험은 다시 안 뜸).
|
||||
|
||||
./venv/Scripts/python.exe resources/tester/helper_472_1_dump.py # 값만 다시
|
||||
./venv/Scripts/python.exe resources/tester/helper_472_1_dump.py --fetch # 고정 자료도
|
||||
|
||||
--fetch = 검증_랩탑메인(`PROJECT`) 노선 하나를 **읽기만**(GET · storage 파일 사본) —
|
||||
쓰기 · 저장 · 지움 없음.
|
||||
서버 = 자기 포트(`--base` · 기본 8004) · 로그인 = 메인 폴더 `tmp/aislo_cred.json`(값은 출력 안 함).
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import shutil
|
||||
import sys
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
|
||||
HERE = Path(__file__).resolve().parent
|
||||
sys.path.insert(0, str(HERE.parents[1]))
|
||||
sys.path.insert(0, str(HERE))
|
||||
|
||||
import helper_472_1_paths as paths # noqa: E402
|
||||
|
||||
PROJECT = "dad81824-4bb7-41df-ad9c-95c870c2a0dc"
|
||||
MAIN = Path("C:/Program_coding/임도설계 및 견적자동화 프로그램 개발")
|
||||
#: storage 사본 — 노선 저장 체인 · [저장] 재계산이 읽는 파일만(노선 · 곡선표 · 관 · 설계 지표면).
|
||||
STORAGE_FILES = (
|
||||
"B05_Profile/route/route_main.geojson",
|
||||
"B05_Profile/route/planned_route_initial.csv",
|
||||
"B05_Profile/route/planned_route_initial_curves.json",
|
||||
"B05_Profile/route/planned_route_initial_nodes.csv",
|
||||
"B04_PreProcess/drainage/edits/pipe_points.json",
|
||||
paths.NPZ,
|
||||
)
|
||||
|
||||
|
||||
def fetch(base: str) -> None:
|
||||
import httpx
|
||||
|
||||
cred = json.loads((MAIN / "tmp" / "aislo_cred.json").read_text(encoding="utf-8"))
|
||||
client = httpx.Client(base_url=f"{base}/api", timeout=120)
|
||||
login = client.post(
|
||||
"/auth/login/request", json={"email": cred["email"], "password": cred["password"]}
|
||||
)
|
||||
login.raise_for_status()
|
||||
get = lambda path: client.get(path).raise_for_status().json() # noqa: E731
|
||||
latest = get(f"/projects/{PROJECT}/route/latest")
|
||||
route = int(latest["route"]["id"])
|
||||
out = {
|
||||
"detail.json": get(f"/projects/{PROJECT}/sections/{route}/detail"),
|
||||
"summary.json": get(f"/projects/{PROJECT}/sections/{route}"),
|
||||
"context.json": get(f"/projects/{PROJECT}/sections/context"),
|
||||
"plan.json": get(f"/projects/{PROJECT}/route/plan"),
|
||||
"pipes.json": {
|
||||
"pipe_points": get(f"/projects/{PROJECT}/drainage/pipe-points")["pipe_points"]
|
||||
},
|
||||
"structures.json": get(f"/projects/{PROJECT}/route/structures"),
|
||||
"plus_stations.json": get(f"/projects/{PROJECT}/section/plus-stations"),
|
||||
"structure_types.json": get("/projects/structure-types"),
|
||||
"terrain_sources.json": get(f"/projects/{PROJECT}/route/terrain-sources"),
|
||||
}
|
||||
assert out["context.json"]["route_id"] == route
|
||||
paths.FIXTURE.mkdir(parents=True, exist_ok=True)
|
||||
for name, body in out.items():
|
||||
(paths.FIXTURE / name).write_text(
|
||||
json.dumps(body, ensure_ascii=False, separators=(",", ":")), encoding="utf-8"
|
||||
)
|
||||
project = next((MAIN / "storage").glob(f"*/*/{PROJECT}"))
|
||||
for relative in STORAGE_FILES:
|
||||
target = paths.FIXTURE / "project" / relative # 폴더 이름 storage = .gitignore
|
||||
target.parent.mkdir(parents=True, exist_ok=True)
|
||||
shutil.copy2(project / relative, target)
|
||||
|
||||
|
||||
def dump() -> dict:
|
||||
values: dict = {"project_id": PROJECT}
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
for name in paths.PATHS:
|
||||
work = Path(tmp) / name
|
||||
work.mkdir()
|
||||
values[name] = paths.run_path(name, work)
|
||||
paths.VALUES.write_text(json.dumps(values, ensure_ascii=False, indent=1), encoding="utf-8")
|
||||
return values
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--fetch", action="store_true")
|
||||
parser.add_argument("--base", default="http://localhost:8004")
|
||||
args = parser.parse_args()
|
||||
if args.fetch:
|
||||
fetch(args.base)
|
||||
got = dump()
|
||||
size = sum(p.stat().st_size for p in paths.FIXTURE.rglob("*") if p.is_file())
|
||||
print(f"고정 자료 {size / 1e6:.2f} MB")
|
||||
for name in paths.PATHS:
|
||||
print(name, got[name]["station_count"], got[name]["final_cumulative_m3"])
|
||||
@@ -0,0 +1,323 @@
|
||||
"""472-1 기준값 — 고정 자료(`fixtures/golden_472`) 하나로 길 넷의 값을 뜸(시험 · 값 뜨기 함께 씀).
|
||||
|
||||
stored GET 상세(정본 그대로) → 누가토량(서버 Node 묶음 `computeMassHaul`)
|
||||
server_save [저장] 서버 재계산 — 정본 상세 → `enforce_design_lines` →
|
||||
`_enforce_stored_designs` → server-calc
|
||||
server_route 노선 저장 체인(같은 노선 · DB 없이) — `run_section_generation`(고정 geojson · npz)
|
||||
→ `_carry_profile` 같은 노선 갈래(옛 base_pvi · 편집) → `_apply_alignment_edits` →
|
||||
측점 열쇠 이월(`carry_cross_inputs`) → `compute_default_designs` → 상세 읽기 →
|
||||
server_save 와 같은 끝
|
||||
browser 진짜 단계 함수 묶음(`helper_472_1_browser.mjs` · vite ssr) — 격자 = 같은 npz 의
|
||||
`dtm_grid_bytes`
|
||||
|
||||
값 꼴(`values_of`) — 측점마다 열쇠 · 누가거리(0.01) · x · y(0.001) · 계획고(0.001) · 면적(0.0001) ·
|
||||
측구 · 층따기 밑수 · 단면 모양 · 누가토량(0.01) + 끝값 · 관 길이 · 종단 경고.
|
||||
DB · 서버 · 사용자 storage 안 씀(고정 자료 사본만).
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import copy
|
||||
import json
|
||||
import shutil
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
HERE = Path(__file__).resolve().parent
|
||||
ROOT = HERE.parents[1]
|
||||
FIXTURE = HERE / "fixtures" / "golden_472"
|
||||
VALUES = FIXTURE / "golden_472_values.json"
|
||||
ROUTE = "B05_Profile/route/route_main.geojson"
|
||||
LONG = "B06_Section/longitudinal/longitudinal.json"
|
||||
NPZ = "B04_PreProcess/models/dtm_classification_smooth.npz"
|
||||
SURFACE = ("classification", "dtm", True)
|
||||
|
||||
|
||||
def read(name: str) -> Any:
|
||||
return json.loads((FIXTURE / name).read_text(encoding="utf-8"))
|
||||
|
||||
|
||||
def stage_project(root: Path) -> Path:
|
||||
"""고정 storage 사본을 임시 프로젝트 뿌리로 — 체인이 파일을 쓰므로 늘 새 사본."""
|
||||
shutil.copytree(FIXTURE / "project", root, dirs_exist_ok=True)
|
||||
return root
|
||||
|
||||
|
||||
# ── 값 꼴 ────────────────────────────────────────────────────────────────────
|
||||
|
||||
|
||||
def _r(value: Any, digits: int) -> float | None:
|
||||
return round(float(value), digits) if isinstance(value, (int, float)) else None
|
||||
|
||||
|
||||
def values_of(
|
||||
sections: list[dict[str, Any]],
|
||||
keys: list[str | None],
|
||||
mass_haul: dict[str, Any] | None,
|
||||
warnings: list[str],
|
||||
violations: list[dict[str, Any]],
|
||||
) -> dict[str, Any]:
|
||||
"""상세 측점(누가거리 차례) · 열쇠 · 누가토량 → 비교 값. 누가토량은 같은 측점 id 로 짝."""
|
||||
rows = sorted(zip(sections, keys, strict=True), key=lambda pair: float(pair[0]["chainage_m"]))
|
||||
points = {p["station_id"]: p for p in (mass_haul or {}).get("points") or []}
|
||||
stations = []
|
||||
for section, key in rows:
|
||||
design = section.get("design") or {}
|
||||
point = points.get(section.get("station_id")) or {}
|
||||
stations.append(
|
||||
{
|
||||
"key": key,
|
||||
"chainage_m": _r(section["chainage_m"], 2),
|
||||
"x": _r(section.get("center_x"), 3),
|
||||
"y": _r(section.get("center_y"), 3),
|
||||
"plan_z": _r(design.get("design_elevation_m"), 3),
|
||||
"mode": design.get("section_mode"),
|
||||
"cut_m2": _r(design.get("cut_area_m2"), 4),
|
||||
"fill_m2": _r(design.get("fill_area_m2"), 4),
|
||||
"cut_soil_m2": _r(design.get("cut_soil_area_m2"), 4),
|
||||
"cut_rock_m2": _r(design.get("cut_rock_area_m2"), 4),
|
||||
"ditch_m2": _r(design.get("ditch_area_m2"), 4),
|
||||
"bench_m": _r(design.get("bench_cut_length_m"), 4),
|
||||
"pipe_length_m": _r(design.get("pipe_length_m"), 2),
|
||||
"cumulative_m3": _r(point.get("cumulative_volume_m3"), 2),
|
||||
}
|
||||
)
|
||||
return {
|
||||
"station_count": len(stations),
|
||||
"stations": stations,
|
||||
"final_cumulative_m3": _r((mass_haul or {}).get("final_cumulative_m3"), 2),
|
||||
"pipe_lengths": {
|
||||
s["key"]: s["pipe_length_m"] for s in stations if s["pipe_length_m"] is not None
|
||||
},
|
||||
"warnings": sorted(warnings),
|
||||
"violations": len(violations),
|
||||
}
|
||||
|
||||
|
||||
def _keys(longitudinal: dict[str, Any], sections: list[dict[str, Any]], root: Path) -> list:
|
||||
"""서버 측점 열쇠(`station_keys` · 노선 저장 이월이 쓰는 한 벌) — 상세 측점 차례."""
|
||||
from B05_Profile.B05_Profile_Route_Save_Parts import station_keys
|
||||
from B05_Profile.B05_Profile_Structures_Repository import load_structures
|
||||
from common_util.common_util_drainage_pipes import pipe_points_path_in, read_pipe_points_file
|
||||
|
||||
pipes = read_pipe_points_file(pipe_points_path_in(root))
|
||||
_, structures = load_structures(str(root))
|
||||
interval = float(
|
||||
(longitudinal.get("profile_alignment") or {}).get("policy", {}).get("station_interval_m")
|
||||
or 20.0
|
||||
)
|
||||
found = station_keys(longitudinal.get("stations") or [], pipes, structures, interval)
|
||||
by_m = {round(at, 3): key for key, at in found.items()}
|
||||
return [by_m.get(round(float(s["chainage_m"]), 3)) for s in sections]
|
||||
|
||||
|
||||
# ── 서버 끝(server_save · server_route 공통) ──────────────────────────────────
|
||||
|
||||
|
||||
def _context() -> dict[str, Any]:
|
||||
"""유토곡선 문맥 — 서버 `_mass_haul_context` + 고정 자료 계수 · 장비 경계(화면이 받는 값)."""
|
||||
from B06_Section.B06_Section_Server_Calc_Prebuild import _mass_haul_context
|
||||
|
||||
context = read("context.json")
|
||||
limits = [(row["key"], row["max_distance_m"]) for row in context["haul_equipment_limits"]]
|
||||
return _mass_haul_context(None, context["earthwork_conversion"], limits)
|
||||
|
||||
|
||||
def _save_tail(detail: dict[str, Any], root: Path) -> tuple[list, dict | None]:
|
||||
"""[저장] 재계산 본문(`_recompute`) — 설계선 · 넓힘 · 보정 → Node 면적 · 누가토량 얹음."""
|
||||
from B06_Section.B06_Section_Router_Design import enforce_design_lines
|
||||
from B06_Section.B06_Section_Server_Calc_Prebuild import (
|
||||
_AREA_KEYS,
|
||||
_NPM_SCRIPT,
|
||||
BUNDLE,
|
||||
_enforce_stored_designs,
|
||||
)
|
||||
from common_util.common_util_node_bundle import run_bundle_json
|
||||
from common_util.common_util_surface_sampler import build_surface_sampler
|
||||
|
||||
longitudinal = detail["longitudinal"]
|
||||
sections = detail["cross_sections"]
|
||||
enforce_design_lines(longitudinal, sections, root, None)
|
||||
unclosed = any((s.get("design") or {}).get("slope_unclosed") for s in sections)
|
||||
sampler = (
|
||||
build_surface_sampler(root / "B04_PreProcess" / "models", *SURFACE) if unclosed else None
|
||||
)
|
||||
_enforce_stored_designs(longitudinal, sections, root, None, sampler)
|
||||
detail = json.loads(
|
||||
json.dumps(detail, default=str)
|
||||
) # 응답 직렬화와 같은 꼴(`model_dump(json)`)
|
||||
output = run_bundle_json(BUNDLE, _NPM_SCRIPT, {"detail": detail, "context": _context()})
|
||||
if not isinstance(output, dict):
|
||||
raise RuntimeError("server-calc 묶음 실패")
|
||||
sections = detail["cross_sections"]
|
||||
for row in output.get("areas") or []:
|
||||
for section in sections:
|
||||
if abs(float(section["chainage_m"]) - float(row["chainage_m"])) < 1e-6:
|
||||
design = section.setdefault("design", {})
|
||||
design.update(
|
||||
{k: row[k] for k in _AREA_KEYS if isinstance(row.get(k), (int, float))}
|
||||
)
|
||||
return sections, output.get("mass_haul")
|
||||
|
||||
|
||||
def server_save(root: Path) -> dict[str, Any]:
|
||||
detail = copy.deepcopy(read("detail.json"))
|
||||
alignment = detail["longitudinal"].get("profile_alignment") or {}
|
||||
keys = _keys(detail["longitudinal"], detail["cross_sections"], root)
|
||||
sections, haul = _save_tail(detail, root)
|
||||
return values_of(
|
||||
sections, keys, haul, alignment.get("warnings") or [], alignment.get("violations") or []
|
||||
)
|
||||
|
||||
|
||||
def server_route(root: Path) -> dict[str, Any]:
|
||||
"""노선 저장 체인 — 같은 노선(바뀐 구간 없음) · DB 행 대신 고정 자료(요약 옵션 · 정본 설계)."""
|
||||
from B05_Profile.B05_Profile_Engine_Grade import GradeDesignOptions
|
||||
from B05_Profile.B05_Profile_Engine_Grade_Carry import carry_policy
|
||||
from B05_Profile.B05_Profile_Engine_Sections import run_section_generation
|
||||
from B05_Profile.B05_Profile_Engine_Sections_Core import SectionGenerationOptions
|
||||
from B05_Profile.B05_Profile_Route_Save_Parts import carry_cross_inputs, station_keys
|
||||
from B05_Profile.B05_Profile_Router import _apply_alignment_edits
|
||||
from B05_Profile.B05_Profile_Structures_Repository import load_structures
|
||||
from B06_Section.B06_Section_Engine_Design import ROUTE_CARRY_KEYS
|
||||
from B06_Section.B06_Section_Router import _read_section_detail
|
||||
from B06_Section.B06_Section_Router_Design import (
|
||||
CARRY_INPUT_KEYS,
|
||||
STRUCTURE_ADJUST_KEYS,
|
||||
attach_default_designs,
|
||||
compute_default_designs,
|
||||
)
|
||||
from common_util.common_util_drainage_pipes import pipe_points_path_in, read_pipe_points_file
|
||||
from common_util.common_util_json import atomic_write_json
|
||||
|
||||
saved = read("detail.json")
|
||||
summary = read("summary.json")["longitudinal"]["data"]
|
||||
options = {k: v for k, v in summary["options"].items() if k != "extra_stations"}
|
||||
run_section_generation(
|
||||
root,
|
||||
ROUTE,
|
||||
*SURFACE,
|
||||
options=SectionGenerationOptions(**options),
|
||||
grade_options=GradeDesignOptions(**summary["grade_options"]),
|
||||
crs=f"EPSG:{read('context.json')['crs_epsg']}",
|
||||
)
|
||||
# 계획고 옮김(`_carry_profile` · 바뀐 구간 없음 = 옛 base_pvi · 편집 통째)
|
||||
old = saved["longitudinal"]["profile_alignment"]
|
||||
longitudinal = json.loads((root / LONG).read_text(encoding="utf-8"))
|
||||
alignment = longitudinal.get("profile_alignment") or {}
|
||||
line = json.loads((root / ROUTE).read_text(encoding="utf-8"))["geometry"]["coordinates"]
|
||||
xy = [[float(p[0]), float(p[1])] for p in line]
|
||||
alignment["policy"] = carry_policy(xy, xy, old, alignment)
|
||||
alignment["base_pvi"] = old["base_pvi"]
|
||||
longitudinal["profile_alignment"] = alignment
|
||||
atomic_write_json(root / LONG, longitudinal)
|
||||
alignment, _summary, _dropped = _apply_alignment_edits(root, LONG, old.get("edits") or {})
|
||||
# 횡단 이월(`_carry_cross`) — 측점 열쇠로 정본 사용자 입력 → 새 측점 · 전 측점 새 계획고로 셈
|
||||
new_long = json.loads((root / LONG).read_text(encoding="utf-8"))
|
||||
pipes = read_pipe_points_file(pipe_points_path_in(root))
|
||||
_, structures = load_structures(str(root))
|
||||
interval = float(options["station_interval_m"])
|
||||
old_keys = station_keys(saved["longitudinal"]["stations"], pipes, structures, interval)
|
||||
new_keys = station_keys(new_long.get("stations") or [], pipes, structures, interval)
|
||||
designs = {
|
||||
round(float(s["chainage_m"]), 3): s["design"]
|
||||
for s in saved["cross_sections"]
|
||||
if isinstance(s.get("design"), dict)
|
||||
}
|
||||
inputs, adjusts, _ = carry_cross_inputs(
|
||||
old_keys, new_keys, designs, (*CARRY_INPUT_KEYS, *ROUTE_CARRY_KEYS), STRUCTURE_ADJUST_KEYS
|
||||
)
|
||||
chainages = [float(s["chainage_m"]) for s in new_long.get("stations") or []]
|
||||
entries = compute_default_designs(root, LONG, chainages, None, inputs)
|
||||
by_m = {round(at, 3): {**design, **adjusts.get(round(at, 3), {})} for at, design in entries}
|
||||
# [확정] 상세 읽기(`get_section_detail`) — 행 설계(0.01 m) 얹기 · 없는 측점 기본값
|
||||
detail = _read_section_detail(root, LONG)
|
||||
for section in detail["cross_sections"]:
|
||||
hit = next(
|
||||
(d for at, d in by_m.items() if abs(at - float(section["chainage_m"])) < 0.01), None
|
||||
)
|
||||
if hit is not None:
|
||||
section["design"] = hit
|
||||
attach_default_designs(detail["longitudinal"], detail["cross_sections"], root, None)
|
||||
keys = _keys(detail["longitudinal"], detail["cross_sections"], root)
|
||||
sections, haul = _save_tail(detail, root)
|
||||
return values_of(
|
||||
sections, keys, haul, alignment.get("warnings") or [], alignment.get("violations") or []
|
||||
)
|
||||
|
||||
|
||||
def stored(root: Path) -> dict[str, Any]:
|
||||
"""정본 그대로 — GET 상세 면적 · 서버 Node 묶음과 같은 누가토량(화면 배지 값)."""
|
||||
from B06_Section.B06_Section_Server_Calc_Prebuild import _NPM_SCRIPT, BUNDLE
|
||||
from common_util.common_util_node_bundle import run_bundle_json
|
||||
|
||||
detail = read("detail.json")
|
||||
alignment = detail["longitudinal"].get("profile_alignment") or {}
|
||||
keys = _keys(detail["longitudinal"], detail["cross_sections"], root)
|
||||
output = run_bundle_json(BUNDLE, _NPM_SCRIPT, {"detail": detail, "context": _context()})
|
||||
haul = (output or {}).get("mass_haul")
|
||||
return values_of(
|
||||
detail["cross_sections"],
|
||||
keys,
|
||||
haul,
|
||||
alignment.get("warnings") or [],
|
||||
alignment.get("violations") or [],
|
||||
)
|
||||
|
||||
|
||||
# ── 브라우저 길 ──────────────────────────────────────────────────────────────
|
||||
|
||||
|
||||
def browser(work: Path) -> dict[str, Any]:
|
||||
"""vite ssr 로 진짜 모듈을 묶어 헬퍼를 돌림(`helper_272_detail_memory` 꼴) · 격자 = 고정 npz."""
|
||||
from common_util.common_util_surface_sampler import dtm_grid_bytes
|
||||
|
||||
grid = work / "grid.bin"
|
||||
grid.write_bytes(dtm_grid_bytes(FIXTURE / "project" / NPZ))
|
||||
build = subprocess.run( # noqa: S603 — 고정 실행 파일
|
||||
[
|
||||
"node",
|
||||
str(ROOT / "config" / "node_modules" / "vite" / "bin" / "vite.js"),
|
||||
"build",
|
||||
"--configLoader",
|
||||
"runner",
|
||||
"--ssr",
|
||||
"../resources/tester/helper_472_1_browser_entry.ts",
|
||||
"--outDir",
|
||||
str(work / "b"),
|
||||
"--logLevel",
|
||||
"error",
|
||||
],
|
||||
cwd=ROOT,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
encoding="utf-8",
|
||||
timeout=300,
|
||||
)
|
||||
if build.returncode:
|
||||
raise RuntimeError(build.stderr)
|
||||
bundle = work / "b" / "bundle.mjs" # 조각(assets/)과 같은 폴더
|
||||
shutil.copy(work / "b" / "helper_472_1_browser_entry.js", bundle)
|
||||
proc = subprocess.run( # noqa: S603 — 고정 실행 파일
|
||||
["node", str(HERE / "helper_472_1_browser.mjs"), str(bundle), str(FIXTURE), str(grid)],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
encoding="utf-8",
|
||||
timeout=120,
|
||||
)
|
||||
if proc.returncode:
|
||||
raise RuntimeError(proc.stderr)
|
||||
out = json.loads(proc.stdout)
|
||||
return values_of(
|
||||
out["sections"], out["keys"], out["mass_haul"], out["warnings"], out["violations"]
|
||||
)
|
||||
|
||||
|
||||
PATHS = ("stored", "server_save", "server_route", "browser")
|
||||
|
||||
|
||||
def run_path(name: str, work: Path) -> dict[str, Any]:
|
||||
if name == "browser":
|
||||
return browser(work)
|
||||
return globals()[name](stage_project(work / "project"))
|
||||
@@ -0,0 +1,149 @@
|
||||
"""PLAN 472-1 (요구 273) — B05 · B06 기준값 시험 · 구조 다시 세움 단계마다의 문.
|
||||
|
||||
고정 자료 `fixtures/golden_472/`(검증_랩탑메인 노선 370 · 읽기만 뜸) 하나로 길 넷의 값을 떠
|
||||
`golden_472_values.json` 과 견줌(값 꼴 · 길 = `helper_472_1_paths.py` 머리).
|
||||
|
||||
못박는 것
|
||||
- 길마다 자기 값과 0 차 — 측점(수 · 열쇠 · 누가거리 · x · y) · 계획고 ·
|
||||
면적(절 · 성 · 토사 · 암 · 측구) · 층따기 밑수 · 단면 모양 · 누가토량(측점별 · 끝값) ·
|
||||
관 길이 · 종단 경고 · 기울기 위반 수.
|
||||
- 두 길 사이 = 「알려진 차」(`KNOWN`)만 · 그 밖 차는 실패 · 안 나타난 알려진 차도 실패
|
||||
(목록에서 지움 — 472-4 가 짝을 하나 옮길 때마다 한 줄씩 지워 마지막에 빈 목록).
|
||||
- 화면 참값 — 정본 누가토량 −17,570.70 ㎥ · 측점 57(465 기준값).
|
||||
이 고정 자료가 안 거치는 짝인데 값이 갈리는 자리 — X1 단면 모양 기본값(설계 없는 새 측점 없음) ·
|
||||
X3 면적 두 갈래(구조물 = 관 351 하나 · 두 길 다 Node TS 로 셈) · X4 · X6(노선 안 바뀜).
|
||||
값 다시 뜨기 = `helper_472_1_dump.py`(승인 때만 · 시험은 다시 안 뜸).
|
||||
|
||||
./venv/Scripts/python.exe -m pytest resources/tester/test_472_1_golden.py -q
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from dataclasses import dataclass
|
||||
|
||||
import helper_472_1_paths as paths
|
||||
import pytest
|
||||
|
||||
pytestmark = pytest.mark.skipif(
|
||||
not (paths.ROOT / "config" / "node_modules" / "vite").is_dir(),
|
||||
reason="프론트엔드 의존성 미설치",
|
||||
)
|
||||
|
||||
GOLDEN = json.loads(paths.VALUES.read_text(encoding="utf-8"))
|
||||
AREAS = ("cut_m2", "fill_m2", "cut_soil_m2", "cut_rock_m2", "ditch_m2")
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class Known:
|
||||
"""알려진 차 한 줄 — 칸 → 허용 폭(None = 같지 않아도 됨 · 글 칸) · 까닭."""
|
||||
|
||||
id: str
|
||||
fields: dict[str, float | None]
|
||||
why: str
|
||||
|
||||
|
||||
KNOWN: dict[tuple[str, str], list[Known]] = {
|
||||
(
|
||||
"server_save",
|
||||
"stored",
|
||||
): [], # [저장] 재계산 = 정본 그대로(사용자 원칙 — 입력 안 바뀌면 값 안 바뀜)
|
||||
("server_route", "stored"): [
|
||||
Known(
|
||||
"R7",
|
||||
{"fill_m2": 0.00011, "cumulative_m3": 0.011},
|
||||
"다시 뜬 표본 마지막 자리 — grid:37 성토 1e-4 ㎡ · 누가토량 0.01 ㎥ 넷(끝값 같음)",
|
||||
),
|
||||
Known(
|
||||
"W0",
|
||||
{"warnings": None},
|
||||
"정본 종단 경고 = 10-17 저장 때 코드(법정 R · L 미달 46 줄 전) · "
|
||||
"[저장] 재계산은 종단 경고를 안 씀",
|
||||
),
|
||||
],
|
||||
("browser", "server_route"): [
|
||||
Known(
|
||||
"X2",
|
||||
{
|
||||
"x": 0.002,
|
||||
"y": 0.002,
|
||||
**dict.fromkeys(AREAS, 0.1),
|
||||
"bench_m": 1.0,
|
||||
"cumulative_m3": 2.0,
|
||||
"final_cumulative_m3": 1.0,
|
||||
},
|
||||
"입력 선 — 브라우저 /route/plan planned(0.1 mm) · 서버 노선 geojson(1 mm) · "
|
||||
"측점 자리 ≤ 1 mm → 표본 · 면적 ≤ 0.07 ㎡ · 층따기 밑수 ≤ 0.52 m · "
|
||||
"누가토량 끝값 0.69 ㎥(−17,570.01 ↔ −17,570.70)",
|
||||
),
|
||||
Known(
|
||||
"W1",
|
||||
{"warnings": None},
|
||||
"종단 경고 글 두 벌(X5 · P8) — TS 「340.0m: …」 · 파이썬 「chainage 340.0m: …」 · "
|
||||
"최대 기울기 총괄 줄은 파이썬만",
|
||||
),
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def got(tmp_path_factory) -> dict:
|
||||
out = {}
|
||||
for name in paths.PATHS:
|
||||
out[name] = paths.run_path(name, tmp_path_factory.mktemp(name))
|
||||
return out
|
||||
|
||||
|
||||
def diffs(a: dict, b: dict) -> list[tuple[str, str, object, object]]:
|
||||
"""(칸, 측점 열쇠, a, b) — 측점은 같은 차례(수가 다르면 측점 수 한 줄)."""
|
||||
out = []
|
||||
for field in ("station_count", "final_cumulative_m3", "pipe_lengths", "warnings", "violations"):
|
||||
if a[field] != b[field]:
|
||||
out.append((field, "-", a[field], b[field]))
|
||||
if a["station_count"] == b["station_count"]:
|
||||
for x, y in zip(a["stations"], b["stations"], strict=True):
|
||||
out += [(k, x["key"], x[k], y[k]) for k in x if x[k] != y[k]]
|
||||
return out
|
||||
|
||||
|
||||
def allowed(diff: tuple, known: Known) -> bool:
|
||||
field, _key, a, b = diff
|
||||
if field not in known.fields:
|
||||
return False
|
||||
width = known.fields[field]
|
||||
if width is None:
|
||||
return True
|
||||
return isinstance(a, (int, float)) and isinstance(b, (int, float)) and abs(a - b) <= width
|
||||
|
||||
|
||||
@pytest.mark.parametrize("name", paths.PATHS)
|
||||
def test_길마다_기준값_그대로(got, name) -> None:
|
||||
found = diffs(got[name], GOLDEN[name])
|
||||
assert not found, f"{name} 기준값과 다름 {len(found)}곳 — 앞 10: {found[:10]}"
|
||||
|
||||
|
||||
@pytest.mark.parametrize("pair", list(KNOWN), ids=lambda pair: f"{pair[0]}-{pair[1]}")
|
||||
def test_두_길_사이_알려진_차만(got, pair) -> None:
|
||||
known = KNOWN[pair]
|
||||
found = diffs(got[pair[0]], got[pair[1]])
|
||||
stray = [d for d in found if not any(allowed(d, k) for k in known)]
|
||||
assert not stray, f"알려진 차 밖 {len(stray)}곳 — 앞 10: {stray[:10]}"
|
||||
gone = [k.id for k in known if not any(allowed(d, k) for d in found)]
|
||||
assert not gone, f"안 나타난 알려진 차 {gone} — KNOWN 에서 지움"
|
||||
|
||||
|
||||
def test_화면_참값() -> None:
|
||||
stored = GOLDEN["stored"]
|
||||
assert stored["final_cumulative_m3"] == -17570.7
|
||||
assert stored["station_count"] == 57
|
||||
assert stored["pipe_lengths"] == {"pipe:p35100": 7.9}
|
||||
|
||||
|
||||
def test_고정_자료_크기() -> None:
|
||||
size = sum(p.stat().st_size for p in paths.FIXTURE.rglob("*") if p.is_file())
|
||||
assert size < 5e6
|
||||
|
||||
|
||||
@pytest.mark.skip(reason="API 왕복(목록 4.2 ③ 선택) — 472-1 에서 건너뜀")
|
||||
def test_API_왕복() -> None:
|
||||
raise AssertionError
|
||||
Reference in New Issue
Block a user