I have a set of points, and I want to build lines between pairs of points whenever their separating distance is within a specified tolerance. For example, 3 or 4 meters. Is there a way to do it in FME?
-
1I suggest you specify a software you're working with. – Erik Mar 25 '21 at 09:49
-
1A short answer: yes it is possible, but to answer how we need more details and more focus from you. For instance, the decision about a software/tool, what have you tried etc. – Taras Mar 25 '21 at 09:49
-
Do they share some attribute? Or is it obvious which two pair of points should be connected? – BERA Mar 25 '21 at 10:05
-
I am working with ArcGIS, but I can manage to use Qgis or FME Unfortunatly the points have no common attributes, just their X and Y coordinates – Liana Olianov Mar 25 '21 at 10:08
-
"I can manage to use three different softwares" is no specification. – Erik Mar 25 '21 at 11:00
-
Does this answer your question? QGIS: create lines to connect points which are within a distance to each other – JGH Mar 25 '21 at 12:36
-
Hi Liana, i tried to write you a script but the thread is closed. So i loaded it into github, check it out. https://github.com/florjanv/Points-2-lines – riflo Mar 25 '21 at 22:38
2 Answers
The NeighborFinder transformer is the tool for this.
Finds the nearest Candidate feature(s) to each Base feature and merges their attributes onto the Base feature. May also be used in Candidates Only mode, where each feature is considered the Base in turn and compared to all other features, but not itself.
You can set the maximum distance to your tolerance of 3 or 4 metres.
- 21,867
- 11
- 68
- 123
Here is a script in arcpy:
1 - Create a empty geodatabase
2 - copy your points inside it
Points - should be in projected coordinates system (the length need to be calculated).
3 - Create an empty line feature inside this .gdb (in the same coordinate system with points)
4 - change the parameters, depending in your paths and change the tolerance
5 - run the script
6 - the result will be extended in the line feature class, and some useful information will be added (linked points id,coordinates).
https://github.com/florjanv/Points-2-lines
import arcpy
import math
#parameters
f = r"C:\Users\user\Desktop\test\points\temp.gdb\Points" #input points feature class
lines_f = r"C:\Users\user\Desktop\test\points\temp.gdb\Lines" #empty line feature class
tolerance = 4 #the tolerance in meters
#variables
feature_id = []
total_x = []
total_y=[]
lines = []
def main():
desc = arcpy.Describe(f)
noZvalue()
#add joined fields
try:
arcpy.AddField_management(lines_f,"from_id","LONG")
arcpy.AddField_management(lines_f,"from_xy","TEXT",250)
arcpy.AddField_management(lines_f,"to_id","LONG")
arcpy.AddField_management(lines_f,"to_xy","TEXT",250)
arcpy.AddField_management(lines_f,"length","DOUBLE")
arcpy.AddField_management(lines_f,"dub","TEXT",50)
except:
print("fields exists")
with arcpy.da.InsertCursor(lines_f,["SHAPE@","from_id","from_xy","to_id","to_xy"]) as cursor:
for i in feature_id:
if lines[i]:
for j in lines[i]:
array = arcpy.Array([arcpy.Point(total_x[i], total_y[i]), arcpy.Point(total_x[j], total_y[j])])
cursor.insertRow([arcpy.Polyline(array),i+1,str(total_x[i])+", "+str(total_y[i]),j+1,str(total_x[j])+", "+str(total_y[j])])
#remove dublicated lines
arcpy.CalculateField_management(lines_f,"length","!SHAPE_Length!","PYTHON_9.3")
arcpy.CalculateField_management(lines_f,"dub",'str(!length!) +", " +str(abs( !from_id! - !to_id! ))',"PYTHON_9.3")
arcpy.DeleteIdentical_management(lines_f, "dub")
def noZvalue(): #function for calculating the distances without Z coordinate
oid = 0
for a in arcpy.da.SearchCursor(f,["SHAPE@X","SHAPE@Y"]):
total_x.append(round(a[0],4))
total_y.append(round(a[1],4))
feature_id.append(oid)
oid+=1
#fill the variable with id's that are nearer than 4m
for i in feature_id:
v1=[]
for j in feature_id:
dist=0
dist = math.sqrt(math.pow(total_x[j]-total_x[i],2)+math.pow(total_y[j]-total_y[i],2))
if dist<=tolerance:
if dist ==0: continue
v1.append(feature_id[j])
lines.append(v1)
if name == "main":
main()
Result, calculated for 1000 points:
- 1,155
- 7
- 13
