Split survey data into lines#
We will try and automatically split a survey into flight lines using various techniques and compare there results to the hand-split lines from the published survey data.
[ ]:
%load_ext autoreload
%autoreload 2
import numpy as np
import pandas as pd
import plotly.io as pio
import airbornegeo
pio.renderers.default = "notebook"
Load data#
This is a subset of the BAS AGAP survey over Antarctica’s Gamburtsev Subglacial Mountains. The file is downloaded and subset in the notebook AGAP_magnetic_survey.
[ ]:
data_df = pd.read_csv("data/AGAP_magnetic_survey_processed_blocked.csv")
# only keep relevant columns
data_df = data_df[
[
"easting",
"northing",
"latitude",
"longitude",
"unixtime",
"line",
]
]
# retain only a subset of lines
data_df = data_df[(data_df.line.between(168, 176)) | (data_df.line.between(90, 127))]
# Construct Survey without line_column set initially
# The CSV has a "line" column that we'll process below
survey = airbornegeo.Survey(
data_df,
latitude_column="latitude",
longitude_column="longitude",
copy=False,
)
# rename lines starting from 1 using the functional API
survey.data["original_line"] = airbornegeo.unique_line_id(survey.data, "line")
survey.data = survey.data.drop(columns="line")
# Now bind line_column to the created original_line column
survey.line_column = "original_line"
# sort by time and line
# survey.data = survey.data.sort_values(by=["original_line", "unixtime"])
survey.data = survey.data.sort_values(by=["unixtime"])
survey.data.head()
[ ]:
print(f"Originally {len(survey.data.original_line.unique())} lines")
[ ]:
survey.plotly_points(
color_col="original_line",
hover_cols=[
"unixtime",
],
robust=False,
size=3,
)
Split lines on time gaps#
Here we assume any time gap greater than 2 minutes between successive points marks the end of one line and the start of another.
[ ]:
survey.split_into_segments(
threshold=60 * 2, # 2 minutes
column_name="unixtime",
result_column="segments_by_time",
)
print(f"{len(survey.data.segments_by_time.unique())} segments")
[ ]:
survey.data["time_dif"] = survey.data.groupby("segments_by_time").unixtime.diff()
print(f"Average jump between points: {np.mean(survey.data['time_dif']):.2f} seconds")
survey.data.time_dif.plot.hist(bins=50)
survey.data["time_dif"].describe()
[ ]:
survey.plotly_points(
color_col="segments_by_time",
hover_cols=[
"original_line",
"unixtime",
],
robust=False,
size=3,
)
Split lines on distance gaps#
Here we assume any distance gap greater than 5 km between successive points marks the end of one line and the start of another.
[ ]:
survey.relative_distance()
survey.split_into_segments(
threshold=5e3, # 5 km
column_name="relative_distance",
result_column="segments_by_distance",
)
print(f"{len(survey.data.segments_by_distance.unique())} segments")
[ ]:
survey.plotly_points(
color_col="segments_by_distance",
hover_cols=["original_line", "relative_distance"],
robust=False,
size=3,
)
Split lines on track / heading changes#
Here we assume any change of track (heading) more than 45 degrees between successive points marks the end of one line and the start of another. First we need to calculate the track from the latitude and longitude of the data.
[ ]:
survey.track()
survey.plotly_points(
color_col="track",
hover_cols=["original_line"],
size=3,
)
[ ]:
survey.data = survey.data.sort_values("unixtime")
survey.split_into_segments(
threshold=40, # 20 degree track change
column_name="track",
angular_difference=True, # the difference between two values on either side of (0/360) should be small
result_column="segments_by_track",
)
print(f"{len(survey.data.segments_by_track.unique())} segments")
[ ]:
survey.plotly_points(
color_col="segments_by_track",
hover_cols=["original_line", "track"],
robust=False,
size=3,
)
[ ]: