Intersection point between two lines using GeoPandas

0

Good morning, everyone. I'm making a code and I came across a problem.

I'm using GeoPandas and I need to find the intersection between two Linestring Z and their elevation values (Z).

What has happened is that when executing the intersection function this returns me correct X and Y, but not Z for each line.

Example: Intersection in line Orange = (2,1,3) Intersection on the lineVerde = (2,1,4)

Thus, X and Y would be equal, but the non-elevations (Z1 = 3 and Z2 = 4)

Used code and result

orange_line.zip line. (green_line) .z

Result = 3

line_Verde.intersection. (orange_line) .z

Result = 3 (should be 4)

Below I have illustrated the problem.

As the points in my lines are not the same, this XYZ of the intersection must come from an interpolation.

Below is the code I'm using:

import numpy as np
import pandas as pd
import geopandas as gpd
from shapely.geometry import LineString, Point


def load_xyz(file_path, file_name, spatial_reference, sep=';', header=0):
    df = pd.read_csv(file_path+'\'+file_name, header=header, sep=sep,
                     names=['Line','X','Y','Z'])

    gdf = gpd.GeoDataFrame(df.values,
                           crs=spatial_reference,
                           geometry=[Point(xyz) for xyz in zip(df['X'], df['Y'], df['Z'])],
                           columns=['Line','X','Y','Z'])

    gdf = gdf.groupby(['Line'])['geometry'].apply(lambda x: LineString(x.tolist()))

    return gdf, df



spatial_reference = {'init': 'epsg:32724'}

file_path = r'C:\Users\VN\Desktop'
file_name = r'xyz.csv'
df_lines, df_lines_raw = load_xyz(file_path, file_name, spatial_reference)

file_path = r'C:\Users\VN\Desktop'
file_name = r'xyz_cross.csv'
df_cross, df_cross_raw = load_xyz(file_path, file_name, spatial_reference)


cross_validation = gpd.GeoDataFrame([],
                                    columns=['Line','Cross_Line','X','Y','Z1','Z2'],
                                    crs=spatial_reference)


lines_names = df_lines.index.tolist()
cross_names  = df_cross.index.tolist()
idx = 0


for i in range(len(df_lines)):
    for j in range(len(df_cross)):
        if(df_lines[i].crosses(df_cross[j])):
            cross_validation.loc[idx, 'Line'] = lines_names[i]
            cross_validation.loc[idx, 'Cross_Line'] = cross_names[j]
            cross_validation.loc[idx, 'X'] = df_lines[i].intersection(df_cross[j]).x
            cross_validation.loc[idx, 'Y'] = df_lines[i].intersection(df_cross[j]).y
            cross_validation.loc[idx, 'Z1'] = df_lines[i].intersection(df_cross[j]).z
            cross_validation.loc[idx, 'Z2'] = df_cross[j].intersection(df_lines[i]).z
            idx = idx + 1


print(cross_validation)

Thank you!

    
asked by anonymous 29.11.2017 / 14:18

1 answer

0

Try this function:

   def exists_intersection(line1, line2):

    def ccw(A,B,C):
        return (C[1]-A[1])*(B[0]-A[0]) > (B[1]-A[1])*(C[0]-A[0])

    def intersect(line1, line2):
        A,B = line1
        C,D = line2
        bol1 = ccw(A,C,D) != ccw(B,C,D) and ccw(A,B,C) != ccw(A,B,D)
        bol2 = (A == C or A == D) or (B == C or B == D)
        return bol1 or bol2

    resultado = []

    x1, y1 = line1[0]
    x2, y2 = line1[1]

    x3, y3 = line2[0]
    x4, y4 = line2[1]

    px_a, px_b = ((x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4)), ((x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4))
    py_a, py_b = ((x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4)), ((x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4))

    if ([px_a, px_b] != [0, 0] and [px_b, py_b] != [0, 0]):
        if intersect(line1, line2):
            px, py = px_a/px_b , py_a/py_b
            resultado = [px, py]

    return resultado

I used it for straight lines, I'm not sure of the result in curves, but maybe it will help.

    
26.11.2018 / 16:01