Counting number of lines connected to point?
It is not a problem of geometry (buffer, etc.) but a simple problem of Graph Theory (nodes and connected edges) and Python has many modules for dealing with Graphs (PythonGraphApi, Graphs in Python, Python Patterns - Implementing Graphs, ...)
In your problem, you don't need a point layer, you only need the points/nodes of the polyline. They are the vertex/nodes of a Graph and the segments between two nodes are the edges of the same Graph. And you want to find the nodes with a degree 2 and 3 (number of edges incident to the vertex = when 2 lines connect to a point, I want to install an elbow, when 3 lines connect, I want to install a Tee)
The layer:
The corresponding Graph where we can see directly the desired points (2 and 3 lines connect - figure made with the NetworkX module):
I will use here the NetworkX module (pure Python module). The module can directly open shapefiles to generates a networkx.Graph (Networkx: GIS shapefile) but I do so in the Python console of QGIS:
We need to extract all the segments of the layer (from point to point): the LineString must be iterated over pairs to divide the polyline in segments.
def pairs(list):
'''generator to iterate over pairs in a list '''
for i in range(1, len(list)):
yield list[i-1], list[i]
Creation of the Graph:
import networkx as nx
# select the polyline layer
layer = qgis.utils.iface.activeLayer()
# create a Graph
G = nx.Graph()
# add the nodes and the edges to the Graph = segment point i -> point i+1
for features in layer.getFeatures():
segment = features.geometry().asPolyline()
# add the two end points of a segment as two nodes and an edge (point1 -> point2) to the Graph
for seg_start, seg_end in pair(segment):
G.add_edges_from([(seg_start, seg_end)])
Now we have the nodes and the edges of the Graph:
print G.nodes() # = nodes of the polyline in (x,y) form
[(198133,93258.8), (198757,93232.4), (197592,94296.2), (197579,93232.4), (198761,94274.3), (198146,94287.5)]
print G.edges() # = all the segments of the polyline
[((198133,93258.8), (198146,94287.5)), ((198757,93232.4), (198761,94274.3)), ((197592,94296.2), (197579,93232.4)), ((197592,94296.2), (198146,94287.5)), ((198761,94274.3), (198146,94287.5))]
We search the nodes which the degree is > 1
for i in G.nodes():
if G.degree(i) > 1:
print QgsPoint(i), G.degree(i)
(197592,94296.2) 2
(198761,94274.3) 2
(198146,94287.5) 3
And we obtain the desired points:
Result:
It depends on Your data structure and precision but I assume that You have separate layers for points and lines. If so, this is relatively easy with Python (either PyQGIS or arcpy) - example with pyqgis could look like this:
#point_layer - vector layer with points
#line_layer - vector layer with lines
iter_p=point_layer.getFeatures() #features from layer
iter_l=list(line_layer.getFeatures()) #changing iterator to list to avoid exhaustion
connections=0 #counter for number of intersections
for p in iter_p:
geom_p=p.geometry().buffer(10,3) #create a small buffer around points, 10 is an arbitrary value, change it according to precision of Your data
for l in iter_l:
geom_l=l.geometry()
if geom_p.intersects(geom_l):
connections=connections+1 # if intersection is true increase counter by one
if connections==2:
#here a set of instructions for doing something - for example changing attrubute value for Tee, elbow or something else
#etc...for each significant value of intersections
connections=0 #reseting counter
In Arcgis, the most simple way is to use "spatial join" : this will give you the count of lines that interesect your point. In order to make sure that your points are exactly located at the intersections, an integrate could be necessary.
On the other hand, you should be aware of your topology in order to know what you are counting. You assume here that all your lines are split at point location, but you should make sure of that. Otherwise, you could have points that intersect 2 lines on a Tee. A more robust method would thus consist in creating buffers around each point and counting the number of point intersections between your lines and your buffer, not just the number of lines that intersect.