def main(): # import required modules and extensions import arcpy arcpy.CheckOutExtension('Spatial') # environment settings arcpy.env.workspace = 'in_memory' # set workspace to temporary workspace arcpy.env.overwriteOutput = True # set to overwrite output sr = arcpy.Describe(flowline_path).spatialReference # dissolve input flowline network flowline_dissolve = arcpy.Dissolve_management(flowline_path, 'in_memory/flowline_dissolve', '', '', 'SINGLE_PART', 'UNSPLIT_LINES') # create line id field and line length fields arcpy.AddField_management(flowline_dissolve, 'LineID', 'SHORT') arcpy.AddField_management(flowline_dissolve, 'LineLen', 'DOUBLE') with arcpy.da.UpdateCursor(flowline_dissolve, ['FID', 'LineID', 'Shape@Length', 'LineLen']) as cursor: for row in cursor: row[1] = row[0] row[3] = row[2] cursor.updateRow(row) # flip lines so segment points are created from end-start of line rather than start-end arcpy.FlipLine_edit(flowline_dissolve) # create points at regular interval along each flowline seg_pts = arcpy.CreateFeatureclass_management('in_memory', 'seg_pts', 'POINT', '', 'DISABLED', 'DISABLED', sr) with arcpy.da.SearchCursor(flowline_dissolve, ['SHAPE@'], spatial_reference = sr) as search: with arcpy.da.InsertCursor(seg_pts, ['SHAPE@']) as insert: for row in search: try: lineGeom = row[0] lineLength = row[0].length lineDist = interval while lineDist + min_segLength <= lineLength: newPoint = lineGeom.positionAlongLine(lineDist) insert.insertRow(newPoint) lineDist += interval except Exception as e: arcpy.AddMessage(str(e.message)) # split flowlines at segment interval points flowline_seg = arcpy.SplitLineAtPoint_management(flowline_dissolve, seg_pts, 'in_memory/flowline_seg', 1.0) # add and populate segment id and length fields arcpy.AddField_management(flowline_seg, 'SegID', 'SHORT') arcpy.AddField_management(flowline_seg, 'SegLen', 'DOUBLE') with arcpy.da.UpdateCursor(flowline_seg, ['FID', 'SegID', 'Shape@Length', 'SegLen']) as cursor: for row in cursor: row[1] = row[0] row[3] = row[2] cursor.updateRow(row) # flip lines back to correct direction arcpy.FlipLine_edit(flowline_seg) # save flowline segment output arcpy.CopyFeatures_management(flowline_seg, outpath) arcpy.Delete_management('in_memory')
def SpitFunction (riv_shp, scratch, home, counter): dist = 200 counter += 1 print("iteration {0} of split function".format(counter)) rivers_gpd = gpd.read_file(riv_shp, driver="ESRI Shapefile") print("shp file loaded") rivers_gpd["Llength"] = rivers_gpd.length long_riv_gpd = rivers_gpd.loc[rivers_gpd["Llength"] > dist] geom_list = [] for index, row in long_riv_gpd.iterrows(): shapelyLine = row['geometry'] shpLen = shapelyLine.length nsplit = math.ceil(shpLen/dist) split_range = range(1, nsplit) for i in split_range: p_dist = 1/(i+1) splitPoint = (shapelyLine.interpolate(p_dist, normalized=True)) x, y = splitPoint.coords.xy geom_list.append((float(x[0]), float(y[0]))) gs_points = gpd.GeoSeries(Point(pnt[0], pnt[1]) for pnt in geom_list) gdf_points = gpd.GeoDataFrame() gdf_points['geometry'] = gs_points pnts_path = os.path.join(scratch, "SnipPoints.shp") gdf_points.to_file(pnts_path, driver="ESRI Shapefile") print("points file created") spltLines = os.path.join(scratch, "SplitLines_c{0}.shp".format(counter)) print(str(counter)) print("split line at point tool runing...") print(riv_shp) print(spltLines) arcpy.SplitLineAtPoint_management(riv_shp, pnts_path, spltLines, search_radius=1) print("slp tool completed.") Splitriv_gpd = gpd.read_file(spltLines, driver="ESRI Shapefile") print("checking line lengths...") if any(x > dist for x in list(Splitriv_gpd.length)) is True: SpitFunction(spltLines, scratch, home, counter) else: print("all line lengths less than {0}".format(dist)) outfile = os.path.join(home, "BDC_reaches.shp") if arcpy.Exists(outfile): arcpy.Delete_management(outfile) arcpy.CopyFeatures_management(spltLines, outfile) print("chunk completed")
def transfer_line(fcInLine, fcToLine, strStreamSide): outputWorkspace = arcpy.Describe(fcInLine).path fcOutput = gis_tools.newGISDataset( outputWorkspace, "LineNetworkConfinement" + strStreamSide) # Split Line Network by Line Ends fcSplitPoints = gis_tools.newGISDataset( outputWorkspace, "SplitPoints_Confinement" + strStreamSide) arcpy.FeatureVerticesToPoints_management(fcInLine, fcSplitPoints, "BOTH_ENDS") tblNearPointsConfinement = gis_tools.newGISDataset( outputWorkspace, "NearPointsConfinement" + strStreamSide) arcpy.GenerateNearTable_analysis(fcSplitPoints, fcToLine, tblNearPointsConfinement, location="LOCATION", angle="ANGLE") lyrNearPointsConfinement = gis_tools.newGISDataset( "Layer", "lyrNearPointsConfinement" + strStreamSide) arcpy.MakeXYEventLayer_management(tblNearPointsConfinement, "NEAR_X", "NEAR_Y", lyrNearPointsConfinement, fcToLine) arcpy.SplitLineAtPoint_management(fcToLine, lyrNearPointsConfinement, fcOutput, search_radius="0.01 Meters") # Prepare Fields strConfinementField = "Con_" + strStreamSide arcpy.AddField_management(fcOutput, strConfinementField, "LONG") # Transfer Attributes by Centroids fcCentroidPoints = gis_tools.newGISDataset( outputWorkspace, "CentroidPoints_Confinement" + strStreamSide) arcpy.FeatureVerticesToPoints_management(fcInLine, fcCentroidPoints, "MID") tblNearPointsCentroid = gis_tools.newGISDataset( outputWorkspace, "NearPointsCentroid" + strStreamSide) arcpy.GenerateNearTable_analysis(fcCentroidPoints, fcToLine, tblNearPointsCentroid, location="LOCATION", angle="ANGLE") lyrNearPointsCentroid = gis_tools.newGISDataset( "Layer", "lyrNearPointsCentroid" + strStreamSide) arcpy.MakeXYEventLayer_management(tblNearPointsCentroid, "NEAR_X", "NEAR_Y", lyrNearPointsCentroid, fcToLine) lyrToLineSegments = gis_tools.newGISDataset("Layer", "lyrToLineSegments") arcpy.MakeFeatureLayer_management(fcOutput, lyrToLineSegments) arcpy.SelectLayerByLocation_management( lyrToLineSegments, "INTERSECT", lyrNearPointsCentroid, selection_type="NEW_SELECTION") #"0.01 Meter","NEW_SELECTION") arcpy.CalculateField_management(lyrToLineSegments, strConfinementField, 1, "PYTHON") return fcOutput
def splitLineAtPoint(self): """ Split the bike lane where it intersect street layer :return: """ split_bike = "bike_split" arcpy.SplitLineAtPoint_management(self.BIKE_NAME, self.intersect_name, split_bike, search_radius=3) self.split_bike = split_bike
def split_line(workspacePath, tempGDB, inputFlsplit, splitDistance): import arcpy import os arcpy.env.workspace = workspacePath includeEndPoints = 'NO_END_POINTS' arcpy.env.overwriteOutput = True mxd = arcpy.mapping.MapDocument('CURRENT') df = arcpy.mapping.ListDataFrames(mxd)[0] #Generate points along line for split arcpy.SetProgressorLabel("Generating points to split by...") outputPointFC = os.path.join(tempGDB, inputFlsplit + "Points") arcpy.GeneratePointsAlongLines_management( inputFlsplit, outputPointFC, 'DISTANCE', splitDistance, Include_End_Points=includeEndPoints) #Split line into separate segments based on previous points with a 2 meter radius tolerance around the point arcpy.SetProgressorLabel("Splitting initial line into segments...") outputFCsplit = os.path.join(tempGDB, inputFlsplit + "Split") arcpy.SplitLineAtPoint_management(inputFlsplit, outputPointFC, outputFCsplit, search_radius='1 Meters') # Get filename part of outputFCsplit flName = os.path.basename(outputFCsplit) #Create a feature layer to be used for AddGeometryAttributes arcpy.MakeFeatureLayer_management(outputFCsplit, flName) #Create a layer object from the feature layer #tempLayer = arcpy.mapping.Layer(flName) #Add attributes for line start,mid, and end to determine order of segments for new feature classes; for some reason line segments are not in proper order arcpy.AddGeometryAttributes_management(flName, "LINE_START_MID_END") #Add layer to the map #arcpy.mapping.AddLayer(df,tempLayer) return outputFCsplit
def snap_and_split(gdb_feature_path): # This function snaps bike station points to the closest bike route # and splits the route segments at the station points # snap bike station points to closest line segment arcpy.Snap_edit( (gdb_feature_path + r'/Bike_Stations'), (gdb_feature_path + r"/CENTRELINE_BIKEWAY_OD_Layer EDGE '100 Meters'") ) # split bike route line segments at station points (necessary for proper network analyst calculations) arcpy.SplitLineAtPoint_management( (gdb_feature_path + r'/CENTRELINE_BIKEWAY_OD_Layer'), (gdb_feature_path + r'/Bike_Stations'), (gdb_feature_path + r'/Bikeways_Split'), "1 Meters" ) print('Snap and Split Complete!')
def main(in_strm, strm_index): arcpy.AddMessage("Select stream segments with " + strm_index + " values...") arcpy.MakeFeatureLayer_management(in_strm, "in_strm_lyr") fields = arcpy.ListFields("in_strm_lyr") for f in fields: if f.name == strm_index: f_type = f.type if f_type == 'Integer': expr_strm_wID = strm_index + " >= 0" arcpy.SelectLayerByAttribute_management("in_strm_lyr", "NEW_SELECTION", expr_strm_wID) elif f_type == 'String': expr_strm_wID = strm_index + " <> ''" arcpy.SelectLayerByAttribute_management("in_strm_lyr", "NEW_SELECTION", expr_strm_wID) strm_wID = arcpy.CopyFeatures_management("in_strm_lyr", r"in_memory\strm_wID") arcpy.AddMessage("Dissolving segments...") strm_dslvID = arcpy.Dissolve_management(strm_wID, r"in_memory\strm_dslvID", strm_index, "", "SINGLE_PART", "DISSOLVE_LINES") arcpy.SelectLayerByAttribute_management("in_strm_lyr", "SWITCH_SELECTION", "") strm_noID = arcpy.CopyFeatures_management("in_strm_lyr", r"in_memory\strm_noid") split_pnt = arcpy.Intersect_analysis([strm_dslvID, strm_noID], r"in_memory\split_pnt", "ONLY_FID", "", "point") strm_split = arcpy.SplitLineAtPoint_management(strm_dslvID, split_pnt, r"in_memory\strm_split", "5 meters") strm_dslvNoID = arcpy.Dissolve_management(strm_noID, r"in_memory\strm_dslvNoID", strm_index, "", "SINGLE_PART", "DISSOLVE_LINES") arcpy.Append_management(strm_dslvNoID, strm_split, "no_test", "", "") return strm_split
def delete_dangles(KVL_dissolve, input_points_p): points_subset = arcpy.FeatureClassToFeatureClass_conversion( input_points_p, "in_memory", "Points_Subset", "Point_Type IN ('ПС', 'ЭС', 'РУ')") points_layer = arcpy.MakeFeatureLayer_management(points_subset, "Points_Layer") arcpy.Integrate_management(KVL_dissolve) split2 = arcpy.SplitLine_management(KVL_dissolve, "SplitLine2") arcpy.DeleteIdentical_management(split2, ["SHAPE", "Name"]) unsplit2 = arcpy.Dissolve_management( split2, "Unsplited_Lines2", [ "Name", "Voltage", "Start", "End", "Circuit", "Operate_Name", "Trace_Version", "Status" ], multi_part="MULTI_PART") KVL_splitted = arcpy.SplitLineAtPoint_management(unsplit2, points_subset, "SplitAtPoint", search_radius="1 Meters") dangles_new = arcpy.FeatureVerticesToPoints_management( KVL_splitted, 'Dangles_KVL', 'DANGLE') dangles_layer = arcpy.MakeFeatureLayer_management(dangles_new, "Dangles_Layer") lines_layer = arcpy.MakeFeatureLayer_management(KVL_splitted, "Lines_Layer") arcpy.SelectLayerByLocation_management(dangles_layer, "INTERSECT", points_layer) arcpy.SelectLayerByAttribute_management(dangles_layer, "SWITCH_SELECTION") arcpy.SelectLayerByLocation_management(lines_layer, "INTERSECT", dangles_layer) arcpy.DeleteFeatures_management(lines_layer) KVL_dissolve_final = arcpy.Dissolve_management( lines_layer, "KVL_Dissolve", [ "Name", "Voltage", "Start", "End", "Circuit", "Operate_Name", "Status" ], multi_part="MULTI_PART") return KVL_dissolve_final
def FlmLineSplit(workspace, Input_Lines, SamplingType, Segment_Length, Tolerance_Radius): if SamplingType == "IN-FEATURES": return Input_Lines arcpy.env.workspace = workspace arcpy.env.overwriteOutput = True FLA_Line_Unsplit = workspace + "\\FLA_Line_Unsplit.shp" FLA_Line_Unsplit_Single = workspace + "\\FLA_Line_Unsplit_Single.shp" FLA_Line_Split_Vertices = workspace + "\\FLA_Line_Split_Vertices.shp" FLA_Segmented_Lines = workspace + "\\FLA_Segmented_Lines.shp" flmc.log("FlmLineSplit: Executing UnsplitLine") flmc.log("Input_Lines: " + Input_Lines) flmc.log("FLA_Line_Unsplit: " + FLA_Line_Unsplit) # TODO: resume UnsplitLine after defining disolve fields # arcpy.UnsplitLine_management(Input_Lines, FLA_Line_Unsplit) arcpy.Copy_management(Input_Lines, FLA_Line_Unsplit) arcpy.MultipartToSinglepart_management(FLA_Line_Unsplit, FLA_Line_Unsplit_Single) #arcpy.Delete_management(FLA_Line_Unsplit) if SamplingType == "ARBITRARY": arcpy.GeneratePointsAlongLines_management(FLA_Line_Unsplit_Single, FLA_Line_Split_Vertices, "DISTANCE", Segment_Length, "", "NO_END_POINTS") elif SamplingType == "LINE-CROSSINGS": arcpy.Intersect_analysis(PathFile(FLA_Line_Unsplit_Single), PathFile(FLA_Line_Split_Vertices), join_attributes="ALL", cluster_tolerance=Tolerance_Radius, output_type="POINT") if SamplingType != "WHOLE-LINE": # "ARBITRARY" or "LINE-CROSSINGS" arcpy.SplitLineAtPoint_management(FLA_Line_Unsplit_Single, FLA_Line_Split_Vertices, FLA_Segmented_Lines, Tolerance_Radius) arcpy.Delete_management(FLA_Line_Unsplit_Single) arcpy.Delete_management(FLA_Line_Split_Vertices) else: # "WHOLE-LINE" FLA_Segmented_Lines = FLA_Line_Unsplit_Single return FLA_Segmented_Lines
def main(fcLineNetwork, fieldStreamRouteID, fieldConfinement, fieldConstriction, strSeedDistance, inputliststrWindowSize, outputWorkspace, tempWorkspace=arcpy.env.scratchWorkspace): """Perform a Moving Window Analysis on a Line Network.""" liststrWindowSize = inputliststrWindowSize.split(";") fcLineNetworkDissolved = gis_tools.newGISDataset( tempWorkspace, "GNAT_MWA_LineNetworkDissolved") arcpy.Dissolve_management(fcLineNetwork, fcLineNetworkDissolved, fieldStreamRouteID, multi_part=False, unsplit_lines=True) listLineGeometries = arcpy.CopyFeatures_management(fcLineNetworkDissolved, arcpy.Geometry()) listWindows = [] listSeeds = [] listWindowEvents = [] listgWindows = [] intSeedID = 0 iRoutes = int( arcpy.GetCount_management(fcLineNetworkDissolved).getOutput(0)) arcpy.SetProgressor("step", "Processing Each Route", 0, iRoutes, 1) iRoute = 0 with arcpy.da.SearchCursor( fcLineNetworkDissolved, ["SHAPE@", fieldStreamRouteID, "SHAPE@LENGTH"]) as scLines: for fLine in scLines: #Loop Through Routes arcpy.SetProgressorLabel("Route: " + str(iRoute) + " Seed Point: " + str(intSeedID)) arcpy.SetProgressorPosition(iRoute) gLine = fLine[0] dblSeedPointPosition = float( max(liststrWindowSize )) / 2 #Start Seeds at position of largest window while dblSeedPointPosition + float( max(liststrWindowSize)) / 2 < fLine[2]: arcpy.SetProgressorLabel("Route: " + str(iRoute) + " Seed Point: " + str(intSeedID)) gSeedPointPosition = gLine.positionAlongLine( dblSeedPointPosition) listSeeds.append([ scLines[1], intSeedID, gSeedPointPosition ]) #gSeedPointPosition.X,gSeedPointPosition.Y]) for strWindowSize in liststrWindowSize: dblWindowSize = float(strWindowSize) dblLengthStart = dblSeedPointPosition - dblWindowSize / 2 dblLengthEnd = dblSeedPointPosition + dblWindowSize / 2 gPointStartLocation = gLine.positionAlongLine( dblLengthStart) gPointEndLocation = gLine.positionAlongLine(dblLengthEnd) gTemp = arcpy.Geometry() listgWindowTemp = arcpy.SplitLineAtPoint_management( gLine, [gPointStartLocation, gPointEndLocation], gTemp, "1 METER") #TODO: Need a better method to select the line here!! for gWindowTemp in listgWindowTemp: if abs(gWindowTemp.length - dblWindowSize) < 10: listgWindows.append([ scLines[1], intSeedID, dblWindowSize, gWindowTemp ]) # End TODO listWindows.append([ scLines[1], intSeedID, dblWindowSize, gPointStartLocation ]) listWindows.append([ scLines[1], intSeedID, dblWindowSize, gPointEndLocation ]) listWindowEvents.append([ scLines[1], intSeedID, dblWindowSize, dblLengthStart, dblLengthEnd ]) dblSeedPointPosition = dblSeedPointPosition + float( strSeedDistance) intSeedID = intSeedID + 1 iRoute = iRoute + 1 fcSeedPoints = gis_tools.newGISDataset(tempWorkspace, "GNAT_MWA_SeedPoints") fcWindowEndPoints = gis_tools.newGISDataset(tempWorkspace, "GNAT_MWA_WindowEndPoints") fcWindowLines = gis_tools.newGISDataset(tempWorkspace, "GNAT_MWA_WindowLines") arcpy.CreateFeatureclass_management(tempWorkspace, "GNAT_MWA_SeedPoints", "POINT", spatial_reference=fcLineNetwork) arcpy.CreateFeatureclass_management(tempWorkspace, "GNAT_MWA_WindowEndPoints", "POINT", spatial_reference=fcLineNetwork) arcpy.CreateFeatureclass_management(tempWorkspace, "GNAT_MWA_WindowLines", "POLYLINE", spatial_reference=fcLineNetwork) gis_tools.resetField(fcSeedPoints, "RouteID", "LONG") gis_tools.resetField(fcSeedPoints, "SeedID", "LONG") gis_tools.resetField(fcWindowEndPoints, "RouteID", "LONG") gis_tools.resetField(fcWindowEndPoints, "SeedID", "LONG") gis_tools.resetField(fcWindowEndPoints, "Seg", "DOUBLE") gis_tools.resetField(fcWindowLines, "RouteID", "LONG") gis_tools.resetField(fcWindowLines, "SeedID", "LONG") gis_tools.resetField(fcWindowLines, "Seg", "DOUBLE") with arcpy.da.InsertCursor( fcSeedPoints, ["RouteID", "SeedID", "SHAPE@XY"]) as icSeedPoints: for row in listSeeds: icSeedPoints.insertRow(row) with arcpy.da.InsertCursor( fcWindowEndPoints, ["RouteID", "SeedID", "Seg", "SHAPE@XY"]) as icWindowEndPoints: for row in listWindows: icWindowEndPoints.insertRow(row) with arcpy.da.InsertCursor( fcWindowLines, ["RouteID", "SeedID", "Seg", "SHAPE@"]) as icWindowLines: for row in listgWindows: icWindowLines.insertRow(row) fcIntersected = gis_tools.newGISDataset( tempWorkspace, "GNAT_MWA_IntersectWindowAttributes") arcpy.Intersect_analysis([fcWindowLines, fcLineNetwork], fcIntersected, "ALL", output_type="LINE") # Confinement tblSummaryStatisticsConfinement = gis_tools.newGISDataset( tempWorkspace, "GNAT_MWA_SummaryStatsTableConfinement") arcpy.Statistics_analysis( fcIntersected, tblSummaryStatisticsConfinement, "Shape_Length SUM", fieldStreamRouteID + ";SeedID;Seg;" + fieldConfinement) tblSummaryStatisticsPivot = gis_tools.newGISDataset( tempWorkspace, "GNAT_MWA_SummaryStatisticsPivotTable") arcpy.PivotTable_management(tblSummaryStatisticsConfinement, "Route;SeedID;Seg", fieldConfinement, "SUM_Shape_Length", tblSummaryStatisticsPivot) fieldConfinementValue = gis_tools.resetField(tblSummaryStatisticsPivot, "CONF_Value", "DOUBLE") if len(arcpy.ListFields(tblSummaryStatisticsPivot, fieldConfinement + "1")) == 0: arcpy.AddField_management(tblSummaryStatisticsPivot, fieldConfinement + "1", "DOUBLE") if len(arcpy.ListFields(tblSummaryStatisticsPivot, fieldConfinement + "0")) == 0: arcpy.AddField_management(tblSummaryStatisticsPivot, fieldConfinement + "0", "DOUBLE") arcpy.CalculateField_management( tblSummaryStatisticsPivot, fieldConfinementValue, "!" + fieldConfinement + "1!/(!" + fieldConfinement + "0! + !" + fieldConfinement + "1!)", "PYTHON") #Pivot Confinement on Segment Size tblSummaryStatisticsWindowPivot = gis_tools.newGISDataset( tempWorkspace, "GNAT_MWA_SummaryStatisticsWindowPivotTable") arcpy.PivotTable_management(tblSummaryStatisticsPivot, fieldStreamRouteID + ";SeedID", "Seg", fieldConfinementValue, tblSummaryStatisticsWindowPivot) # Constriction tblSummaryStatisticsConstriction = gis_tools.newGISDataset( tempWorkspace, "GNAT_MWA_SummaryStatsTableConstriction") arcpy.Statistics_analysis( fcIntersected, tblSummaryStatisticsConstriction, "Shape_Length SUM", fieldStreamRouteID + ";SeedID;Seg;" + fieldConstriction) tblSummaryStatisticsPivotConstriction = gis_tools.newGISDataset( tempWorkspace, "GNAT_MWA_SummaryStatisticsPivotTableConsriction") arcpy.PivotTable_management(tblSummaryStatisticsConstriction, "Route;SeedID;Seg", fieldConstriction, "SUM_Shape_Length", tblSummaryStatisticsPivotConstriction) fieldConstrictionValue = gis_tools.resetField( tblSummaryStatisticsPivotConstriction, "CNST_Value", "DOUBLE") if len( arcpy.ListFields(tblSummaryStatisticsConstriction, fieldConstriction + "1")) == 0: arcpy.AddField_management(tblSummaryStatisticsConstriction, fieldConstriction + "1", "DOUBLE") if len( arcpy.ListFields(tblSummaryStatisticsConstriction, fieldConstriction + "0")) == 0: arcpy.AddField_management(tblSummaryStatisticsConstriction, fieldConstriction + "0", "DOUBLE") arcpy.CalculateField_management( tblSummaryStatisticsPivotConstriction, fieldConstrictionValue, "!" + fieldConstriction + "1!/(!" + fieldConstriction + "0! + !" + fieldConstriction + "1!)", "PYTHON") tblSummaryStatisticsWindowPivotConstriction = gis_tools.newGISDataset( tempWorkspace, "GNAT_MWA_SummaryStatisticsWindowPivotTableConstriction") arcpy.PivotTable_management(tblSummaryStatisticsPivotConstriction, fieldStreamRouteID + ";SeedID", "Seg", fieldConstrictionValue, tblSummaryStatisticsWindowPivotConstriction) strWindowSizeFields = "" for WindowSize in liststrWindowSize: strWindowSizeFields = strWindowSizeFields + ";Seg" + WindowSize strWindowSizeFields = strWindowSizeFields.lstrip(";") #Join Above table to seed points arcpy.JoinField_management(fcSeedPoints, "SeedID", tblSummaryStatisticsWindowPivot, "SeedID", strWindowSizeFields) arcpy.JoinField_management(fcSeedPoints, "SeedID", tblSummaryStatisticsWindowPivotConstriction, "SeedID", strWindowSizeFields) # Manage Outputs fcOutputSeedPoints = gis_tools.newGISDataset(outputWorkspace, "MovingWindowSeedPoints") arcpy.CopyFeatures_management(fcSeedPoints, fcOutputSeedPoints) fcOutputWindows = gis_tools.newGISDataset(outputWorkspace, "MovingWindowSegments") arcpy.CopyFeatures_management(fcWindowLines, fcOutputWindows) return
def main(fcInputCenterline, fcInputPolygon, fcSegmentedPolygons, dblPointDensity=10.0, dblJunctionBuffer=100.00, workspaceTemp="in_memory"): # Manage Environments env_extent = arcpy.env.extent env_outputmflag = arcpy.env.outputMFlag env_outputzflag = arcpy.env.outputZFlag arcpy.env.outputMFlag = "Disabled" arcpy.env.outputZFlag = "Disabled" arcpy.env.extent = fcInputPolygon ## Set full extent to build Thiessan polygons over entire line network. # Copy centerline to temporary workspace fcCenterline = gis_tools.newGISDataset(workspaceTemp, "GNAT_DPS_Centerline") arcpy.CopyFeatures_management(fcInputCenterline, fcCenterline) if "FromID" not in [ field.name for field in arcpy.ListFields(fcCenterline) ]: arcpy.AddField_management(fcCenterline, "FromID", "LONG") arcpy.CalculateField_management( fcCenterline, "FromID", "!{}!".format(arcpy.Describe(fcCenterline).OIDFieldName), "PYTHON_9.3") # Build Thiessan polygons arcpy.AddMessage("GNAT DPS: Building Thiessan polygons") arcpy.Densify_edit(fcCenterline, "DISTANCE", "{} METERS".format(dblPointDensity)) fcTribJunctionPoints = gis_tools.newGISDataset( workspaceTemp, "GNAT_DPS_TribJunctionPoints") arcpy.Intersect_analysis([fcCenterline], fcTribJunctionPoints, output_type="POINT") fcThiessanPoints = gis_tools.newGISDataset(workspaceTemp, "GNAT_DPS_ThiessanPoints") arcpy.FeatureVerticesToPoints_management(fcCenterline, fcThiessanPoints, "ALL") lyrThiessanPoints = gis_tools.newGISDataset("Layer", "lyrThiessanPoints") arcpy.MakeFeatureLayer_management(fcThiessanPoints, lyrThiessanPoints) arcpy.SelectLayerByLocation_management( lyrThiessanPoints, "INTERSECT", fcTribJunctionPoints, "{} METERS".format(dblJunctionBuffer)) fcThiessanPoly = gis_tools.newGISDataset(workspaceTemp, "GNAT_DPS_ThiessanPoly") # arcpy.CreateThiessenPolygons_analysis(lyrThiessanPoints,fcThiessanPoly,"ONLY_FID") arcpy.CreateThiessenPolygons_analysis(lyrThiessanPoints, fcThiessanPoly, "ALL") # Clean polygons # lyrInputPolygon = gis_tools.newGISDataset("Layer", "lyrInputPolygon") # arcpy.MakeFeatureLayer_management(fcInputPolygon, lyrInputPolygon) arcpy.RepairGeometry_management(fcInputPolygon, "KEEP_NULL") fcThiessanPolyClip = gis_tools.newGISDataset(workspaceTemp, "GNAT_DPS_TheissanPolyClip") arcpy.Clip_analysis(fcThiessanPoly, fcInputPolygon, fcThiessanPolyClip) # Split the junction Thiessan polygons arcpy.AddMessage("GNAT DPS: Split junction Thiessan polygons") lyrTribThiessanPolys = gis_tools.newGISDataset("Layer", "lyrTribThiessanPolys") arcpy.MakeFeatureLayer_management(fcThiessanPolyClip, lyrTribThiessanPolys) arcpy.SelectLayerByLocation_management(lyrTribThiessanPolys, "INTERSECT", fcTribJunctionPoints) fcSplitPoints = gis_tools.newGISDataset(workspaceTemp, "GNAT_DPS_SplitPoints") arcpy.Intersect_analysis([lyrTribThiessanPolys, fcCenterline], fcSplitPoints, output_type="POINT") arcpy.AddMessage("GNAT DPS: Moving starting vertices of junction polygons") geometry_functions.changeStartingVertex(fcTribJunctionPoints, lyrTribThiessanPolys) arcpy.AddMessage("GNAT DPS: Vertices moved") fcThiessanTribPolyEdges = gis_tools.newGISDataset( workspaceTemp, "GNAT_DPS_ThiessanTribPolyEdges") arcpy.FeatureToLine_management(lyrTribThiessanPolys, fcThiessanTribPolyEdges) fcSplitLines = gis_tools.newGISDataset(workspaceTemp, "GNAT_DPS_SplitLines") arcpy.SplitLineAtPoint_management(fcThiessanTribPolyEdges, fcSplitPoints, fcSplitLines, "0.1 METERS") fcMidPoints = gis_tools.newGISDataset(workspaceTemp, "GNAT_DPS_MidPoints") arcpy.FeatureVerticesToPoints_management(fcSplitLines, fcMidPoints, "MID") arcpy.Near_analysis(fcMidPoints, fcTribJunctionPoints, location="LOCATION") arcpy.AddXY_management(fcMidPoints) fcTribToMidLines = gis_tools.newGISDataset(workspaceTemp, "GNAT_DPS_TribToMidLines") arcpy.XYToLine_management(fcMidPoints, fcTribToMidLines, "POINT_X", "POINT_Y", "NEAR_X", "NEAR_Y") ### Select polygons by centerline ### arcpy.AddMessage("GNAT DPS: Select polygons by centerline") fcThiessanEdges = gis_tools.newGISDataset(workspaceTemp, "GNAT_DPS_ThiessanEdges") arcpy.FeatureToLine_management(fcThiessanPolyClip, fcThiessanEdges) fcAllEdges = gis_tools.newGISDataset(workspaceTemp, "GNAT_DPS_AllEdges") arcpy.Merge_management([fcTribToMidLines, fcThiessanEdges, fcCenterline], fcAllEdges) # include fcCenterline if needed fcAllEdgesPolygons = gis_tools.newGISDataset(workspaceTemp, "GNAT_DPS_AllEdgesPolygons") arcpy.FeatureToPolygon_management(fcAllEdges, fcAllEdgesPolygons) fcAllEdgesPolygonsClip = gis_tools.newGISDataset( workspaceTemp, "GNAT_DPS_AllEdgesPolygonsClip") arcpy.Clip_analysis(fcAllEdgesPolygons, fcInputPolygon, fcAllEdgesPolygonsClip) fcPolygonsJoinCenterline = gis_tools.newGISDataset( workspaceTemp, "GNAT_DPS_PolygonsJoinCenterline") arcpy.SpatialJoin_analysis(fcAllEdgesPolygonsClip, fcCenterline, fcPolygonsJoinCenterline, "JOIN_ONE_TO_MANY", "KEEP_ALL", match_option="SHARE_A_LINE_SEGMENT_WITH") fcPolygonsDissolved = gis_tools.newGISDataset( workspaceTemp, "GNAT_DPS_PolygonsDissolved") arcpy.Dissolve_management(fcPolygonsJoinCenterline, fcPolygonsDissolved, "FromID", multi_part="SINGLE_PART") lyrPolygonsDissolved = gis_tools.newGISDataset("Layer", "lyrPolygonsDissolved") arcpy.MakeFeatureLayer_management(fcPolygonsDissolved, lyrPolygonsDissolved) arcpy.SelectLayerByAttribute_management(lyrPolygonsDissolved, "NEW_SELECTION", """ "FromID" IS NULL """) arcpy.Eliminate_management(lyrPolygonsDissolved, fcSegmentedPolygons, "LENGTH") arcpy.AddMessage("GNAT DPS: Tool complete") # Reset env arcpy.env.extent = env_extent arcpy.env.outputMFlag = env_outputmflag arcpy.env.outputZFlag = env_outputzflag return
def main(fcFromLine, fcToLine, fcOutputLineNetwork, searchDistance, tempWorkspace): reload(DividePolygonBySegment) # Environment settings arcpy.env.overwriteOutput = True arcpy.env.outputMFlag = "Disabled" arcpy.env.outputZFlag = "Disabled" arcpy.env.scratchWorkspace = tempWorkspace arcpy.AddMessage("GNAT TLA: starting transfer process...") gis_tools.resetData(fcOutputLineNetwork) fcFromLineTemp = gis_tools.newGISDataset(tempWorkspace, "GNAT_TLA_FromLineTemp") fcToLineTemp = gis_tools.newGISDataset(tempWorkspace, "GNAT_TLA_ToLineTemp") arcpy.MakeFeatureLayer_management(fcFromLine, "lyrFromLine") arcpy.MakeFeatureLayer_management(fcToLine, "lyrToLine") arcpy.CopyFeatures_management("lyrFromLine", fcFromLineTemp) arcpy.CopyFeatures_management("lyrToLine", fcToLineTemp) # Add a unique ID for the "From" line feature class from_oid = arcpy.Describe(fcFromLineTemp).OIDFieldName arcpy.AddField_management(fcFromLineTemp, "FromID", "LONG") arcpy.CalculateField_management(fcFromLineTemp, "FromID", "!{0}!".format(from_oid), "PYTHON_9.3") # Snap "From" line network to "To" line network lyrFromLineTemp = gis_tools.newGISDataset("Layer", "lyrFromLineTemp") lyrToLineTemp = gis_tools.newGISDataset("Layer", "lyrToLineTemp") arcpy.MakeFeatureLayer_management(fcFromLineTemp, lyrFromLineTemp) arcpy.MakeFeatureLayer_management(fcToLineTemp, lyrToLineTemp) lyrSnapFromLine = snap_junction_points(lyrFromLineTemp, lyrToLineTemp, searchDistance) # Make bounding polygon for "From" line feature class # arcpy.AddMessage("GNAT TLA: Create buffer polygon around 'From' network") # fcFromLineBuffer = gis_tools.newGISDataset(tempWorkspace, "GNAT_TLA_FromLineBuffer") # arcpy.Buffer_analysis(lyrSnapFromLine, fcFromLineBuffer, "{0} Meters".format(searchDistance * 3), "FULL", "ROUND", "ALL") # fcFromLineBufDslv = gis_tools.newGISDataset(tempWorkspace, "GNAT_TLA_FromLineBUfDslv") # arcpy.AddMessage("GNAT TLA: Dissolve buffer") # arcpy.Dissolve_management(fcFromLineBuffer, fcFromLineBufDslv) merge_lines = gis_tools.newGISDataset(tempWorkspace, "GNAT_TLA_merged_lines") arcpy.Merge_management([lyrSnapFromLine, lyrToLineTemp], merge_lines) fcFromLineBuffer = gis_tools.newGISDataset(tempWorkspace, "GNAT_TLA_FromLineBUfDslv") external_edge_buffer(merge_lines, 10, fcFromLineBuffer) # Select features from "To" line feature class that are inside "From" line buffer arcpy.AddMessage("GNAT TLA: Select 'To' line features inside 'From' buffer") lyrFromLineBuffer = gis_tools.newGISDataset("Layer", "lyrFromLineBuffer") arcpy.MakeFeatureLayer_management(fcFromLineBuffer, lyrFromLineBuffer) lyrToLine = gis_tools.newGISDataset("Layer", "lyrToLine") arcpy.MakeFeatureLayer_management(fcToLine, lyrToLine) arcpy.SelectLayerByLocation_management(lyrToLine, "WITHIN", lyrFromLineBuffer, "#", "NEW_SELECTION") fcToLineWithinFromBuffer = arcpy.FeatureClassToFeatureClass_conversion(lyrToLine, tempWorkspace, "GNAT_TLA_ToLineWithinFromBuffer") # Select features from "To" line feature class that are outside "From" line buffer arcpy.SelectLayerByAttribute_management(lyrToLine, "SWITCH_SELECTION") fcToLineOutsideFromBuffer = arcpy.FeatureClassToFeatureClass_conversion(lyrToLine, tempWorkspace, "GNAT_TLA_ToLineOutsideFromBuffer") # Segment "From" line buffer polygon arcpy.AddMessage("GNAT TLA: Segmenting 'From' line buffer polygon") fcSegmentedBoundingPolygons = gis_tools.newGISDataset(tempWorkspace, "GNAT_TLA_SegmentedBoundingPolygons") DividePolygonBySegment.main(lyrSnapFromLine, fcFromLineBuffer, fcSegmentedBoundingPolygons, 10.0, 150.0, tempWorkspace) # Split points of "To" line at intersection of polygon segments arcpy.AddMessage("GNAT TLA: Split 'To' line features") fcIntersectSplitPoints = gis_tools.newGISDataset(tempWorkspace, "GNAT_TLA_IntersectSplitPoints") arcpy.Intersect_analysis([fcToLineWithinFromBuffer, fcSegmentedBoundingPolygons], fcIntersectSplitPoints, output_type="POINT") fcSplitLines = gis_tools.newGISDataset(tempWorkspace, "GNAT_TLA_SplitLines") arcpy.SplitLineAtPoint_management(fcToLineWithinFromBuffer, fcIntersectSplitPoints, fcSplitLines, "0.1 METERS") # Spatial join lines based on a common field, as transferred by segmented polygon arcpy.AddMessage("GNAT TLA: Joining polygon segments") arcpy.SpatialJoin_analysis(fcSplitLines, fcSegmentedBoundingPolygons, fcOutputLineNetwork, "JOIN_ONE_TO_ONE", "KEEP_ALL", match_option="WITHIN") arcpy.JoinField_management(fcOutputLineNetwork, "FromID", fcFromLineTemp, "FromID") # Append the "To" lines that were outside of the "From" line buffer, which will have NULL or zero values arcpy.env.extent = fcToLine # changed earlier in the workflow in DividePolygonBySegment module arcpy.Append_management([fcToLineOutsideFromBuffer], fcOutputLineNetwork, "NO_TEST") # Change values of "From" features to -99999 if no "To" features to transfer to. arcpy.MakeFeatureLayer_management(fcOutputLineNetwork, "lyrOutputLineNetwork") arcpy.SelectLayerByLocation_management("lyrOutputLineNetwork", "ARE_IDENTICAL_TO", fcToLineOutsideFromBuffer, "#", "NEW_SELECTION") to_fields = [f.name for f in arcpy.ListFields(fcToLine)] empty_attributes("lyrOutputLineNetwork", to_fields) arcpy.SelectLayerByAttribute_management("lyrOutputLineNetwork", "CLEAR_SELECTION") arcpy.AddMessage("GNAT TLA: Tool complete") return
"#", "NULLABLE", "NON_REQUIRED", "#") arcpy.CalculateField_management(attr_roads, "lengt_road", "!shape.geodesicLength@meters!", "PYTHON_9.3") arcpy.MakeFeatureLayer_management(attr_roads, "attr_roads") arcpy.SelectLayerByAttribute_management("attr_roads", "NEW_SELECTION", ' "lengt_road" >= 20 ') arcpy.CopyFeatures_management("attr_roads", spatial_roads_above20m) segmented_roads = intermediate_layers + "/segmented_roads.shp" _40m_points = intermediate_layers + "/_40m_points.shp" arcpy.GeneratePointsAlongLines_management(spatial_roads_above20m, _40m_points, 'DISTANCE', Distance='40 meters') arcpy.SplitLineAtPoint_management(spatial_roads_above20m, _40m_points, 'segmented_roads') arcpy.CopyFeatures_management('segmented_roads', segmented_roads) step2_endTime = bk_logger.currentSecondsTime() bk_logger.showPyMessage( " -- Step 2 done. Took {}".format( bk_logger.timeTaken(step2_startTime, step2_endTime)), logger) #Step 3: Selecting all roads that are less than 40m from a property and then export layer bk_logger.showPyMessage( "Step 3: Selecting all roads that are less than 40m from a property and then export layer ", logger) step3_startTime = bk_logger.currentSecondsTime() cad_proximal_roads = intermediate_layers + "/cad_proximal_roads.shp" arcpy.MakeFeatureLayer_management(segmented_roads, "segmented_roads")
arcpy.env.overwriteOutput = True # Inputs fc_bacis = 'C:/Users/cerni/Desktop/Univerzita Karlova/Geografie/Diplomka/data/silnicni_sit.gdb/silnicni_sit_test_multiple' fc_output = 'C:/Users/cerni/Desktop/Univerzita Karlova/Geografie/Diplomka/data/silnicni_sit.gdb' dem = 'C:/Users/cerni/Desktop/Univerzita Karlova/Geografie/Diplomka/data/silnicni_sit.gdb/dem' speedField = 'rychlost' inExField = 'intravilan' pnts_fc = fc_output + '/splitPnts' # Defining variables exp = inExField + "= 0" koef = 0.01813 # fc_bacis = arcpy.GetParameterAsText(0) # fc_output = arcpy.GetParameterAsText(1) # dem = arcpy.GetParameterAsText(2) # speedField = arcpy.GetParameterAsText(3) # inExField = arcpy.GetParameterAsText(4) # Cursor for reading rows in line input fc_input = functions.editLines(fc_bacis, fc_output, dem) functions.splitPoints(exp, fc_input, fc_output, speedField, pnts_fc) finalLines = fc_output + '/finalLines' arcpy.SplitLineAtPoint_management(fc_input, pnts_fc, finalLines, "0.25 Meters") arcpy.AddField_management(finalLines, "ftSpeed", "FLOAT") arcpy.AddField_management(finalLines, "tfSpeed", "FLOAT") functions.addSpeeds(koef, finalLines)
+ str(ncurrentstep) + "/" + str(nstep)) NearTable = arcpy.GenerateNearTable_analysis(ExtremePoints, PolyToLine, "NearTable", "", "LOCATION", "NO_ANGLE") rows = arcpy.SearchCursor(NearTable) Counter = 0 for row in rows: if row.NEAR_DIST > Counter: Counter = row.NEAR_DIST Counter += 1 ncurrentstep += 1 arcpy.AddMessage("Splitting polygon with the extreme points - Step " + str(ncurrentstep) + "/" + str(nstep)) FracTEMP = arcpy.SplitLineAtPoint_management(PolyToLine, ExtremePoints, "%ScratchWorkspace%\\FracTEMP", Counter) ncurrentstep += 1 arcpy.AddMessage("Deleting residual segments - Step " + str(ncurrentstep) + "/" + str(nstep)) FracTEMPToPoints = arcpy.FeatureVerticesToPoints_management( FracTEMP, "%ScratchWorkspace%\\FracTEMPToPoints", "BOTH_ENDS") arcpy.AddField_management(FracTEMP, "Fusion", "LONG", "", "", "", "", "NULLABLE", "NON_REQUIRED", "") fieldnames = [f.name for f in arcpy.ListFields(FracTEMP)] arcpy.CalculateField_management(FracTEMP, "Fusion", "!" + fieldnames[0] + "!", "PYTHON_9.3", "") SpatialRef = arcpy.Describe(Polygon).spatialReference
def conflate_tmc2projline(fl_proj, dirxn_list, tmc_dir_field, fl_tmcs_buffd, speed_data_fields): out_row_dict = {} # get length of project fld_shp_len = "SHAPE@LENGTH" fld_totprojlen = "proj_length_ft" with arcpy.da.SearchCursor(fl_proj, fld_shp_len) as cur: for row in cur: out_row_dict[fld_totprojlen] = row[0] for direcn in dirxn_list: # https://support.esri.com/en/technical-article/000012699 # temporary files temp_intersctpts = "temp_intersectpoints" temp_intrsctpt_singlpt = "temp_intrsctpt_singlpt" # converted from multipoint to single point (1 pt per feature) temp_splitprojlines = "temp_splitprojlines" # fc of project line split up to match TMC buffer extents temp_splitproj_w_tmcdata = "temp_splitproj_w_tmcdata" # fc of split project lines with TMC data on them fl_splitprojlines = "fl_splitprojlines" fl_splitproj_w_tmcdata = "fl_splitproj_w_tmcdata" # get TMCs whose buffers intersect the project line arcpy.SelectLayerByLocation_management(fl_tmcs_buffd, "INTERSECT", fl_proj) # select TMCs that intersect the project and are in indicated direction sql_sel_tmcxdir = "{} = '{}'".format(tmc_dir_field, direcn) arcpy.SelectLayerByAttribute_management(fl_tmcs_buffd, "SUBSET_SELECTION", sql_sel_tmcxdir) # split the project line at the boundaries of the TMC buffer, creating points where project line intersects TMC buffer boundaries arcpy.Intersect_analysis([fl_proj, fl_tmcs_buffd], temp_intersctpts, "", "", "POINT") arcpy.MultipartToSinglepart_management(temp_intersctpts, temp_intrsctpt_singlpt) # split project line into pieces at points where it intersects buffer, with 10ft tolerance # (not sure why 10ft tolerance needed but it is, zero tolerance results in some not splitting) arcpy.SplitLineAtPoint_management(fl_proj, temp_intrsctpt_singlpt, temp_splitprojlines, "10 Feet") arcpy.MakeFeatureLayer_management(temp_splitprojlines, fl_splitprojlines) # get TMC speeds onto each piece of the split project line via spatial join arcpy.SpatialJoin_analysis(temp_splitprojlines, fl_tmcs_buffd, temp_splitproj_w_tmcdata, "JOIN_ONE_TO_ONE", "KEEP_ALL", "#", "HAVE_THEIR_CENTER_IN", "30 Feet") # convert to fl and select records where "check field" col val is not none arcpy.MakeFeatureLayer_management(temp_splitproj_w_tmcdata, fl_splitproj_w_tmcdata) check_field = speed_data_fields[ 0] # choose first speed value field for checking--if it's null, then don't include those rows in aggregation sql_notnull = "{} IS NOT NULL".format(check_field) arcpy.SelectLayerByAttribute_management(fl_splitproj_w_tmcdata, "NEW_SELECTION", sql_notnull) # convert the selected records into a numpy array then a pandas dataframe flds_df = [fld_shp_len] + speed_data_fields df_spddata = utils.esri_object_to_df(fl_splitproj_w_tmcdata, flds_df) # remove project pieces with no speed data so their distance isn't included in weighting df_spddata = df_spddata.loc[pd.notnull( df_spddata[speed_data_fields[0]])].astype(float) dir_len = df_spddata[fld_shp_len].sum( ) #sum of lengths of project segments that intersect TMCs in the specified direction out_row_dict["{}_calc_len".format( direcn )] = dir_len #"calc" length because it may not be same as project length #get distance-weighted average value for each speed/congestion field #for PHED or hours of delay, will want to get dist-weighted SUM; for speed/reliability, want dist-weighted AVG #ideally this would be a dict of {<field>:<aggregation method>} for field in speed_data_fields: fielddir = "{}{}".format(direcn, field) # add direction tag to field names # if there's speed data, get weighted average value. linklen_w_speed_data = df_spddata[fld_shp_len].sum() if linklen_w_speed_data > 0: #wgtd avg = sum(piece's data * piece's len)/(sum of all piece lengths) avg_data_val = (df_spddata[field]*df_spddata[fld_shp_len]).sum() \ / df_spddata[fld_shp_len].sum() out_row_dict[fielddir] = avg_data_val else: out_row_dict[fielddir] = df_spddata[field].mean( ) #if no length, just return mean speed? Maybe instead just return 'no data avaialble'? Or -1 to keep as int? continue #cleanup fcs_to_delete = [ temp_intersctpts, temp_intrsctpt_singlpt, temp_splitprojlines, temp_splitproj_w_tmcdata ] for fc in fcs_to_delete: arcpy.Delete_management(fc) return pd.DataFrame([out_row_dict])
def getSinuosity(shape): ## This functions calculates the sinuosity of a polyline. ## Needs as an input a polyline shapefile. ## And a list of the years that the shapefiles are refering to. ## Also divides the line into section in order to calculate the sinuosity per section. ############################################# # Catching possible Errors - Error handling. ############################################# # Catch the error of using an empty shapefile (i.e. with no features in it) f_count = arcpy.GetCount_management(shape) if int(f_count[0]) > 0: arcpy.AddMessage("The input {0} has {1} features".format( shape.split("\\")[-1], f_count)) else: arcpy.AddError( 'The input {} has no features the execution of the script will fail ... Please check the input shapefiles ...' .format(shape.split("\\")[-1])) sys.exit(0) # Catch the error of having an unknown spatial reference for the input data. spatial_ref = arcpy.Describe(shape).spatialReference if spatial_ref.name != "Unknown": arcpy.AddMessage("The spatial reference of {0} is {1}".format( shape.split("\\")[-1], spatial_ref.name)) else: arcpy.AddError( "Beware ... the used input {0} has Unknown spatial reference ... Please check the Spatial Reference of the input shapefiles ... The execution of the script will be terminated soon ..." .format(shape)) sys.exit(0) # Catch the geometry Type error (of the input shapefiles not being polyline) desc = arcpy.Describe(shape) geometryType = desc.shapeType if str(geometryType) == 'Polyline': pass else: arcpy.AddError( '{} is not a line/polyline ... Please check the input shapefiles ...' .format(shape.split("\\")[-1])) sys.exit(0) ##################### # Calculate Sinuosity ##################### arcpy.AddMessage( "### Calculating sinuosity index for the whole river ###") for year in year_list: # Go through all the different Years the user enter as input (stored in a list). if year in shape: # If the Year input connects to a shapefile input (i.e. the user did not put wrong Year). try: if int( f_count[0] ) > 1: # If the input consits of multiple features dissolve it to 1. arcpy.AddMessage( "{0} has {1} features and it will be dissolved into 1 feature ..." .format(shape.split("\\")[-1], f_count)) shape_dissolve = r'river_dissolved.shp' # Name of the shapefile for the dissolved river arcpy.Dissolve_management( shape, shape_dissolve) # Perform dissolve shape = shape_dissolve # From now on the dissolved shape is going to be the variable shape. arcpy.AddMessage("Adding Geometry field ...") arcpy.AddGeometryAttributes_management( shape, "LENGTH", "METERS" ) # Add a Geometry field to calculate the length of each feature. arcpy.AddMessage("Adding field ...") arcpy.AddField_management( shape, 'TOT_LENGTH', 'DOUBLE' ) # Add another field "TOT_LENGTH" to copy the values ofthe length field - fixing field names to avoid confusions. arcpy.AddMessage("Calculating field ...") arcpy.CalculateField_management( shape, "TOT_LENGTH", "!LENGTH!", "PYTHON" ) # Actually copying the values of "LENGTH" to the new field added above. arcpy.AddMessage("Deleting field ...") arcpy.DeleteField_management( shape, "LENGTH" ) # Delete the geometry field that was just created. arcpy.AddMessage( "Calculating total length of the river ...") cursor = arcpy.da.SearchCursor( shape, ["TOT_LENGTH"] ) # Use a search cursor to go through the "TOT_LENGTH" of the input shapefile. length = 0 for row in cursor: # For all the individual features / lines in a polyline. length += row[0] arcpy.AddMessage( "Extracting the ending point of the river ...") river_end_shp = r'end_' + str( year ) + '.shp' # Variable for the shapefile of the end point of the polyline. arcpy.AddMessage( "Extracting the starting point of the river ...") river_start_shp = r'start_' + str( year ) + '.shp' # Variable for the shapefile of the start point of the polyline. arcpy.AddMessage( "Feature Vertices to Points for the 'start' and 'end' vertices of the river ..." ) arcpy.FeatureVerticesToPoints_management( shape, river_end_shp, "end" ) # Convert the last-end vertex of the polyline (river) to point, output River_end arcpy.FeatureVerticesToPoints_management( shape, river_start_shp, "start" ) # Convert the first-start vertex of the polyline (river) to point, output River_start. arcpy.AddMessage( "Calculating straight distance between start and end vertices of the river ..." ) distance_table = r'distance' + str(year) + '.dbf' arcpy.PointDistance_analysis( river_end_shp, river_start_shp, distance_table, "" ) # Calculate the straight distance between start and end and save it to a table cursor = arcpy.da.SearchCursor( distance_table, "DISTANCE" ) # Use a search cursor to go through the distance collumn in the created distance table. d = 0 # Variable for straight distance - direct distance for rows in cursor: # For the different rows of the distance collumn in the distance_table d = rows[ 0] # Add the different rows (the distance will always in the first row though) arcpy.AddMessage( "The straight distance between the starting and ending point is now computed and stored in the {}" .format(distance_table)) if normalize_sin_bool == 'true': sinuosity = d / length # Defined as Length / d but reverse is used, Max possible sinuosity = 1 . else: sinuosity = length / d # Normalized sinuosity index as used by ESRI toolbox. except: arcpy.AddMessage(arcpy.GetMessages()) arcpy.AddMessage("Adding field ...") arcpy.AddField_management( shape, 'sinuosity', 'DOUBLE' ) # Add a field in the river shapefile to store the sinuosity value arcpy.AddMessage("Calculating field ...") arcpy.CalculateField_management( shape, 'sinuosity', sinuosity, 'VB' ) # Calculate the sinuosity field - actually store the value in the table of the shapefile. ############################### ## Sinuosity per Section Part. ############################### if river_section_bool == 'true': # This condition is satisfied if the user selected to also calculate the Sinuosity Index per section. arcpy.AddMessage( "### Calculating sinuosity index for different parts of the river ####" ) arcpy.AddMessage( "You have selected {0} sections ".format(sections) ) # Need to move in the IF for the section statement arcpy.AddMessage("Creating new shapefiles ...") points_along_shape_shp = r'points_along_shape_' + str( year ) + '.shp' # Variable for the shapefile of the points along the river line. river_section_shp = 'river_sections_year_' + str( year ) + '.shp' # Variable for the shapefile of the river divided into sections. arcpy.AddMessage( "Calculating the length of sections in % of total length ..." ) per = 100 / int( sections ) # Calculate the percentage of each section based on the Number of Sections that the user asked with his input. arcpy.AddMessage( "The percentage of the total length for each section is :{}" .format(per)) arcpy.AddMessage( "Generating points along the river line ...") arcpy.GeneratePointsAlongLines_management( shape, points_along_shape_shp, "PERCENTAGE", Percentage=per, Include_End_Points='NO_END_POINTS' ) # Generate points along the based on the above calculate percentage. ##Added to delete the last point of the points along lines. points_temp = 'points_along_shape' + str( year ) + 'filtered.shp' # Temporary shapefile used to delete the point the the edge of the line from the points along the line. arcpy.MakeFeatureLayer_management(points_along_shape_shp, points_temp) sel_exp = "\"FID\"=" + str( int(sections) - 1 ) # The last one will have FID the number of sections -1 arcpy.SelectLayerByAttribute_management( points_temp, "NEW_SELECTION", sel_exp) if int( arcpy.GetCount_management(points_temp)[0] ) > 0: # If there are any features satisfying this condition - Will be! arcpy.DeleteFeatures_management( points_temp) # Delete them. ## arcpy.AddMessage("Spliting line on points ...") arcpy.SplitLineAtPoint_management( shape, points_along_shape_shp, river_section_shp, "2000 Meters" ) # Splitting the line into sections by using the above generate points. arcpy.AddMessage("Adding Geometry field ...") arcpy.AddGeometryAttributes_management( river_section_shp, "LENGTH", "METERS") # Get the length of each section arcpy.AddMessage("Adding field ...") arcpy.AddField_management( river_section_shp, 'SEC_LENGTH', 'DOUBLE' ) # Store the length in a new field "SEC_LENGTH" to be more clear - avoid confusion. arcpy.AddMessage("Calculating field ...") arcpy.CalculateField_management(river_section_shp, "SEC_LENGTH", "!LENGTH!", "PYTHON") arcpy.AddMessage( "Deleting field ..." ) # Delete the "LENGTH" field in the same logic. arcpy.DeleteField_management(river_section_shp, "LENGTH") arcpy.AddMessage( "The calculation of the length of each section was successful, the values are stored in the field " "\"SEC_LENGTH\"" " ") river_section_shp_lvl2 = 'river_sections_year_' + str( year ) + 'lvl2' + '.shp' # Variable for the shapefile of the river sections that will be used to be sure that the script will delete all the sections # that are substantially 'small' because in such a case the sinuosity values of that sections will be missleading arcpy.CopyFeatures_management(river_section_shp, river_section_shp_lvl2) temp_sec_len_l = [ ] # Create an empty list that will store all the length values of the different sections. cursor = arcpy.da.SearchCursor( river_section_shp_lvl2, "SEC_LENGTH" ) # Use a search cursor to go through the section length field. for row in cursor: temp_sec_len_l.append( int(row[0]) ) # Populate/Append each value of the field to the list we just created. minimum_section_length = min( temp_sec_len_l) # Find the minimum length per section. mean_section_length = sum(temp_sec_len_l) / len( temp_sec_len_l ) # And find the average length per section. arcpy.AddMessage("Minimum section length :{}".format( minimum_section_length)) arcpy.AddMessage("Average section length :{}".format( mean_section_length)) arcpy.AddMessage( "Deleting the substantially small sections ...") temp = 'river_sections_year_' + str( year ) + 'lvl3' + '.shp' # Temporary shapefile used to delete the 'small' sections arcpy.MakeFeatureLayer_management(river_section_shp_lvl2, temp) delete_thres = 0.35 # Threshold of deletion (Small section) is defined as 0.35 of the average length of the sections exp_sec_len = "\"SEC_LENGTH\" <" + str( delete_thres * mean_section_length) arcpy.SelectLayerByAttribute_management( temp, "NEW_SELECTION", exp_sec_len ) # Select the features by attributes based on the above threshold/expression if int( arcpy.GetCount_management(temp)[0] ) > 0: # If there are any features satisfying this condition - arcpy.AddWarning( "{} of the generated sections were substantially smaller than the average section length, and they are being deleted ..." .format(int(arcpy.GetCount_management(temp)[0]))) arcpy.DeleteFeatures_management(temp) # Delete them ###### arcpy.AddMessage("Adding field ...") arcpy.AddField_management( river_section_shp_lvl2, "startx", "DOUBLE" ) # Field that will store the X coordinate of the starting point of each section. arcpy.AddMessage("Adding field ...") arcpy.AddField_management( river_section_shp_lvl2, "starty", "DOUBLE" ) # Field that will store the Y coordinate of the starting point of each section. arcpy.AddMessage("Adding field ...") arcpy.AddField_management( river_section_shp_lvl2, "endx", "DOUBLE" ) # Field that will store the X coordinate of the ending point of each section. arcpy.AddField_management( river_section_shp_lvl2, "endy", "DOUBLE" ) # Field that will store the Y coordinate of the ending point of each section. arcpy.AddMessage("Adding field ...") arcpy.AddField_management( river_section_shp_lvl2, 'dirdis', 'DOUBLE' ) # Field that will store the direct distance for each section of the river from starting to ending vertex. arcpy.AddMessage("Adding field ...") arcpy.AddField_management( river_section_shp_lvl2, "sec_sin", "DOUBLE" ) # Field that will store the sinuosity of EACH Section. #Expressions for the calculations of the new fields. # Create the expressions in order to populate the fields that were just created above. exp_start_X = "!Shape!.positionAlongLine(0.0,True).firstPoint.X" # expression for starting X exp_start_Y = "!Shape!.positionAlongLine(0.0,True).firstPoint.Y" # expression for starting Y exp_end_X = "!Shape!.positionAlongLine(1.0,True).firstPoint.X" # expression for ending X exp_end_Y = "!Shape!.positionAlongLine(1.0,True).firstPoint.Y" # expression for ending Y arcpy.AddMessage("Calculating field ...") # Finally arcpy.CalculateField_management( river_section_shp_lvl2, "startx", exp_start_X, "PYTHON" ) # Populate/Calculate the starting X-coordinate of each section. arcpy.AddMessage("Calculating field ...") arcpy.CalculateField_management( river_section_shp_lvl2, "starty", exp_start_Y, "PYTHON" ) # Populate/Calculate the starting X-coordinate of each section. arcpy.AddMessage("Calculating field ...") arcpy.CalculateField_management( river_section_shp_lvl2, "endx", exp_end_X, "PYTHON" ) # Populate/Calculate the starting X-coordinate of each section arcpy.AddMessage("Calculating field ...") arcpy.CalculateField_management( river_section_shp_lvl2, "endy", exp_end_Y, "PYTHON" ) # Populate/Calculate the starting X-coordinate of each section # Based on the above (Xstart-Xend,Ystart,Yend) and using dd_exp = "math.sqrt((!startx!-!endx!)**2+(!starty!-!endy!)**2)" # The pythagoreum we can now get straight distance. arcpy.AddMessage("Calculating field ...") arcpy.CalculateField_management( river_section_shp_lvl2, "dirdis", dd_exp, "PYTHON" ) # Populate the field based on the pythagoreum expression for each section. if normalize_sin_bool == 'true': sin_exp = "!dirdis!/!SEC_LENGTH!" # Defined as Length / d but reverse is used, Max possible sinuosity = 1 . else: # Expression for Sinuosity Formula (direct distance / Length). sin_exp = "!SEC_LENGTH!/!dirdis!" arcpy.AddMessage("Calculating field ...") arcpy.CalculateField_management( river_section_shp_lvl2, "sec_sin", sin_exp, "PYTHON" ) # Populate/Calculate the sections sinuosity field based on the sinuosity expression for each section. arcpy.AddMessage( "The calculation of the sinuosity per section was successful, the values are stored in a field named " "\"sec_sin\"" " ")
import arcpy #export working railroad files to shapefiles # Replace a layer/table view name with a path to a dataset (which can be a layer file) or create the layer/table view within the script # The following inputs are layers or table views: "ActiveLines2013" arcpy.CalculateField_management("ActiveLines2013", "LRSKEY", """[RAILROAD] &"_" & [SUBDIVISIO]""", "VB", "#") # Replace a layer/table view name with a path to a dataset (which can be a layer file) or create the layer/table view within the script # The following inputs are layers or table views: "ActiveLines2013" arcpy.CreateRoutes_lr( "ActiveLines2013", "LRSKEY", "//gisdata/arcgis/GISdata/KDOT/BTP/Projects/RAIL/R1.shp", "ONE_FIELD", "LENGTHMILE", "#", "UPPER_RIGHT", "1", "0", "IGNORE", "INDEX") # Replace a layer/table view name with a path to a dataset (which can be a layer file) or create the layer/table view within the script # The following inputs are layers or table views: "ActiveStations", "R1" arcpy.LocateFeaturesAlongRoutes_lr( "ActiveStations", "R1", "LRSKEY", "1 Miles", "//gisdata/arcgis/gisdata/kdot/btp/projects/rail/stationlraf", "LRSKEY POINT MEAS", "FIRST", "DISTANCE", "ZERO", "FIELDS", "M_DIRECTON") #Make Route event layer # Replace a layer/table view name with a path to a dataset (which can be a layer file) or create the layer/table view within the script # The following inputs are layers or table views: "ActiveLines2013", "ActiveStationsSnap" arcpy.SplitLineAtPoint_management( "ActiveLines2013", "ActiveStationsSnap", "//gisdata/arcgis/GISdata/KDOT/BTP/Projects/RAIL/SplitLines.shp", "50 Feet")
Typ(FC) #--nodes--# if bool(Nodes) == True: arcpy.AddMessage("> creating nodes") arcpy.FeatureVerticesToPoints_management(FC, Node_Name, "BOTH_ENDS") arcpy.AddMessage("> deleting stacked nodes\n") arcpy.AddXY_management(Node_Name) fields = ["POINT_X", "POINT_Y"] arcpy.DeleteIdentical_management(Node_Name, fields) arcpy.DeleteField_management(Node_Name, fields) #--spliting links--# if bool(Split) == True: arcpy.AddMessage("> spliting links at nodes\n") arcpy.SplitLineAtPoint_management(FC, Node_Name, Split_Name, Radius) #--create cleare node and link numbers--# if bool(Double_Node) or bool(Double_Link) == True: VISUM = win32com.client.dynamic.Dispatch("Visum.Visum.22") VISUM.loadversion(Network) VISUM.Filters.InitAll() if bool(Double_Node) == True: arcpy.AddMessage("> creating clear node numbers") arcpy.AddField_management(Node_Name, "ID", "LONG") Nodes = numpy.array( VISUM.Net.Nodes.GetMultiAttValues("No")).astype("int")[:, 1] with arcpy.da.UpdateCursor(Node_Name, ['ID']) as cursor: Value = 20000 for row in cursor:
def conflate_tmc2projline(fl_proj, dirxn_list, tmc_dir_field, fl_tmcs_buffd, fields_calc_dict): speed_data_fields = [k for k, v in fields_calc_dict.items()] out_row_dict = {} # get length of project fld_shp_len = "SHAPE@LENGTH" fld_totprojlen = "proj_length_ft" with arcpy.da.SearchCursor(fl_proj, fld_shp_len) as cur: for row in cur: out_row_dict[fld_totprojlen] = row[0] for direcn in dirxn_list: # https://support.esri.com/en/technical-article/000012699 # temporary files scratch_gdb = arcpy.env.scratchGDB temp_intersctpts = os.path.join( scratch_gdb, "temp_intersectpoints" ) # r"{}\temp_intersectpoints".format(scratch_gdb) temp_intrsctpt_singlpt = os.path.join( scratch_gdb, "temp_intrsctpt_singlpt" ) # converted from multipoint to single point (1 pt per feature) temp_splitprojlines = os.path.join( scratch_gdb, "temp_splitprojlines" ) # fc of project line split up to match TMC buffer extents temp_splitproj_w_tmcdata = os.path.join( scratch_gdb, "temp_splitproj_w_tmcdata" ) # fc of split project lines with TMC data on them fl_splitprojlines = g_ESRI_variable_1 fl_splitproj_w_tmcdata = g_ESRI_variable_2 # get TMCs whose buffers intersect the project line arcpy.SelectLayerByLocation_management(fl_tmcs_buffd, "INTERSECT", fl_proj) # select TMCs that intersect the project and are in indicated direction sql_sel_tmcxdir = g_ESRI_variable_3.format(tmc_dir_field, direcn) arcpy.SelectLayerByAttribute_management(fl_tmcs_buffd, "SUBSET_SELECTION", sql_sel_tmcxdir) # split the project line at the boundaries of the TMC buffer, creating points where project line intersects TMC buffer boundaries arcpy.Intersect_analysis([fl_proj, fl_tmcs_buffd], temp_intersctpts, "", "", "POINT") arcpy.MultipartToSinglepart_management(temp_intersctpts, temp_intrsctpt_singlpt) # split project line into pieces at points where it intersects buffer, with 10ft tolerance # (not sure why 10ft tolerance needed but it is, zero tolerance results in some not splitting) arcpy.SplitLineAtPoint_management(fl_proj, temp_intrsctpt_singlpt, temp_splitprojlines, "10 Feet") arcpy.MakeFeatureLayer_management(temp_splitprojlines, fl_splitprojlines) # get TMC speeds onto each piece of the split project line via spatial join arcpy.SpatialJoin_analysis(temp_splitprojlines, fl_tmcs_buffd, temp_splitproj_w_tmcdata, "JOIN_ONE_TO_ONE", "KEEP_ALL", "#", "HAVE_THEIR_CENTER_IN", "30 Feet") # convert to fl and select records where "check field" col val is not none arcpy.MakeFeatureLayer_management(temp_splitproj_w_tmcdata, fl_splitproj_w_tmcdata) check_field = speed_data_fields[ 0] # choose first speed value field for checking--if it's null, then don't include those rows in aggregation sql_notnull = g_ESRI_variable_4.format(check_field) arcpy.SelectLayerByAttribute_management(fl_splitproj_w_tmcdata, "NEW_SELECTION", sql_notnull) # convert the selected records into a numpy array then a pandas dataframe flds_df = [fld_shp_len] + speed_data_fields df_spddata = utils.esri_object_to_df(fl_splitproj_w_tmcdata, flds_df) # remove project pieces with no speed data so their distance isn't included in weighting df_spddata = df_spddata.loc[pd.notnull( df_spddata[speed_data_fields[0]])].astype(float) # remove rows where there wasn't enough NPMRDS data to get a valid speed or reliability reading df_spddata = df_spddata.loc[df_spddata[flds_df].min(axis=1) > 0] dir_len = df_spddata[fld_shp_len].sum( ) #sum of lengths of project segments that intersect TMCs in the specified direction out_row_dict["{}_calc_len".format( direcn )] = dir_len #"calc" length because it may not be same as project length # go through and do conflation calculation for each TMC-based data field based on correct method of aggregation for field, calcmthd in fields_calc_dict.items(): if calcmthd == params.calc_inv_avg: # See PPA documentation on how to calculated "inverted speed average" method sd_dict = get_wtd_speed(df_spddata, field, direcn, fld_shp_len) out_row_dict.update(sd_dict) elif calcmthd == params.calc_distwt_avg: fielddir = "{}{}".format( direcn, field) # add direction tag to field names # if there's speed data, get weighted average value. linklen_w_speed_data = df_spddata[fld_shp_len].sum() if linklen_w_speed_data > 0: #wgtd avg = sum(piece's data * piece's len)/(sum of all piece lengths) avg_data_val = (df_spddata[field]*df_spddata[fld_shp_len]).sum() \ / df_spddata[fld_shp_len].sum() out_row_dict[fielddir] = avg_data_val else: out_row_dict[fielddir] = df_spddata[field].mean( ) #if no length, just return mean speed? Maybe instead just return 'no data avaialble'? Or -1 to keep as int? continue else: continue #cleanup fcs_to_delete = [ temp_intersctpts, temp_intrsctpt_singlpt, temp_splitprojlines, temp_splitproj_w_tmcdata ] for fc in fcs_to_delete: arcpy.Delete_management(fc) return pd.DataFrame([out_row_dict])
def conflate_link2projline(fl_proj, fl_links_buffd, links_desc): # get length of project fld_shp_len = "SHAPE@LENGTH" project_len = 0 with arcpy.da.SearchCursor(fl_proj, fld_shp_len) as cur: for row in cur: project_len += row[0] # temporary files temp_intersctpts = "temp_intersectpoints" temp_intrsctpt_singlpt = "temp_intrsctpt_singlpt" # converted from multipoint to single point (1 pt per feature) temp_splitprojlines = "temp_splitprojlines" # fc of project line split up to match link buffer extents temp_splitproj_w_linkdata = "temp_splitproj_w_linkdata" # fc of split project lines with link data on them fl_splitprojlines = "fl_splitprojlines" fl_splitproj_w_linkdata = "fl_splitproj_w_linkdata" # get links whose buffers intersect the project line arcpy.SelectLayerByLocation_management(fl_links_buffd, "INTERSECT", fl_proj) #split the project line at the boundaries of the link buffer, creating points where project line intersects link buffer boundaries arcpy.Intersect_analysis([fl_proj, fl_links_buffd], temp_intersctpts, "", "", "POINT") arcpy.MultipartToSinglepart_management(temp_intersctpts, temp_intrsctpt_singlpt) # split project line into pieces at points where it intersects buffer, with 10ft tolerance # (not sure why 10ft tolerance needed but it is, zero tolerance results in some not splitting) arcpy.SplitLineAtPoint_management(fl_proj, temp_intrsctpt_singlpt, temp_splitprojlines, "10 Feet") arcpy.MakeFeatureLayer_management(temp_splitprojlines, fl_splitprojlines) # get link speeds onto each piece of the split project line via spatial join arcpy.SpatialJoin_analysis(temp_splitprojlines, fl_links_buffd, temp_splitproj_w_linkdata, "JOIN_ONE_TO_ONE", "KEEP_ALL", "#", "HAVE_THEIR_CENTER_IN", "30 Feet") # convert to fl and select records where "check field" col val is not none arcpy.MakeFeatureLayer_management(temp_splitproj_w_linkdata, fl_splitproj_w_linkdata) #return total project length, project length that overlaps input line network, and pct join_count = "Join_Count" link_overlap_dist = 0 with arcpy.da.SearchCursor(fl_splitproj_w_linkdata, [fld_shp_len, join_count]) as cur: for row in cur: if row[1] > 0: link_overlap_dist += row[0] else: continue overlap_pct = link_overlap_dist / project_len links_desc = links_desc.replace(" ", "_") out_dict = { 'project_length': project_len, 'overlap with {}'.format(links_desc): link_overlap_dist, 'pct_proj_{}'.format(links_desc): overlap_pct } # cleanup fcs_to_delete = [ temp_intersctpts, temp_intrsctpt_singlpt, temp_splitprojlines, temp_splitproj_w_linkdata ] for fc in fcs_to_delete: arcpy.Delete_management(fc) return out_dict
def SplitLinksAnalysis(inStreetfile, Outfile): """This function first removes all freeways and ramps, then splits all roadway segments to less than 530 feet to prepare the street link and nodes file.""" global start_time global workspace # Remove Highways and Ramps try: whereclause1 = '''NOT "CLASS" = 'H' AND NOT "CLASS" = 'RAMP' ''' # Note Centerline file did not have HWY arcpy.AddMessage( "Create All Streets Network: Remove Highways and Ramps") arcpy.AddMessage("Where Clause: " + whereclause1) allstreetlyr = arcpy.MakeFeatureLayer_management( inStreetfile, "allstreetlyr", whereclause1) # Cleanup incase thier is any hanging files... if arcpy.Exists("SplitLine"): arcpy.Delete_management("SplitLine") # Split Lines until all roadway segments are less than 530 feet. count = 1 i = 0 RndptD = 250 # Used to split segments, halved every iteration to adjust random point splits. SptLn_start_time = time.time() arcpy.AddMessage("Start Split Line Process at: %s minutes ---" % (round((time.time() - start_time) / 60, 1))) while count > 0: i += 1 # Get Count of Features Greater than 530 feet arcpy.AddMessage(str(i) + " : Split segments >= 530 feet") whereclause2 = "shape_length >= 530" if not arcpy.Exists("SplitLine"): street2_lyr = arcpy.MakeFeatureLayer_management( allstreetlyr, "street2_lyr", whereclause2) allstreetlyr2 = allstreetlyr RndPtsSplt = str(RndptD) + " Feet" Cntresult = arcpy.GetCount_management(street2_lyr) count = int(Cntresult.getOutput(0)) arcpy.AddMessage("records to split:" + str(count)) if count < 1: break # Find Endpoints to remove slivers Ends1_lyr = arcpy.FeatureVerticesToPoints_management( allstreetlyr, "Ends1_lyr", "BOTH_ENDS") buffer = "50 Feet" Int4_buf_lyr = arcpy.Buffer_analysis(Ends1_lyr, "Int4_buf_lyr", buffer) # Split Lines at Random points based on "RndptsD", should splits 99% of points to required length. Rndptsft = arcpy.CreateRandomPoints_management( workspace, "Rndptsft", street2_lyr, "", 10000, RndPtsSplt) Rndptsft2_lyr = arcpy.MakeFeatureLayer_management( Rndptsft, "Rndptsft2_lyr") SplitptsLayer = arcpy.SelectLayerByLocation_management( in_layer=Rndptsft2_lyr, overlap_type="INTERSECT", select_features=Int4_buf_lyr, search_distance=".001 Feet", selection_type="NEW_SELECTION", invert_spatial_relationship="INVERT") else: street2_lyr = arcpy.MakeFeatureLayer_management( SplitLine, "street2_lyr" + str(i), whereclause2) allstreetlyr2 = arcpy.CopyFeatures_management( SplitLine, "in_memory/SplitLine" + str(i)) arcpy.AddMessage("Check for any remaining long segments") Cntresult = arcpy.GetCount_management(street2_lyr) count = int(Cntresult.getOutput(0)) arcpy.AddMessage("records to split:" + str(count)) if count < 1: break # Split Remaining Long Lines at Midpoints points to avoid slivers. SplitptsLayer = arcpy.FeatureVerticesToPoints_management( street2_lyr, "MidptsSplt", "MID") # Split Line ArcpySptLn_start_time = time.time() arcpy.AddMessage( " Start Splitting Lines Process at: %s minutes ---" % (round((time.time() - start_time) / 60, 1))) SplitLine = arcpy.SplitLineAtPoint_management( allstreetlyr2, SplitptsLayer, "SplitLine", "1 Feet") arcpy.AddMessage( " Complete Splitting Lines Processing Time: %s minutes ---" % (round((time.time() - ArcpySptLn_start_time) / 60, 1))) arcpy.AddMessage( str(i) + " :Split Line Process Complete %s minutes ---" % (round((time.time() - start_time) / 60, 1))) arcpy.AddMessage("Finish Process Iteration: " + str(i)) arcpy.AddMessage("------------------------------") arcpy.AddMessage("Complete Split Line Process at: %s minutes ---" % (round((time.time() - start_time) / 60, 1))) # Copy Final Feature Layers arcpy.AddMessage("Creating Outputs") # arcpy.CopyFeatures_management(Int3_lyr,outStreet + "_Ints") arcpy.CopyFeatures_management(SplitLine, Outfile) arcpy.AddMessage("Total Process Time: %s minutes ---" % (round( (time.time() - SptLn_start_time) / 60, 1))) arcpy.AddMessage("----------------------------------------------") # Cleanup arcpy.Delete_management(street2_lyr) arcpy.Delete_management(Int4_buf_lyr) arcpy.Delete_management(Rndptsft) arcpy.Delete_management(Rndptsft2_lyr) for x in range(i): try: ItsSplitLine = "in_memory/SplitLine" + str(x) arcpy.Delete_management(ItsSplitLine) except: pass except arcpy.ExecuteError: arcpy.AddMessage(arcpy.GetMessages(2)) except Exception as e: arcpy.AddMessage(e.args[0]) # If an error occurred, print line number and error message tb = sys.exc_info()[2] arcpy.AddMessage("An error occured on line %i" % tb.tb_lineno) arcpy.AddMessage(str(e)) arcpy.AddWarning( "Check feature class has CLASS field and H and RAMP values") print("--- %s minutes ---" % (round( (time.time() - start_time) / 60, 1)))
def main(): # import required modules and extensions import os import arcpy arcpy.CheckOutExtension('Spatial') # environment settings arcpy.env.workspace = 'in_memory' # set workspace to temporary workspace arcpy.env.overwriteOutput = True # set to overwrite output sr = arcpy.Describe(nhd_flowline_path).spatialReference # select lines from original nhd that are not coded as pipeline (fcdoe 428**) arcpy.MakeFeatureLayer_management(nhd_flowline_path, 'nhd_flowline_lyr') quer = """ "FCODE" >=42800 AND "FCODE" <= 42813 """ arcpy.SelectLayerByAttribute_management('nhd_flowline_lyr', 'NEW_SELECTION', quer) arcpy.SelectLayerByAttribute_management('nhd_flowline_lyr', 'SWITCH_SELECTION') flowline_network = arcpy.CopyFeatures_management('nhd_flowline_lyr', 'in_memory/flowline_selection') # dissolve flowline network by name #flowline_dissolve_name = arcpy.Dissolve_management(flowline_network, 'in_memory/flowline_dissolve', 'GNIS_NAME', '', 'SINGLE_PART', 'UNSPLIT_LINES') tmp_flowline_dissolve_name = arcpy.Dissolve_management(flowline_network, 'in_memory/flowline_dissolve_tmp', 'GNIS_NAME', '', 'SINGLE_PART', 'UNSPLIT_LINES') flowline_dissolve_name = arcpy.Sort_management(tmp_flowline_dissolve_name, 'in_memory/flowline_dissolve', [['Shape', 'DESCENDING']], 'PEANO') # create line id field and line length fields # if fields already exist, delete them check_fields = ['LineID', 'LineLen', 'SegID', 'SegLen', 'ReachID', 'ReachLen'] fields = [f.name for f in arcpy.ListFields(flowline_dissolve_name)] for field in fields: if field in check_fields: arcpy.DeleteField_management(flowline_dissolve_name, field) arcpy.AddField_management(flowline_dissolve_name, 'StreamName', 'TEXT', 50) arcpy.AddField_management(flowline_dissolve_name, 'StreamID', 'LONG') arcpy.AddField_management(flowline_dissolve_name, 'StreamLen', 'DOUBLE') ct = 1 with arcpy.da.UpdateCursor(flowline_dissolve_name, ['FID', 'StreamID', 'Shape@Length', 'StreamLen', 'GNIS_NAME', 'StreamName']) as cursor: for row in cursor: #row[1] = row[0] row[1] = ct row[3] = row[2] row[5] = row[4] ct += 1 cursor.updateRow(row) # dissolve flowline network flowline_dissolve_all = arcpy.Dissolve_management(flowline_network, 'in_memory/flowline_dissolve_all', '', '', 'SINGLE_PART', 'UNSPLIT_LINES') arcpy.AddField_management(flowline_dissolve_all, 'SegID', 'LONG') arcpy.AddField_management(flowline_dissolve_all, 'SegLen', 'DOUBLE') with arcpy.da.UpdateCursor(flowline_dissolve_all, ['FID', 'SegID', 'Shape@Length', 'SegLen']) as cursor: for row in cursor: row[1] = row[0] row[3] = row[2] cursor.updateRow(row) flowline_int = arcpy.Intersect_analysis([flowline_dissolve_name, flowline_dissolve_all], 'in_memory/flowline_int') keep = ['FID', 'Shape', 'StreamID', 'StreamLen', 'StreamName', 'SegID', 'SegLen'] drop = [] fields = [f.name for f in arcpy.ListFields(flowline_int)] for field in fields: if field not in keep: drop.append(field) arcpy.DeleteField_management(flowline_int, drop) # flip lines so segment points are created from end-start of line rather than start-end arcpy.FlipLine_edit(flowline_int) # create points at regular interval along each flowline seg_pts = arcpy.CreateFeatureclass_management('in_memory', 'seg_pts', 'POINT', '', 'DISABLED', 'DISABLED', sr) with arcpy.da.SearchCursor(flowline_int, ['SHAPE@'], spatial_reference = sr) as search: with arcpy.da.InsertCursor(seg_pts, ['SHAPE@']) as insert: for row in search: try: lineGeom = row[0] lineLength = row[0].length lineDist = interval while lineDist + min_segLength <= lineLength: newPoint = lineGeom.positionAlongLine(lineDist) insert.insertRow(newPoint) lineDist += interval except Exception as e: arcpy.AddMessage(str(e.message)) # split flowlines at segment interval points flowline_seg = arcpy.SplitLineAtPoint_management(flowline_int, seg_pts, 'in_memory/flowline_seg', 1.0) # add and populate reach id and length fields arcpy.AddField_management(flowline_seg, 'ReachID', 'SHORT') arcpy.AddField_management(flowline_seg, 'ReachLen', 'DOUBLE') with arcpy.da.UpdateCursor(flowline_seg, ['FID', 'ReachID', 'Shape@Length', 'ReachLen']) as cursor: for row in cursor: row[1] = row[0] row[3] = row[2] cursor.updateRow(row) # # get distance along route (LineID) for segment midpoints # midpoints = arcpy.FeatureVerticesToPoints_management(flowline_seg, 'in_memory/midpoints', "MID") # arcpy.CopyFeatures_management(midpoints, os.path.join(os.path.dirname(outpath), 'tmp_midpoints.shp')) # # arcpy.FlipLine_edit(flowline_int) # arcpy.AddField_management(flowline_int, 'From_', 'DOUBLE') # arcpy.AddField_management(flowline_int, 'To_', 'DOUBLE') # with arcpy.da.UpdateCursor(flowline_int, ['SegLen', 'From_', 'To_']) as cursor: # for row in cursor: # row[1] = 0.0 # row[2] = row[0] # cursor.updateRow(row) # # # arcpy.CreateRoutes_lr(flowline_int, 'SegID', 'in_memory/flowline_route', 'TWO_FIELDS', 'From_', 'To_') # routeTbl = arcpy.LocateFeaturesAlongRoutes_lr(midpoints, 'in_memory/flowline_route', 'SegID', # 1.0, os.path.join(os.path.dirname(outpath), 'tbl_Routes.dbf'), # 'RID POINT MEAS') # # distDict = {} # # add reach id distance values to dictionary # with arcpy.da.SearchCursor(routeTbl, ['ReachID', 'MEAS']) as cursor: # for row in cursor: # distDict[row[0]] = row[1] # # # populate dictionary value to output field by ReachID # arcpy.AddField_management(flowline_seg, 'ReachDist', 'DOUBLE') # with arcpy.da.UpdateCursor(flowline_seg, ['ReachID', 'ReachDist']) as cursor: # for row in cursor: # aKey = row[0] # row[1] = distDict[aKey] # cursor.updateRow(row) # # flip lines back to correct direction # arcpy.FlipLine_edit(flowline_seg) # save flowline segment output arcpy.CopyFeatures_management(flowline_seg, outpath) arcpy.Delete_management('in_memory')
def createSegments(contour_at_mean_high_water, contour_at_surge): # Start a timer time1 = time.clock() arcpy.AddMessage("\nSegmentation of the coastline started at "+str(datetime.now())) # Specify a tolerance distance or minimum length of a seawall # Users are not yet given control of this th = 150 # Create random points along the lines (mean high water and the surge of choice) # The numbers used are just my choice based on iterative observations random0 = arcpy.CreateRandomPoints_management(out_path= arcpy.env.workspace, \ out_name= "random0", \ constraining_feature_class= contour_at_mean_high_water, \ number_of_points_or_field= long(1600), \ minimum_allowed_distance = "{0} Feet".format(th)) random1 = arcpy.CreateRandomPoints_management(out_path= arcpy.env.workspace, \ out_name= "random1", \ constraining_feature_class= contour_at_surge, \ number_of_points_or_field= long(1600), \ minimum_allowed_distance = "{0} Feet".format(th)) # Perform a proximity analysis with the NEAR tool arcpy.Near_analysis(random0, random1) # Give each point a fixed unique ID # Create the ID field arcpy.AddField_management (random0, "UniqueID", "SHORT") arcpy.AddField_management (random1, "UniqueID", "SHORT") # Add Unique IDs arcpy.CalculateField_management(random0, "UniqueID", "[FID]") arcpy.CalculateField_management(random1, "UniqueID", "[FID]") # Categorize/Separate each feature based on their near feature # Crate a table view of random0 table0 = arcpy.MakeTableView_management(random0, "random0_table") #table1 = arcpy.MakeTableView_management(random1, "random1_table") # Sort the near feature for each points in random0 random0_sorted = arcpy.Sort_management(table0, "random0_sorte.dbf", [["NEAR_FID", "ASCENDING"]]) # Create "long enough" lists for each of the field of interests: ID, NEAR_ID, and NEAR_DIST # (distance to closest point). I added [99999] here to extend the list length and avoid IndexError list_fid = [r.getValue("UniqueID") for r in arcpy.SearchCursor(random0_sorted, ["UniqueID"])] +[99999] list_nearid = [r.getValue("NEAR_FID") for r in arcpy.SearchCursor(random0_sorted, ["NEAR_FID"])]\ +[99999] list_neardist = [r.getValue("NEAR_DIST") for r in arcpy.SearchCursor(random0_sorted, ["NEAR_DIST"])]\ +[99999] del r # Only take points with near feature within the specified threshold. If it's too far, it's not better # than the others for a segment point list_fid_filtered = [i for i in list_neardist if i < th] # Then initiate a list o contain their Unique ID and Near ID first_unique_id = [] first_near_id = [] # Get NEAR_ID and Unique ID for each of these points for i in list_fid_filtered: first_unique_id.append(list_fid[list_neardist.index(i)]) first_near_id.append(list_nearid[list_neardist.index(i)]) # Only take the unique values in case there are duplicates. This shoudn't happen. Just to make sure. first_unique_id = [i for i in set(first_unique_id)] first_near_id = [i for i in set(first_near_id)] # Now create a new feature out of these points # Frist let's create a Feature Layer arcpy.MakeFeatureLayer_management("random0.shp", "random0_lyr") # Let's select all points and export them into a new feature random0_points = arcpy.SearchCursor(random0, ["UniqueID"]) point0 = random0_points.next() for point0 in random0_points: for i in range(len(first_unique_id)): if point0.getValue("UniqueID") == first_unique_id[i]: selector0 = arcpy.SelectLayerByAttribute_management(\ "random0_lyr", "ADD_TO_SELECTION", '"UniqueID" = {0}'.format(first_unique_id[i])) del point0, random0_points new_random0 = arcpy.CopyFeatures_management(selector0, "new_random0") arcpy.Delete_management('random0_lyr') # Now for the new point feature, remove clusters of points around them and take only the ones # with minimum NEAR_DIST # First, get the geometry attributes of the new points arcpy.AddGeometryAttributes_management(new_random0, "POINT_X_Y_Z_M", "", "", "") # Create long enough list of the field of interest (same as the previous) pointx = [r.getValue("POINT_X") for r in arcpy.SearchCursor(new_random0, ["POINT_X"])] +[99999] pointy = [r.getValue("POINT_Y") for r in arcpy.SearchCursor(new_random0, ["POINT_Y"])] +[99999] new_list_fid = [r.getValue("UniqueID") for r in arcpy.SearchCursor(new_random0, ["UniqueID"])]\ +[99999] new_list_nearid = [r.getValue("NEAR_FID") for r in arcpy.SearchCursor(new_random0, ["NEAR_FID"])]\ +[99999] new_list_neardist = [r.getValue("NEAR_DIST") for r in arcpy.SearchCursor(new_random0, ["NEAR_DIST"])]\ +[99999] del r # Initiate a list of every points that has already been compared to the near points garbage = [] # Also initiate a list for the new Unique ID and NEAR ID new_unique_ID = [] new_near_ID = [] # Then, check if the points are right next to them. If so, add them to a temporary list # and find the one with closest near ID (or find minimum of their NEAR_DIST) for i in range(len(pointx)): if i+1 < len(pointx): # If not within the th range if not calculateDistance(pointx[i], pointy[i], pointx[i+1], pointy[i+1]) < float(th)*1.5: # Skip if it's in garbage if new_list_nearid[i] in garbage: continue else: new_unique_ID.append(new_list_fid[i]) new_near_ID.append(new_list_nearid[i]) # If within the range else: # Skip if it's in garbage if new_list_nearid[i] in garbage: continue else: temp_ID = [] temp_NEAR = [] temp_DIST = [] while True: temp_ID.append(new_list_fid[i]) temp_NEAR.append(new_list_nearid[i]) temp_DIST.append(new_list_neardist[i]) garbage.append(new_list_nearid[i]) i = i+1 # Stop when within the range again. And add the last point within the range if not calculateDistance(pointx[i], pointy[i], pointx[i+1], pointy[i+1]) < 200: temp_ID.append(new_list_fid[i]) temp_NEAR.append(new_list_nearid[i]) temp_DIST.append(new_list_neardist[i]) garbage.append(new_list_nearid[i]) # Calculate the minimum and get the Unique ID and Near ID minD = min(temp_DIST) new_unique_ID.append(new_list_fid[new_list_neardist.index(minD)]) new_near_ID.append(new_list_nearid[new_list_neardist.index(minD)]) del temp_ID, temp_NEAR, temp_DIST break # Now select these final points export them into new feature. # These are the end points for the segments to be created # First, make a layer out of all the random points arcpy.MakeFeatureLayer_management("random0.shp", "random0_lyr") arcpy.MakeFeatureLayer_management("random1.shp", "random1_lyr") # Then select and export the end points into feature0 and feature1 # Based on new_unique_ID for random0 random0_points = arcpy.SearchCursor(random0, ["UniqueID"]) point0 = random0_points.next() for point0 in random0_points: for i in range(len(new_unique_ID)): if point0.getValue("UniqueID") == new_unique_ID[i]: selected0 = arcpy.SelectLayerByAttribute_management(\ "random0_lyr", "ADD_TO_SELECTION", '"UniqueID" = {0}'.format(new_unique_ID[i])) feature0 = arcpy.CopyFeatures_management(selected0, "feature0") # Based on new_near_ID for random1 random1_points = arcpy.SearchCursor(random1, ["UniqueID"]) point1 = random1_points.next() for point1 in random1_points: for k in range(len(new_near_ID)): if point1.getValue("UniqueID") == new_near_ID[k]: selected1 = arcpy.SelectLayerByAttribute_management(\ "random1_lyr", "ADD_TO_SELECTION", '"UniqueID" = {0}'.format(new_near_ID[k])) feature1 = arcpy.CopyFeatures_management(selected1, "feature1") del point0, point1, random0_points, random1_points arcpy.Delete_management('random0_lyr') arcpy.Delete_management('random1_lyr') # Now for the actual create of the coastal segments # Which include creation of polygon and splitting the contours as the corresponding points # STEPS NECESSARY FOR POLYGON CREATION # Let's first add geometry attributes to these points arcpy.AddGeometryAttributes_management(feature0, "POINT_X_Y_Z_M", "", "", "") arcpy.AddGeometryAttributes_management(feature1, "POINT_X_Y_Z_M", "", "", "") # Let's create lines that connects points from feature0 to feature1 # Initiate a POLYLINE feature class for these lines arcpy.CreateFeatureclass_management (arcpy.env.workspace, "connector_lines.shp", "POLYLINE") # Then for each of the points in feature0, get the correspondingin feature1 # And create a line for each of the two points with arcpy.da.SearchCursor(feature0, ["NEAR_FID", "POINT_X", "POINT_Y"]) as features0: for feat0 in features0: with arcpy.da.SearchCursor(feature1, ["UniqueID", "POINT_X", "POINT_Y"]) as features1: x=0 for feat1 in features1: x = x+1 theseTwoPoints = [] if feat0[0] == feat1[0]: # Get coordinates X0, Y0 = feat0[1], feat0[2] X1, Y1 = feat1[1], feat1[2] # Append coordinates theseTwoPoints.append(arcpy.PointGeometry(arcpy.Point(X0, Y0))) theseTwoPoints.append(arcpy.PointGeometry(arcpy.Point(X1, Y1))) # Create line from the coordinates subline = arcpy.PointsToLine_management(theseTwoPoints, "subline"+str(x)+".shp") # Append all lines into one feature lines = arcpy.Append_management(["subline"+str(x)+".shp"], "connector_lines.shp") # Then delete subline as it's now unnecessary arcpy.Delete_management(subline) continue del feat0, feat1, features0, features1 # Now that the connectors are created, let's split the segments # Before splitting contours into segments, let's integrate the points and the segments # Just in case, there are misalignment arcpy.Integrate_management([contour_at_mean_high_water, feature0]) arcpy.Integrate_management([contour_at_surge, feature1]) segments0 = arcpy.SplitLineAtPoint_management(contour_at_mean_high_water, feature0, "segments0.shp", "10 Feet") segments1 = arcpy.SplitLineAtPoint_management(contour_at_surge, feature1, "segments1.shp", "10 Feet") # And let's give fixed unique ID for each segment arcpy.CalculateField_management(segments0, "Id", "[FID]") arcpy.CalculateField_management(segments1, "Id", "[FID]") # Now with the split segments and connector lines, let's make segment polygon of the segments almost_segment_polygons = arcpy.FeatureToPolygon_management([segments0, segments1, lines],\ "almost_segment_polygons.shp") # Adding unique ID to the segment polygons arcpy.CalculateField_management(almost_segment_polygons, "Id", "[FID]") # The Feature to Polygon process also created polygons that are surrounded by polygons # These are because these areas are surrounded by flooded areas at surge. # They are above the surge and technically safe. So, let's remove them. arcpy.MakeFeatureLayer_management(almost_segment_polygons, 'almost_segment_polygons_lyr') arcpy.MakeFeatureLayer_management(segments0, 'segments0_lyr') # Only the polygons within the mean_high_water segments are at risk arcpy.SelectLayerByLocation_management('almost_segment_polygons_lyr', 'INTERSECT', 'segments0_lyr') final_without_length = arcpy.CopyFeatures_management('almost_segment_polygons_lyr', 'final.shp') arcpy.Delete_management('segments0_lyr') arcpy.Delete_management('almost_segment_polygons_lyr') # For the new polygons, let's add the corresponding seawall length # Let's add Length field to both first arcpy.AddField_management(final_without_length, "Length", "SHORT") arcpy.AddField_management(segments0, "Length", "SHORT") # Calculation of the length with arcpy.da.UpdateCursor(segments0, ["SHAPE@LENGTH", "Length"]) as segments_0: for segment_0 in segments_0: length = segment_0[0] segment_0[1] = length segments_0.updateRow(segment_0) del segment_0, segments_0 # With spatial join, let's add these results to the segment polygons final = spatialJoin(final_without_length, segments0, "Length", "Length", "max", "joined_segment.shp") # Delete the created but now unnecessary files arcpy.Delete_management(random0) arcpy.Delete_management(random1) # Stop the timer time2 = time.clock() arcpy.AddMessage("Seawall segments and regions successfully created. It took "\ +str(time2-time1)+" seconds") return final
def main(): # Initialize variables arcpy.env.overwriteOutput = True watershed_folders = get_watershed_folders(root_folder) delete_old( os.path.join(root_folder, "00_ProjectWide", "Intermediates", "Reach_Editing", "Inputs")) project_networks = [] project_points = [] temps_to_delete = [] if fixed_points: network = os.path.join(root_folder, "00_ProjectWide", "Inputs", "Stream_Network", "Stream_Network.shp") fixed_folder = os.path.join(root_folder, "00_ProjectWide", "Intermediates", "Points", "Unsnapped_Fixed") save_fixed_points(network, fixed_folder, watershed_folders) # For each watershed: for watershed_folder in watershed_folders: arcpy.AddMessage("Starting {}...".format(watershed_folder)) # Get all file names output_folder = os.path.join(watershed_folder, "Intermediates", "Reach_Editing", "Inputs") network = os.path.join(watershed_folder, "Inputs", "Stream_Network", "Stream_Network.shp") delete_old(output_folder) new_tor_filename = "temp_tor.shp" new_tor_points = os.path.join(watershed_folder, new_tor_filename) temps_to_delete.append(new_tor_points) new_bor_filename = "temp_bor.shp" new_bor_points = os.path.join(watershed_folder, new_bor_filename) temps_to_delete.append(new_bor_points) old_tor_points = os.path.join(watershed_folder, "Intermediates", "Points", "Snapped", "TOR_Points_Snapped.shp") old_bor_points = os.path.join(watershed_folder, "Intermediates", "Points", "Snapped", "BOR_Points_Snapped.shp") if fixed_points: # Merge the now fixed points with the snapped points, and use this going forward tor_temp_name = "temp_tor_merge.shp" tor_temp_merge = os.path.join(watershed_folder, tor_temp_name) tor_fixed = \ os.path.join(watershed_folder, "Intermediates", "Points", "Unsnapped_Fixed", "TOR_Points_Fixed.shp") if not is_empty(tor_fixed): arcpy.Merge_management([tor_fixed, old_tor_points], tor_temp_merge) temps_to_delete.append(tor_temp_merge) old_tor_points = tor_temp_merge bor_temp_name = "temp_bor_merge.shp" bor_temp_merge = os.path.join(watershed_folder, bor_temp_name) bor_fixed = \ os.path.join(watershed_folder, "Intermediates", "Points", "Unsnapped_Fixed", "BOR_Points_Fixed.shp") if not is_empty(bor_fixed): arcpy.Merge_management([bor_fixed, old_bor_points], bor_temp_merge) temps_to_delete.append(bor_temp_merge) old_bor_points = bor_temp_merge arcpy.CopyFeatures_management(old_tor_points, new_tor_points) arcpy.CopyFeatures_management(old_bor_points, new_bor_points) points_list = [new_tor_points, new_bor_points] tor_bor_list = ("\"TOR\"", "\"BOR\"") # This loops once for TOR points, once for BOR points for points, tor_bor in zip(points_list, tor_bor_list): # Add and populate TOR_BOR Field arcpy.AddField_management(points, "TOR_BOR", "TEXT") arcpy.CalculateField_management(points, "TOR_BOR", tor_bor) # Merge TOR_BOR Points merge_location = os.path.join(watershed_folder, "Intermediates", "Reach_Editing", "Inputs", "Points_Merge.shp") merge_edit_location = os.path.join(watershed_folder, "Intermediates", "Reach_Editing", "Outputs", "Points_Merge_To_Edit.shp") arcpy.Merge_management(points_list, merge_location) arcpy.Merge_management(points_list, merge_edit_location) project_points.append(merge_location) # Dissolve the network new_network = os.path.join(watershed_folder, "temp_network.shp") temps_to_delete.append(new_network) arcpy.Dissolve_management(network, new_network) network = new_network new_network = os.path.join(watershed_folder, "temp_network2.shp") temps_to_delete.append(new_network) # Split network at points arcpy.SplitLineAtPoint_management(network, merge_location, new_network, "10 METERS") network = new_network network_layer = "Network" arcpy.MakeFeatureLayer_management(network, network_layer) # Make a new layer of only segments that intersect the field points arcpy.SelectLayerByLocation_management\ (network_layer, 'INTERSECT', merge_location) save_location = os.path.join(watershed_folder, "Intermediates", "Reach_Editing", "Inputs", "Stream_Network_Segments.shp") edit_location = os.path.join(watershed_folder, "Intermediates", "Reach_Editing", "Outputs", "Stream_Network_Segments_To_Edit.shp") arcpy.CopyFeatures_management(network_layer, save_location) arcpy.CopyFeatures_management(network_layer, edit_location) project_networks.append(save_location) arcpy.AddMessage("Saving ProjectWide...") make_projectwide(root_folder, project_points, project_networks) delete_temps(temps_to_delete) finish()