|
1 | 1 | """ |
| 2 | +DTA = the dynamic traffic assignment model |
| 3 | +
|
| 4 | +This script is developed to automatically establish the corresponding relationship between CMP segments and the DTA network links. |
| 5 | +It finds DTA links that are near each CMP segment and decides the matching links based on street name, angle and distance attributes. |
| 6 | +
|
| 7 | +File was last touched 2022/12/9 |
| 8 | +The docstring (only above here) was amended then committed to repo 2023/4/6 |
| 9 | +
|
| 10 | +The rest of this docstring has not been updated to reflect any changes between the swap from doing conflation on the INRIX network vs the DTA network: |
| 11 | +
|
2 | 12 | This script is developed to automatically establish the corresponding relationship between CMP segments and INRIX XD network links. |
3 | 13 | It finds INRIX links that are near each CMP segment and decides the matching links based on street name, angle and distance attributes. |
4 | 14 |
|
|
21 | 31 | python SF_CMP_INRIX_Network_Conflation.py |
22 | 32 | """ |
23 | 33 |
|
24 | | -MAP_VER = 2301 |
| 34 | +MAP_VER = 2202 |
25 | 35 |
|
26 | 36 | # Specify input file names |
27 | 37 | # INRIX XD network |
28 | | -inrix_sf = f"INRIX_XD-SF-{MAP_VER}" # .gpkg' # HOTFIX, leaving the extension hardcoded below |
29 | | -segid_col = "XDSegID" |
| 38 | +# dta = 'inrix_xd_sf' |
| 39 | +dta = "links" |
| 40 | +segid_col = "ID" |
30 | 41 | # CMP network |
31 | | -# CMP network (as in the reports) |
32 | | -# cmp = "Q:\GIS\Transportation\Roads\CMP\cmp_roadway_segments" # .shp" # HOTFIX, leaving the extension hardcoded below |
33 | | -# online COVID congestion tracker network: |
34 | | -cmp = "Q:\CMP\LOS Monitoring 2022\CMP_exp_shp\cmp_segments_exp_v2201" # .shp" # HOTFIX, leaving the extension hardcoded below |
| 42 | +cmp = "cmp_segments_exp_v2201" |
35 | 43 |
|
36 | 44 |
|
37 | 45 | import math |
38 | | -import os |
39 | 46 | import warnings |
40 | 47 |
|
41 | 48 | # Import needed python modules |
|
56 | 63 | "no_defs": True, |
57 | 64 | } |
58 | 65 | # Define NAD 1983 StatePlane California III |
59 | | -cal3 = { |
60 | | - "proj": "lcc +lat_1=37.06666666666667 +lat_2=38.43333333333333 +lat_0=36.5 +lon_0=-120.5 +x_0=2000000 +y_0=500000.0000000002", |
61 | | - "ellps": "GRS80", |
62 | | - "datum": "NAD83", |
63 | | - "no_defs": True, |
64 | | -} |
| 66 | +# cal3 = {'proj': 'lcc +lat_1=37.06666666666667 +lat_2=38.43333333333333 +lat_0=36.5 +lon_0=-120.5 +x_0=2000000 +y_0=500000.0000000002', 'ellps': 'GRS80', 'datum': 'NAD83', 'no_defs': True} |
| 67 | +cal = "epsg:2227" |
65 | 68 |
|
66 | 69 | # Convert original coordinate system to California III state plane |
67 | 70 | # CMP network |
68 | 71 | cmp_segs_org = gp.read_file(cmp + ".shp") |
69 | 72 | cmp_segs_prj = cmp_segs_org.to_crs(cal3) |
70 | 73 | cmp_segs_prj["cmp_name"] = cmp_segs_prj["cmp_name"].str.replace("/ ", "/") |
71 | 74 | cmp_segs_prj["Length"] = cmp_segs_prj.geometry.length |
72 | | -cmp_segs_prj["Length"] = cmp_segs_prj["Length"] * 3.2808 # meters to feet |
73 | | -cmp_segs_prj.to_file(os.path.splitext(cmp)[0] + "_prj.shp") |
| 75 | +# cmp_segs_prj['Length'] = cmp_segs_prj['Length'] * 3.2808 #meters to feet (REMOVING, EPSG:2227 is in feet |
| 76 | +cmp_segs_prj.to_file(cmp + "_prj.shp") |
74 | 77 |
|
75 | 78 | # INRIX XD network |
76 | | -inrix_net_org = gp.read_file( |
77 | | - inrix_sf + ".gpkg" |
78 | | -) # HOTFIX, leaving this hardcoded for now, switched from .shp to .gpkg |
79 | | -inrix_net_prj = inrix_net_org.to_crs(cal3) |
80 | | -inrix_net_prj["Length"] = inrix_net_prj.geometry.length |
81 | | -inrix_net_prj["Length"] = inrix_net_prj["Length"] * 3.2808 # meters to feet |
82 | | -inrix_net_prj["SegID"] = inrix_net_prj[segid_col].astype(int) |
83 | | -inrix_net_prj["Miles"] = inrix_net_prj["Miles"].astype(float) |
84 | | -inrix_net_prj = inrix_net_prj.rename( |
85 | | - columns={"PreviousXD": "PreviousSe", "NextXDSegI": "NextSegID"} |
86 | | -) |
87 | | -inrix_net_prj.to_file(os.path.splitext(inrix_sf)[0] + "_prj.shp") |
| 79 | +dta_net_org = gp.read_file(dta + ".shp") |
| 80 | +dta_net_prj = dta_net_org.to_crs(cal3) |
| 81 | +dta_net_prj["Length"] = dta_net_prj.geometry.length |
| 82 | +# dta_net_prj['Length'] = dta_net_prj['Length'] * 3.2808 #meters to feet #meters to feet (REMOVING, EPSG:2227 is in feet |
| 83 | +dta_net_prj["SegID"] = dta_net_prj[segid_col].astype(int) |
| 84 | +dta_net_prj["Miles"] = dta_net_prj["Miles"].astype(float) |
| 85 | +# dta_net_prj = dta_net_prj.rename(columns = {'PreviousXD':'PreviousSe', 'NextXDSegI':'NextSegID'}) |
| 86 | +dta_net_prj.to_file(dta + "_prj.shp") |
88 | 87 |
|
89 | 88 |
|
90 | 89 | # # Get endpoints of INRIX links |
|
100 | 99 | }, |
101 | 100 | } |
102 | 101 | # Input file |
103 | | -inrixin = inrix_sf + "_prj.shp" |
| 102 | +dtain = dta + "_prj.shp" |
104 | 103 | # Output file |
105 | | -inrixout = inrix_sf + "_prj_endpoints.shp" |
| 104 | +dtaout = dta + "_prj_endpoints.shp" |
106 | 105 | with fiona.open( |
107 | | - inrixout, mode="w", crs=cal3, driver="ESRI Shapefile", schema=vschema |
| 106 | + dtaout, mode="w", crs=cal3, driver="ESRI Shapefile", schema=vschema |
108 | 107 | ) as output: |
109 | | - layer = fiona.open(inrixin) |
| 108 | + layer = fiona.open(dtain) |
110 | 109 | for line in layer: |
111 | 110 | vertices = line["geometry"]["coordinates"] |
112 | 111 | v_begin = vertices[0] |
113 | 112 | if isinstance(v_begin, list): |
114 | 113 | v_begin = vertices[0][0] |
115 | 114 | point = Point(float(v_begin[0]), float(v_begin[1])) |
116 | 115 | prop = { |
117 | | - "SegID": int(line["properties"]["SegID"]), |
118 | | - "RoadName": line["properties"]["RoadName"], |
| 116 | + "ID": int(line["properties"]["ID"]), |
| 117 | + "Start": line["properties"]["Start"], # here |
119 | 118 | "type": "begin", |
120 | 119 | "Latitude": float(v_begin[1]), |
121 | 120 | "Longitude": float(v_begin[0]), |
|
158 | 157 |
|
159 | 158 |
|
160 | 159 | # Read in the created inrix endpoints file |
161 | | -endpoints = gp.read_file(inrix_sf + "_prj_endpoints.shp") |
| 160 | +endpoints = gp.read_file(dta + "_prj_endpoints.shp") |
162 | 161 |
|
163 | 162 | # Assign unique node id |
164 | 163 | endpoints_cnt = ( |
|
173 | 172 | ) |
174 | 173 | endpoints_cnt["Coordinates"] = endpoints_cnt["Coordinates"].apply(Point) |
175 | 174 | endpoints_cnt_gpd = gp.GeoDataFrame(endpoints_cnt, geometry="Coordinates") |
176 | | -endpoints_cnt_gpd.to_file(inrix_sf + "_prj_endpoints_unique.shp") |
| 175 | +endpoints_cnt_gpd.to_file(dta + "_prj_endpoints_unique.shp") |
177 | 176 |
|
178 | 177 | endpoints = endpoints.merge( |
179 | 178 | endpoints_cnt, on=["Latitude", "Longitude"], how="left" |
|
190 | 189 | ] |
191 | 190 | endpoints_end.columns = ["SegID", "E_Lat", "E_Long", "E_NodeID"] |
192 | 191 |
|
193 | | -inrix_net_prj = inrix_net_prj.merge(endpoints_begin, on="SegID") |
194 | | -inrix_net_prj = inrix_net_prj.merge(endpoints_end, on="SegID") |
| 192 | +dta_net_prj = dta_net_prj.merge(endpoints_begin, on="SegID") |
| 193 | +dta_net_prj = dta_net_prj.merge(endpoints_end, on="SegID") |
195 | 194 |
|
196 | 195 |
|
197 | 196 | # # Get endnodes of CMP segments |
|
312 | 311 |
|
313 | 312 | # INRIX lines intersecting cmp segment buffer zone |
314 | 313 | inrix_lines_intersect = gp.sjoin( |
315 | | - inrix_net_prj, cmp_segs_buffer, op="intersects" |
| 314 | + dta_net_prj, cmp_segs_buffer, op="intersects" |
316 | 315 | ).reset_index() |
317 | 316 |
|
318 | 317 | # INRIX lines within cmp segment buffer zone |
319 | 318 | inrix_lines_within = gp.sjoin( |
320 | | - inrix_net_prj, cmp_segs_buffer, op="within" |
| 319 | + dta_net_prj, cmp_segs_buffer, op="within" |
321 | 320 | ).reset_index() |
322 | 321 |
|
323 | 322 |
|
|
1214 | 1213 |
|
1215 | 1214 | # INRIX lines intersecting with cmp endpoint buffer zone |
1216 | 1215 | inrix_lines_intersect_ep = gp.sjoin( |
1217 | | - inrix_net_prj, cmp_endpoints_buffer, op="intersects" |
| 1216 | + dta_net_prj, cmp_endpoints_buffer, op="intersects" |
1218 | 1217 | ).reset_index() |
1219 | 1218 |
|
1220 | 1219 |
|
|
1762 | 1761 | MANUAL_UPDATE = True |
1763 | 1762 | if MANUAL_UPDATE: |
1764 | 1763 | cols = inrix_lines_matched_output.columns |
1765 | | - rem_df = pd.read_csv( |
1766 | | - r"Q:\CMP\LOS Monitoring 2022\Network_Conflation\v2202\conflation_script_test\manual_remove.csv" |
1767 | | - ) |
| 1764 | + rem_df = pd.read_csv("manual_remove.csv") |
1768 | 1765 | rem_df["del_flag"] = 1 |
1769 | 1766 | inrix_lines_matched_output = inrix_lines_matched_output.merge( |
1770 | 1767 | rem_df, how="left" |
|
1773 | 1770 | pd.isna(inrix_lines_matched_output["del_flag"]), |
1774 | 1771 | ] |
1775 | 1772 |
|
1776 | | - add_df = pd.read_csv( |
1777 | | - r"Q:\CMP\LOS Monitoring 2022\Network_Conflation\v2202\conflation_script_test\manual_add.csv" |
1778 | | - ) |
| 1773 | + add_df = pd.read_csv("manual_add.csv") |
1779 | 1774 | inrix_lines_matched_output = pd.concat( |
1780 | 1775 | (inrix_lines_matched_output[cols], add_df) |
1781 | 1776 | ) |
|
0 commit comments