2. Find survey intersections#
[11]:
%load_ext autoreload
%autoreload 2
import logging
import geopandas as gpd
import pandas as pd
import plotly.io as pio
import airbornegeo
logging.getLogger("airbornegeo").setLevel("INFO")
logging.basicConfig()
pio.renderers.default = "notebook"
The autoreload extension is already loaded. To reload it, use:
%reload_ext autoreload
2.1. Load data#
This is a subset of the BAS AGAP survey over Antarcticaβs Gamburtsev Subglacial Mountains. The file is download and subset in the notebook AGAP_magnetic_survey, and the BAS processing steps are repeated in the notebook processing_AGAP_magnetic_survey.
[ ]:
data_df = pd.read_csv("data/AGAP_magnetic_survey_processed.csv")
data_df = data_df[
[
"easting",
"northing",
"height",
"line",
"unixtime",
"distance_along_line",
"mag",
]
]
# for testing limit number of lines
data_df = data_df[data_df.line.isin([149, 162, 47, 64, 80])]
data_df = data_df[
~(data_df.line == 47) | ~(data_df.distance_along_line.between(125e3, 134e3))
]
data_df = data_df[~(data_df.line == 64) | ~(data_df.distance_along_line > 497e3)]
data_df.head()
| easting | northing | height | line | unixtime | distance_along_line | mag | |
|---|---|---|---|---|---|---|---|
| 244630 | 1.078385e+06 | 324738.995745 | 4188.1 | 47 | 1.230251e+09 | 0.0 | 11.24 |
| 244631 | 1.078385e+06 | 324738.995745 | 4188.1 | 47 | 1.230251e+09 | 0.0 | 8.04 |
| 244632 | 1.078385e+06 | 324738.995745 | 4188.1 | 47 | 1.230251e+09 | 0.0 | 4.84 |
| 244633 | 1.078385e+06 | 324738.995745 | 4188.1 | 47 | 1.230251e+09 | 0.0 | 1.64 |
| 244634 | 1.078385e+06 | 324738.995745 | 4188.1 | 47 | 1.230251e+09 | 0.0 | -1.56 |
[13]:
# define flight lines vs tie lines with column 'tie' which is True or False
data_df["tie"] = False
data_df.loc[data_df.line >= 142, "tie"] = True
[14]:
data_df[data_df.tie].line.sort_values().unique()
[14]:
array([149, 162])
[15]:
data_df[~data_df.tie].line.sort_values().unique()
[15]:
array([47, 64, 80])
[16]:
airbornegeo.plotly_points(
data_df,
color_col="line",
hover_cols=["distance_along_line", "tie"],
)
2.2. Calculate intersections of lines and ties#
[17]:
# convert dataframe into geodataframe
data_df = gpd.GeoDataFrame(
data_df,
geometry=gpd.points_from_xy(data_df.easting, data_df.northing),
crs="EPSG:3031",
)
[21]:
# calculate theoretical intersection points
inters = airbornegeo.create_intersection_table(
data_df,
plot_hist=False,
)
inters
Line/tie combinations: 100%|ββββββββββ| 6/6 [00:00<00:00, 1449.23it/s]
Potential intersections: 100%|ββββββββββ| 5/5 [00:00<00:00, 203.44it/s]
INFO:airbornegeo:found 5 intersections
[21]:
| line | tie | geometry | max_dist | easting | northing | |
|---|---|---|---|---|---|---|
| 0 | 47 | 149 | POINT (590788 237703) | 12.785759 | 590788.0 | 237703.0 |
| 1 | 47 | 162 | POINT (947875 301515) | 1470.097394 | 947875.0 | 301515.0 |
| 2 | 64 | 162 | POINT (961606 224280) | 13.818089 | 961606.0 | 224280.0 |
| 3 | 80 | 149 | POINT (616278 93894) | 8.205492 | 616278.0 | 93894.0 |
| 4 | 80 | 162 | POINT (973552 156679) | 22.552582 | 973552.0 | 156679.0 |
From the above map and table we can see there are 5 intersection points. You can hover your mouse over the points in the plot to see some more information about them, including which line and tie they belong to, and the distance from the intersection point to the nearest actual measurement of the line and tie.
Theoretically since there are 2 ties and 3 lines, there could be 6 intersection points. Notice that line 64 ends just before crossing tie 149. If you zoom in on the flight survey plot, you can see this.
2.2.1. Buffer the ends of each line#
Since those two lines would cross if line 64 was just a few hundred meters longer, we can buffer all the lines to see if you can include it as an intersection. We show this below with the buffer_dist parameter.
[25]:
# calculate theoretical intersection points
inters = airbornegeo.create_intersection_table(
data_df,
buffer_dist=200, # if intersection would be within 200 m of end of line, include it
plot_hist=False,
)
inters
Line/tie combinations: 100%|ββββββββββ| 6/6 [00:00<00:00, 829.10it/s]
Potential intersections: 100%|ββββββββββ| 34/34 [00:00<00:00, 221.70it/s]
INFO:airbornegeo:found 6 intersections
[25]:
| line | tie | geometry | max_dist | easting | northing | |
|---|---|---|---|---|---|---|
| 0 | 47 | 149 | POINT (590788 237703) | 12.785759 | 590788.0 | 237703.0 |
| 1 | 47 | 162 | POINT (947753 301493) | 1346.129682 | 947753.0 | 301493.0 |
| 2 | 64 | 149 | POINT (604391 161048) | 173.862216 | 604391.0 | 161048.0 |
| 3 | 64 | 162 | POINT (961606 224280) | 13.818089 | 961606.0 | 224280.0 |
| 4 | 80 | 149 | POINT (616278 93894) | 8.205492 | 616278.0 | 93894.0 |
| 5 | 80 | 162 | POINT (973552 156679) | 22.552582 | 973552.0 | 156679.0 |
Now you can see weβve included this 6th intersection, and it was only ~170m away from the end of line 64. Notice that the itersection of line 47 and tie 162 is over 1 km away from the nearest actual data point of line 47. This might be too far away to be useful as an intersection.
2.2.2. Exclude intersections far away from data#
Below we show how the cutoff_dist parameter can be used to exclude intersections which are far away from either the tie or line data. Each itersection point has a max_dist parameter, which is the largest of the distances between the point and the nearest line data point, and the point and the nearest tie data point.
[33]:
# calculate theoretical intersection points
inters = airbornegeo.create_intersection_table(
data_df,
buffer_dist=500, # if intersection would be within 500 m of end of line, include it
cutoff_dist=1e3, # if intersection is more than 1km from nearest line or tie data, it is not included
plot_hist=False,
)
inters
Line/tie combinations: 100%|ββββββββββ| 6/6 [00:00<00:00, 865.13it/s]
Potential intersections: 100%|ββββββββββ| 34/34 [00:00<00:00, 209.31it/s]
INFO:airbornegeo:found 6 intersections
INFO:airbornegeo:removed 1 intersection point(s) with a max distance greater than 1 km
[33]:
| line | tie | geometry | max_dist | easting | northing | |
|---|---|---|---|---|---|---|
| 0 | 47 | 149 | POINT (590788 237703) | 12.785759 | 590788.0 | 237703.0 |
| 1 | 64 | 149 | POINT (604391 161048) | 173.862216 | 604391.0 | 161048.0 |
| 2 | 64 | 162 | POINT (961606 224280) | 13.818089 | 961606.0 | 224280.0 |
| 3 | 80 | 149 | POINT (616278 93894) | 8.205492 | 616278.0 | 93894.0 |
| 4 | 80 | 162 | POINT (973552 156679) | 22.552582 | 973552.0 | 156679.0 |
We have now successfull included the intersection which was within 200 m of the end of a line using the buffer_dist, and also excluded the intersection which was over 1 km away from the nearest data point, using cutoff_dist.
2.2.3. Manually exclude intersections#
We can manually exclude intersections if we know they have issues. You can supply tuples of pairs on line and tie numbers, or if you want to exclude an entire line or tie, just supply the individual line or tie number.
[53]:
# calculate theoretical intersection points
inters = airbornegeo.create_intersection_table(
data_df,
buffer_dist=500, # if intersection would be within 500 m of end of line, include it
cutoff_dist=1e3, # if intersection is more than 1km from nearest line or tie data, it is not included
exclude_ints=[
[47],
[80, 149],
], # exclude all intersection of line 47 and the intersection of 80 and 149
plot_hist=False,
)
inters
Line/tie combinations: 100%|ββββββββββ| 6/6 [00:00<00:00, 927.33it/s]
Potential intersections: 100%|ββββββββββ| 34/34 [00:00<00:00, 227.49it/s]
INFO:airbornegeo:found 6 intersections
INFO:airbornegeo:removed 1 intersection point(s) with a max distance greater than 1 km
INFO:airbornegeo:manually omitted 2 intersections points
[53]:
| line | tie | geometry | max_dist | easting | northing | |
|---|---|---|---|---|---|---|
| 0 | 64 | 149 | POINT (604391 161048) | 173.862216 | 604391.0 | 161048.0 |
| 1 | 64 | 162 | POINT (961606 224280) | 13.818089 | 961606.0 | 224280.0 |
| 2 | 80 | 162 | POINT (973552 156679) | 22.552582 | 973552.0 | 156679.0 |