0

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?

7
  • 1
    I suggest you specify a software you're working with.
    – Erik
    Commented Mar 25, 2021 at 9:49
  • 1
    A 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
    Commented Mar 25, 2021 at 9:49
  • Do they share some attribute? Or is it obvious which two pair of points should be connected?
    – Bera
    Commented Mar 25, 2021 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 Commented Mar 25, 2021 at 10:08
  • "I can manage to use three different softwares" is no specification.
    – Erik
    Commented Mar 25, 2021 at 11:00

2 Answers 2

1

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.

0

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:

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.