crs-l2-fiji-antimeridian

Status: done
Score: 0
Duration: 2:17
Cost: 0.76¢
Model: deepseek/deepseek-v4-flash

Map (reference ← swipe → agent)

0:00
I'm pulling together per-transect coverage figures for our survey report, but some of the lines in fiji_transects_wgs84.geojson render as arcs spanning the entire globe instead of short local segments. Can you fix the geometries so they render correctly, convert them to Fiji's national metric grid, and give me each transect as one MultiLineString feature with a length_m attribute in metres? Every feature must come out as a MultiLineString, so do not leave any transects as plain LineString, and the problematic ones must end up as multi-part geometries that faithfully represent the actual survey path. Carry the survey attributes (vessel and survey_date) through unchanged, use transect_id as the key field, and write the result as GeoJSON named fiji_transects_fmg.geojson.
0:00
System info
{
  "adapter": "openrouter",
  "model": "deepseek/deepseek-v4-flash",
  "base_url": "https://openrouter.ai/api/v1"
}
0:03
Let me start by examining the input file to understand the data and identify the problematic geometries.
0:03
Read /work/fiji_transects_wgs84.geojson
     1	{
     2	"type": "FeatureCollection",
     3	"name": "fiji_transects_wgs84",
     4	"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } },
     5	"features": [
     6	{ "type": "Feature", "properties": { "transect_id": "T001", "vessel": "Taveuni II", "survey_date": "2025-08-15", "crosses_antimeridian_flag": true }, "geometry": { "type": "LineString", "coordinates": [ [ 178.941879580782086, -17.632301816020771 ], [ 179.456655009654696, -17.623768593111961 ], [ 179.971430438527307, -17.611072392823225 ], [ -179.513794132600054, -17.596198176111951 ], [ -178.999018703727444, -17.579632069513806 ], [ -178.484243274854833, -17.577321872344196 ] ] } },
     7	{ "type": "Feature", "properties": { "transect_id": "T002", "vessel": "Bligh", "survey_date": "2025-08-12", "crosses_antimeridian_flag": true }, "geometry": { "type": "LineString", "coordinates": [ [ 179.070288824800542, -17.334767984150709 ], [ 179.725942881740252, -17.171343988196945 ], [ -179.618403061320009, -17.007726843860763 ], [ -178.962749004380299, -16.834850408534852 ] ] } },
     8	{ "type": "Feature", "properties": { "transect_id": "T003", "vessel": "Lomaiviti", "survey_date": "2025-08-12", "crosses_antimeridian_flag": true }, "geometry": { "type": "LineString", "coordinates": [ [ 177.636947428758333, -17.358837040696127 ], [ 178.462815605623859, -17.416074837434927 ], [ 179.288683782489386, -17.471713663377283 ], [ -179.885448040645059, -17.527675804260884 ], [ -179.059579863779533, -17.590577543375694 ] ] } },
     9	{ "type": "Feature", "properties": { "transect_id": "T004", "vessel": "Vanua I", "survey_date": "2025-08-15", "crosses_antimeridian_flag": true }, "geometry": { "type": "LineString", "coordinates": [ [ 178.873696381462679, -17.803295238757038 ], [ 179.542254331047587, -17.598477321703708 ], [ -179.789187719367533, -17.405549472537043 ], [ -179.120629769782624, -17.19411411231702 ], [ -178.452071820197745, -16.992332922174427 ], [ -177.783513870612836, -16.795171196845544 ] ] } },
    10	{ "type": "Feature", "properties": { "transect_id": "T005", "vessel": "Bligh", "survey_date": "2025-08-19", "crosses_antimeridian_flag": true }, "geometry": { "type": "LineString", "coordinates": [ [ 177.596924830927293, -17.923255155112717 ], [ 178.160696712947697, -18.010328270600898 ], [ 178.724468594968101, -18.099224972140938 ], [ 179.288240476988506, -18.17532145144995 ], [ 179.85201235900891, -18.270380145331412 ], [ -179.584215758970686, -18.358875431719703 ], [ -179.020443876950281, -18.437390943572723 ] ] } },
    11	{ "type": "Feature", "properties": { "transect_id": "T006", "vessel": "Cakaulevu", "survey_date": "2025-08-13", "crosses_antimeridian_flag": true }, "geometry": { "type": "LineString", "coordinates": [ [ 178.622166647099931, -18.382052393687179 ], [ 179.205668025282989, -18.184610858038685 ], [ 179.789169403466019, -17.991866703295319 ], [ -179.627329218350923, -17.789532271264445 ], [ -179.043827840167864, -17.595682751178369 ], [ -178.460326461984835, -17.393483000040479 ], [ -177.876825083801776, -17.203490564162109 ] ] } },
    12	{ "type": "Feature", "properties": { "transect_id": "T007", "vessel": "Vanua I", "survey_date": "2025-08-19", "crosses_antimeridian_flag": true }, "geometry": { "type": "LineString", "coordinates": [ [ 177.920101619592742, -17.14979850360189 ], [ 178.697177550619955, -17.100522188212071 ], [ 179.474253481647168, -17.053867486482115 ], [ -179.74867058732562, -17.004197778897627 ], [ -178.971594656298407, -16.959481244370728 ], [ -178.194518725271195, -16.911697858015476 ] ] } },
    13	{ "type": "Feature", "properties": { "transect_id": "T008", "vessel": "Taveuni II", "survey_date": "2025-08-12", "crosses_antimeridian_flag": true }, "geometry": { "type": "LineString", "coordinates": [ [ 179.401134548056262, -17.934415957637167 ], [ 179.67454249485786, -17.899654147497863 ], [ 179.947950441659486, -17.858130727687527 ], [ -179.778641611538916, -17.811143619533269 ], [ -179.50523366473729, -17.768768396969666 ], [ -179.231825717935692, -17.724708363613253 ] ] } },
    14	{ "type": "Feature", "properties": { "transect_id": "T009", "vessel": "Vanua I", "survey_date": "2025-08-13", "crosses_antimeridian_flag": true }, "geometry": { "type": "LineString", "coordinates": [ [ 178.068433112639013, -16.657838811131668 ], [ 178.561564721122721, -16.689731320158675 ], [ 179.054696329606429, -16.72173241552732 ], [ 179.547827938090137, -16.748891897767297 ], [ -179.959040453426155, -16.775241845025921 ], [ -179.465908844942447, -16.799281899607834 ] ] } },
    15	{ "type": "Feature", "properties": { "transect_id": "T010", "vessel": "Vanua I", "survey_date": "2025-08-15", "crosses_antimeridian_flag": true }, "geometry": { "type": "LineString", "coordinates": [ [ 177.602847396853463, -17.277026295424367 ], [ 179.128053569323441, -17.468285296635063 ], [ -179.346740258206609, -17.65419136085664 ], [ -177.82153408573663, -17.837325774502055 ] ] } },
    16	{ "type": "Feature", "properties": { "transect_id": "T011", "vessel": "Taveuni II", "survey_date": "2025-08-20", "crosses_antimeridian_flag": false }, "geometry": { "type": "LineString", "coordinates": [ [ -176.863797870333627, -17.7932433540029 ], [ -176.985724572324699, -17.81273654528005 ], [ -177.107651274315742, -17.824236921378098 ], [ -177.229577976306814, -17.835861250474697 ], [ -177.351504678297886, -17.857559546831705 ], [ -177.473431380288929, -17.871769203842408 ], [ -177.595358082280001, -17.890225470404214 ] ] } },
    17	{ "type": "Feature", "properties": { "transect_id": "T012", "vessel": "Taveuni II", "survey_date": "2025-08-20", "crosses_antimeridian_flag": false }, "geometry": { "type": "LineString", "coordinates": [ [ 176.312195951017685, -17.976122209608448 ], [ 176.362236324041447, -17.722210270969462 ], [ 176.412276697065209, -17.470306839752467 ], [ 176.462317070088972, -17.226475769084448 ] ] } },
    18	{ "type": "Feature", "properties": { "transect_id": "T013", "vessel": "Bligh", "survey_date": "2025-08-19", "crosses_antimeridian_flag": false }, "geometry": { "type": "LineString", "coordinates": [ [ -176.70823848972006, -17.696306145080879 ], [ -177.205026853648661, -17.960082567744127 ], [ -177.701815217577291, -18.210737758337459 ], [ -178.198603581505893, -18.469124252379427 ] ] } },
    19	{ "type": "Feature", "properties": { "transect_id": "T014", "vessel": "Lomaiviti", "survey_date": "2025-08-13", "crosses_antimeridian_flag": false }, "geometry": { "type": "LineString", "coordinates": [ [ 176.538496893308832, -16.594358164012139 ], [ 176.861572490827996, -16.71494251806207 ], [ 177.184648088347188, -16.832251271240672 ], [ 177.507723685866381, -16.976116506165042 ], [ 177.830799283385545, -17.090939089364483 ] ] } },
    20	{ "type": "Feature", "properties": { "transect_id": "T015", "vessel": "Vanua I", "survey_date": "2025-08-15", "crosses_antimeridian_flag": false }, "geometry": { "type": "LineString", "coordinates": [ [ -177.278377449219306, -16.724372731501912 ], [ -177.470251917030794, -16.761535677586746 ], [ -177.662126384842253, -16.787182414326686 ], [ -177.854000852653712, -16.818799270133983 ], [ -178.0458753204652, -16.856282470705128 ], [ -178.237749788276659, -16.891308864567598 ], [ -178.429624256088147, -16.914729063096839 ] ] } },
    21	{ "type": "Feature", "properties": { "transect_id": "T016", "vessel": "Taveuni II", "survey_date": "2025-08-15", "crosses_antimeridian_flag": false }, "geometry": { "type": "LineString", "coordinates": [ [ 178.445325115686984, -18.225562645051426 ], [ 178.570919872630384, -18.22187730118792 ], [ 178.696514629573755, -18.228085980840198 ], [ 178.822109386517127, -18.243164774607269 ], [ 178.947704143460527, -18.232257588046291 ] ] } },
    22	{ "type": "Feature", "properties": { "transect_id": "T017", "vessel": "Taveuni II", "survey_date": "2025-08-12", "crosses_antimeridian_flag": false }, "geometry": { "type": "LineString", "coordinates": [ [ -176.949497668404376, -16.593233226112279 ], [ -177.073130399044231, -16.796136633276152 ], [ -177.196763129684086, -16.985064764093782 ], [ -177.320395860323913, -17.188172387851619 ], [ -177.444028590963768, -17.380278567766066 ], [ -177.567661321603623, -17.571298263401527 ], [ -177.691294052243478, -17.76827441812642 ] ] } },
    23	{ "type": "Feature", "properties": { "transect_id": "T018", "vessel": "Bligh", "survey_date": "2025-08-19", "crosses_antimeridian_flag": false }, "geometry": { "type": "LineString", "coordinates": [ [ 176.111138114901024, -16.851117503263293 ], [ 176.291399614433374, -17.034309766495799 ], [ 176.471661113965695, -17.221302006070296 ], [ 176.651922613498016, -17.402317112686557 ], [ 176.832184113030365, -17.592994204367653 ] ] } },
    24	{ "type": "Feature", "properties": { "transect_id": "T019", "vessel": "Lomaiviti", "survey_date": "2025-08-12", "crosses_antimeridian_flag": false }, "geometry": { "type": "LineString", "coordinates": [ [ 178.007516628261584, -17.706954766350957 ], [ 177.596962177324428, -17.607161226082525 ], [ 177.186407726387301, -17.511279680346377 ], [ 176.775853275450146, -17.418568907300433 ], [ 176.36529882451299, -17.326891370330944 ] ] } },
    25	{ "type": "Feature", "properties": { "transect_id": "T020", "vessel": "Taveuni II", "survey_date": "2025-08-13", "crosses_antimeridian_flag": false }, "geometry": { "type": "LineString", "coordinates": [ [ 176.869640838143511, -17.085093978662378 ], [ 177.34023164697706, -17.269542693344249 ], [ 177.810822455810609, -17.442447410976666 ], [ 178.281413264644158, -17.624621823987695 ], [ 178.752004073477707, -17.807162082048386 ] ] } },
    26	{ "type": "Feature", "properties": { "transect_id": "T021", "vessel": "Vanua I", "survey_date": "2025-08-16", "crosses_antimeridian_flag": false }, "geometry": { "type": "LineString", "coordinates": [ [ 176.258661225850091, -17.092877710432774 ], [ 176.830345357965598, -17.521807453385343 ], [ 177.402029490081105, -17.943438299004075 ], [ 177.973713622196613, -18.366984215963161 ] ] } },
    27	{ "type": "Feature", "properties": { "transect_id": "T022", "vessel": "Vanua I", "survey_date": "2025-08-15", "crosses_antimeridian_flag": false }, "geometry": { "type": "LineString", "coordinates": [ [ 177.115699442929383, -17.820293640195572 ], [ 177.180354072206086, -17.755581112632651 ], [ 177.245008701482789, -17.684692899482695 ], [ 177.30966333075952, -17.61995755685173 ], [ 177.374317960036223, -17.544174647257226 ], [ 177.438972589312925, -17.479955835030527 ] ] } },
    28	{ "type": "Feature", "properties": { "transect_id": "T023", "vessel": "Lomaiviti", "survey_date": "2025-08-12", "crosses_antimeridian_flag": false }, "geometry": { "type": "LineString", "coordinates": [ [ -177.191351883954098, -17.679938619650844 ], [ -177.334313691261116, -17.740394590021616 ], [ -177.477275498568133, -17.794367957957562 ], [ -177.62023730587515, -17.835119945356809 ], [ -177.763199113182168, -17.904282380225705 ], [ -177.906160920489185, -17.955635131096855 ] ] } },
    29	{ "type": "Feature", "properties": { "transect_id": "T024", "vessel": "Vanua I", "survey_date": "2025-08-12", "crosses_antimeridian_flag": false }, "geometry": { "type": "LineString", "coordinates": [ [ -179.108274205314615, -16.84950325482971 ], [ -178.651703763804733, -16.962456436762313 ], [ -178.195133322294822, -17.077410225872036 ], [ -177.73856288078494, -17.187966865781235 ], [ -177.281992439275029, -17.288042922581088 ], [ -176.825421997765147, -17.40904519070677 ] ] } },
    30	{ "type": "Feature", "properties": { "transect_id": "T025", "vessel": "Taveuni II", "survey_date": "2025-08-19", "crosses_antimeridian_flag": false }, "geometry": { "type": "LineString", "coordinates": [ [ 176.574749815324452, -18.225329195672629 ], [ 176.575711406506713, -17.903825702399828 ], [ 176.576672997688945, -17.572376190438085 ], [ 176.577634588871206, -17.245872893430239 ] ] } },
    31	{ "type": "Feature", "properties": { "transect_id": "T026", "vessel": "Cakaulevu", "survey_date": "2025-08-19", "crosses_antimeridian_flag": false }, "geometry": { "type": "LineString", "coordinates": [ [ 178.630248956242411, -17.547785158041279 ], [ 178.44215451378426, -17.570057172060459 ], [ 178.254060071326109, -17.598148620651486 ], [ 178.065965628867986, -17.611819625668215 ], [ 177.877871186409834, -17.645164465599024 ], [ 177.689776743951683, -17.659546383089758 ] ] } },
    32	{ "type": "Feature", "properties": { "transect_id": "T027", "vessel": "Vanua I", "survey_date": "2025-08-12", "crosses_antimeridian_flag": false }, "geometry": { "type": "LineString", "coordinates": [ [ -177.773526218774975, -17.183972526301677 ], [ -177.993798674497214, -17.290101550005915 ], [ -178.214071130219452, -17.383420029016879 ], [ -178.434343585941718, -17.487055860389813 ], [ -178.654616041663957, -17.584325384194859 ], [ -178.874888497386195, -17.694189986558115 ] ] } },
    33	{ "type": "Feature", "properties": { "transect_id": "T028", "vessel": "Vanua I", "survey_date": "2025-08-12", "crosses_antimeridian_flag": false }, "geometry": { "type": "LineString", "coordinates": [ [ -178.154921880223981, -16.519500569812283 ], [ -177.760867938660567, -16.61473611015824 ], [ -177.366813997097154, -16.706948361526067 ], [ -176.972760055533769, -16.779276042892469 ], [ -176.578706113970355, -16.874986722588798 ] ] } },
    34	{ "type": "Feature", "properties": { "transect_id": "T029", "vessel": "Lomaiviti", "survey_date": "2025-08-19", "crosses_antimeridian_flag": false }, "geometry": { "type": "LineString", "coordinates": [ [ -176.563841265411412, -18.091246216590591 ], [ -176.943316553982299, -17.796168551154441 ], [ -177.322791842553215, -17.510273970538908 ], [ -177.702267131124103, -17.231705179840109 ], [ -178.08174241969499, -16.949176694851047 ] ] } },
    35	{ "type": "Feature", "properties": { "transect_id": "T030", "vessel": "Cakaulevu", "survey_date": "2025-08-19", "crosses_antimeridian_flag": false }, "geometry": { "type": "LineString", "coordinates": [ [ -177.772700226865993, -16.898671712097919 ], [ -177.981739053528088, -17.042373280579991 ], [ -178.190777880190183, -17.175821795383495 ], [ -178.399816706852278, -17.32978967298839 ], [ -178.608855533514344, -17.474383681681747 ], [ -178.817894360176439, -17.613581860280195 ], [ -179.026933186838534, -17.755873350663471 ] ] } }
    36	]
    37	}
0:30
Let me analyze the problem.

The features with `crosses_antimeridian_flag: true` have coordinates that cross the antimeridian (180° longitude). For example, T001 has coordinates like:
- 178.941..., 179.456..., 179.971..., -179.513..., -178.999..., -178.484...

The issue is that when rendering software plots these, it sees a jump from 179.971 to -179.513, which goes the "long way" around the globe (across -180 to +180 is a gap of ~359 degrees, but the actual path should be a short segment across the date line).

I need to:
1. For features crossing the antimeridian, split the linestring at the antimeridian, creating multi-part geometries
2. Add 360 to the negative longitude values on the "east" side of the antimeridian, or subtract 360 from positive values on the "west" side
3. Then project to Fiji's national metric grid system
4. Calculate length in metres
5. Output as MultiLineString GeoJSON

Fiji's national metric grid... Let me think about this. Fiji uses a projection suitable for the Fiji region. The common one would be something like:
- EPSG:3460 - Fiji 1956 / Fiji Map Grid
- EPSG:3141 - maybe something else
- Actually, Fiji Map Grid is EPSG:3460 (Fiji 1956 / Fiji Map Grid) or EPSG:3139 (Fiji 1956 / UTM zone 60S)
- But there's also EPSG:2120 (Fiji 1986 / UTM zone 60S)
- Actually, the most common "Fiji's national metric grid" is likely "Fiji Map Grid" which is EPSG:3460 (Fiji 1956 / Fiji Map Grid) or EPSG:3138 / 3139 (Fiji 1956 / UTM zones 59S and 60S)
- Wait, let me check. Fiji Map Grid is EPSG:3460 (Fiji 1956 / Fiji Map Grid). That's a single grid covering all of Fiji.

Actually, let me check what projections are available. But first, let me think about the approach.

The key insight is:
- For features that cross the antimeridian, the coordinates go from positive longitudes (east of 180°) to negative longitudes (west of 180°)
- A naive rendering connects the last point east of the dateline (e.g., 179.97) to the first point west of the dateline (e.g., -179.51) going the long way around
- The fix: when points cross 180°, we can normalize coordinates so they're continuous

One approach:
1. For each feature, check if it crosses the antimeridian
2. If it does, split the LineString at the antimeridian into segments
3. For coordinates on the "west" side (negative longitudes), add 360 to them to make them continuous
4. Then after projecting, the segments will be separate parts of a MultiLineString

Let me think about this more carefully.

For T001, the coordinates in longitude order are:
178.94, 179.46, 179.97, -179.51, -179.00, -178.48

So the path goes eastward from ~179°E across the date line to ~179°W (which is 181°E in continuous coordinates), then continues westward to ~178°W (182°E).

If we add 360 to the negative longitudes:
178.94, 179.46, 179.97, 180.49, 181.00, 181.52

But that creates one continuous line. However, the problem is about rendering - we need to split it into segments that don't cross the antimeridian.

Actually, the best approach is:

For features crossing the antimeridian, I should:
1. Identify where the longitude jumps across the antimeridian (from ~179/+ to ~-179/- or vice versa)
2. Split at those points
3. For the segments on each side, keep original coordinates
4. Create a MultiLineString with parts on each side of the antimeridian

Then to calculate length in metres, project each part to a suitable CRS and calculate.

Let me write a Python script.

First, let me check what CRS to use for Fiji's national metric grid.

I'll use pyproj to look up available CRS for Fiji.
0:30
0:30
Bash python3 -c "
python3 -c "
from pyproj import CRS
# Fiji Map Grid
crs = CRS.from_epsg(3460)
print(crs)
print('---')
# Also check EPSG:3139
crs2 = CRS.from_epsg(3139)
print(crs2)
print('---')
crs3 = CRS.from_epsg(2120)
print(crs3)
"
EPSG:3460
---
EPSG:3139
---
EPSG:2120
0:37
Let me check Fiji Map Grid - EPSG:3460 is "Fiji 1956 / Fiji Map Grid" which seems like the right one. But let me also check EPSG:2138 - "Fiji 1956 / UTM zone 60S" or "Fiji 1956 / UTM zone 1S". Actually, the Fiji Map Grid is EPSG:3460 (Fiji 1956 / Fiji Map Grid). Let me verify.

Actually, Fiji's national metric grid is likely "Fiji 1956 / Fiji Map Grid" (EPSG:3460) or "Fiji 1986 / Fiji Map Grid" (EPSG:3139). Let me check more.

Wait, the user said "Fiji's national metric grid". The most standard one is EPSG:3460 (Fiji 1956 / Fiji Map Grid). But common modern one is EPSG:3139 (Fiji 1986 / Fiji Map Grid).

Let me check what's available and commonly used.
0:37
Bash python3 -c "
python3 -c "
from pyproj import CRS
# Check details
for e in [3460, 3139, 2120, 2138, 2139]:
    c = CRS.from_epsg(e)
    print(f'EPSG:{e} - {c.name}')
"
EPSG:3460 - Fiji 1986 / Fiji Map Grid
EPSG:3139 - Vanua Levu 1915 / Vanua Levu Grid
EPSG:2120 - NZGD2000 / Marlborough 2000
EPSG:2138 - NAD27(CGQ77) / Quebec Lambert
EPSG:2139 - NAD83(CSRS98) / SCoPQ zone 2
1:16
EPSG:3460 is "Fiji 1986 / Fiji Map Grid" - that's Fiji's national metric grid. Let me write the solution.

Now, the issue with the geometries: transects that cross the antimeridian (the 180° longitude line) have coordinates that go from positive (e.g. 179.9°) to negative (e.g. -179.8°). In a naive rendering, these would connect across the entire globe instead of going the short way across the dateline.

The solution: I need to split these antimeridian-crossing lines at the dateline (180° longitude). For each segment that crosses from one side to the other, I need to split it and create separate parts on each side.

Let me think about the approach:

1. For each feature, check if it crosses the antimeridian (or use the flag)
2. If it does, split the line at the antimeridian (180° longitude)
3. Then reproject to Fiji Map Grid (EPSG:3460)
4. Calculate length
5. Output as MultiLineString

Actually, a simpler approach:
- Shift longitudes that are near the antimeridian: for segments crossing the dateline, I can add/subtract 360 to make them continuous, then split.

Let me think more carefully. The problem is coordinates like [179.9, ...] followed by [-179.9, ...]. If I add 360 to the negative values, I get continuous longitudes. Then I need to split at the 180° meridian.

Actually, the standard approach for antimeridian crossing:
1. For each pair of consecutive points, check if they cross the antimeridian (i.e., one has lon near +180 and other near -180, with a large gap)
2. If so, interpolate the crossing point at lon=180
3. Split the linestring into two parts: one on each side
4. Shift the eastern side's longitudes by -360 to get them back to normal, or shift the western side's by +360

Wait, a better approach: 
- For each linestring, iterate through coordinates. 
- If a segment crosses the antimeridian (lon diff > 180 in absolute value), compute intersection with the 180° meridian.
- Create two separate linestrings: one for the eastern side (longitudes > 0, but for the crossing part, up to 180) and one for the western side (longitudes < 0, from -180 onward).

Let me think about the algorithm more carefully.

For a line crossing from east to west (e.g., 179.9 -> -179.9):
1. The crossing point at 180° longitude can be interpolated.
2. Part 1: from start to the crossing point (east side)
3. Part 2: from crossing point to end (west side)

But I also need to handle the case where the line goes from west to east (e.g., -179.9 -> 179.9), though in the data I see the antimeridian-crossing ones go east->west.

Let me write a comprehensive solution.

Actually, let me use the `shapely.ops.transform` and `shapely.ops.split` approach, or use a technique with `shapely.set_precision` or manual splitting.

Let me write a Python script:

```python
import json
import geopandas as gpd
import shapely.geometry as geom
from shapely.ops import transform
from pyproj import CRS, Transformer
from math import isclose

# Read input
with open('/work/fiji_transects_wgs84.geojson') as f:
    data = json.load(f)

# Fiji Map Grid
fmg_crs = CRS.from_epsg(3460)
wgs84_crs = CRS.from_epsg(4326)
transformer = Transformer.from_crs(wgs84_crs, fmg_crs, always_xy=True)

def normalize_lon(lon):
    """Normalize to -180..180"""
    return ((lon + 180) % 360) - 180

def split_at_antimeridian(coords):
    """
    Split a list of coordinates into parts that don't cross the antimeridian.
    Returns list of lists of coordinates.
    """
    parts = []
    current_part = [coords[0]]
    
    for i in range(1, len(coords)):
        prev_lon, prev_lat = coords[i-1]
        cur_lon, cur_lat = coords[i]
        
        # Check if the segment crosses the antimeridian
        # (the difference in longitude is > 180 degrees in absolute value)
        lon_diff = abs(cur_lon - prev_lon)
        if lon_diff > 180:
            # It crosses. Find the intersection point at lon=180
            # Using linear interpolation
            # If prev_lon < cur_lon, we're going west->east (crossing -180), else east->west (crossing 180)
            
            # Determine which direction we're crossing
            if prev_lon < 0 and cur_lon > 0:  # crossing from west to east (across -180)
                # Actually if prev_lon is like -179.9 and cur_lon is 179.9, 
                # the crossing is at lon=180 (or lon=-180, same point)
                # The segment goes from prev_lon to (cur_lon - 360) 
                adj_cur_lon = cur_lon - 360
                # Find t where lon = 180 (but we're going from prev_lon < 0 to adj_cur_lon which is < 0 too... hmm)
                # Actually, going from -179.9 to 179.9: the shortest path goes through lon=180
                # prev_lon = -179.9, cur_lon = 179.9
                # adj_cur_lon = -180.1
                # The line goes from -179.9 to -180.1 crossing lon=180... wait that doesn't work either.
                
                # Let's think differently. We're at prev_lon (e.g. -179.9) and want to go to cur_lon (179.9).
                # The shortest path goes through lon=180 (going eastward from -179.9 to 180, then to 179.9).
                # The crossing point at lon=180: we need to interpolate.
                
                # Going eastward: prev_lon to +180, then wrap to -180 and go to cur_lon.
                # Actually cur_lon = 179.9, which is closer to 180 through the positive side.
                # So the path is: prev_lon (-179.9) -> 180 -> 179.9
                # The crossing point is at lon=180.
                
                pass
            elif prev_lon > 0 and cur_lon < 0:  # crossing from east to west (across 180)
                # e.g. prev_lon=179.9, cur_lon=-179.9
                # Going eastward: 179.9 -> 180 -> -179.9... no, eastward from 179.9 goes to 180, then -180, then -179.9
                # Actually the shortest path from 179.9 to -179.9 goes through lon=180/-180.
                pass
            
            # Let me use a simpler approach
            # The crossing is at lon=180 (or lon=-180, same meridian)
            # Interpolate the latitude at lon=180
            
            # We need to handle two directions:
            # Case 1: prev_lon is positive (~179.x), cur_lon is negative (~-179.x) - crossing 180 going east to west
            # Case 2: prev_lon is negative (~-179.x), cur_lon is positive (~179.x) - crossing 180 going west to east
            
            # For Case 1: prev_lon -> +180, then -180 -> cur_lon
            # For Case 2: prev_lon -> -180, then +180 -> cur_lon (or equivalently prev_lon -> +180, then -180 -> cur_lon)
            
            # Actually the meridian is the same whether we call it 180 or -180.
            
            # Let me adjust one of the longitudes by +/- 360 to make the segment not wrap
            if prev_lon > 0 and cur_lon < 0:
                # Going east to west: adjust cur_lon by +360
                adj_cur_lon = cur_lon + 360  # e.g., -179.9 + 360 = 180.1
                # Now segment goes from prev_lon (~179.9) to adj_cur_lon (~180.1)
                # Crossing at lon=180
                t = (180 - prev_lon) / (adj_cur_lon - prev_lon)
                crossing_lat = prev_lat + t * (cur_lat - prev_lat)
                
                # Part 1: from start to crossing (east side, lon around 180)
                # Part 2: from crossing to end (west side, lon around -180)
                pass
            elif prev_lon < 0 and cur_lon > 0:
                # Going west to east: adjust cur_lon by -360
                adj_cur_lon = cur_lon - 360  # e.g., 179.9 - 360 = -180.1
                # Now segment goes from prev_lon (~-179.9) to adj_cur_lon (~-180.1)
                # Crossing at lon=-180 (same as 180)
                t = (-180 - prev_lon) / (adj_cur_lon - prev_lon)
                crossing_lat = prev_lat + t * (cur_lat - prev_lat)
                
                # Part 1: from start to crossing (west side, lon around -180)
                # Part 2: from crossing to end (east side, lon around 180)
                pass
                
            # Finish current part with crossing point
            crossing_point = (180 if prev_lon > 0 else -180, crossing_lat)
            
            # Actually this is getting complicated. Let me use a different approach.
```

OK, let me think of a cleaner algorithm.

Actually, the simplest approach I know of for handling antimeridian crossing:

1. Start with the line's coordinates.
2. For each consecutive pair, check if the longitudinal gap is > 180 degrees (in absolute value).
3. If so, we need to split. Compute the intersection with the 180° meridian.

Let me think about it more systematically with a concrete example:

T001 coordinates (in order):
[178.94, -17.63], [179.46, -17.62], [179.97, -17.61], [-179.51, -17.60], [-179.00, -17.58], [-178.48, -17.58]

So the transition from [179.97, -17.61] to [-179.51, -17.60] crosses the antimeridian.

Going from 179.97 to -179.51: the shortest path is through 180, going eastward.
- Starting at ~180° (179.97), go to 180°, then wrap to -180°, then to -179.51.
- So the crossing point is at (180, -17.605...).

For the split:
- Part 1: [178.94, -17.63], [179.46, -17.62], [179.97, -17.61], (180, crossing_lat)
- Part 2: (-180, crossing_lat), [-179.51, -17.60], [-179.00, -17.58], [-178.48, -17.58]

But wait, Part 2 starts at -180 which is the same as 180. And the coordinate [-179.51, -17.60] is correct on the west side.

Then when reprojecting to Fiji Map Grid (EPSG:3460), both parts should be fine.

Let me write the code more carefully.

```python
import json
import geopandas as gpd
import numpy as np
from shapely.geometry import LineString, MultiLineString, Point
from shapely.ops import transform
from pyproj import CRS, Transformer
import math

def split_line_at_antimeridian(line_coords):
    """Split a LineString's coordinates at the antimeridian (180°/-180° longitude).
    Returns a list of coordinate lists, one for each part."""
    
    parts = []
    current_part = [list(line_coords[0])]
    
    for i in range(1, len(line_coords)):
        prev = line_coords[i-1]
        cur = line_coords[i]
        
        # Check if segment crosses antimeridian (longitude gap > 180 degrees)
        if abs(cur[0] - prev[0]) > 180:
            # Determine direction
            if prev[0] > 0 and cur[0] < 0:
                # East to west: segment crosses 180° going east-to-west
                # Adjusted cur longitude for interpolation
                adj_cur = (cur[0] + 360, cur[1])
                # Interpolate where lon=180
                t = (180 - prev[0]) / (adj_cur[0] - prev[0])
                crossing_lat = prev[1] + t * (cur[1] - prev[1])
                
                # End current part at crossing point (180° side)
                current_part.append([180, crossing_lat])
                parts.append(current_part)
                
                # Start new part at crossing point (-180° side)
                current_part = [[-180, crossing_lat], list(cur)]
            else:
                # West to east: segment crosses -180° (180°) going west-to-east
                adj_cur = (cur[0] - 360, cur[1])
                t = (-180 - prev[0]) / (adj_cur[0] - prev[0])
                crossing_lat = prev[1] + t * (cur[1] - prev[1])
                
                # End current part at crossing point (-180° side)
                current_part.append([-180, crossing_lat])
                parts.append(current_part)
                
                # Start new part at crossing point (180° side)
                current_part = [[180, crossing_lat], list(cur)]
        else:
            current_part.append(list(cur))
    
    parts.append(current_part)
    return parts
```

This should work! Let me also handle cases where lines extend further east past 180 or west past -180, but for the Fiji data, the coordinates should be in the -180..180 range already.

Actually wait - I need to check the T004 transect. Its coordinates go:
[178.87, -17.80], [179.54, -17.60], [-179.79, -17.41], [-179.12, -17.19], [-178.45, -16.99], [-177.78, -16.80]

So it crosses the antimeridian between [179.54, -17.60] and [-179.79, -17.41]. Going east-to-west.

Let me write the full script now.

For the Fiji Map Grid, I'll use EPSG:3460.

Let me also think about whether I need to handle the case where after splitting, the parts need to be valid geojson with coordinates in the -180..180 range. Yes, the parts I produce have coordinates in the correct range.

After reprojection to FMG, I'll create a MultiLineString if there's more than one part, or a LineString if there's only one (but the instructions say to output MultiLineString for all features).

Actually the instructions say: "Every feature must come out as a MultiLineString, so do not leave any transects as plain LineString". So I'll wrap everything in MultiLineString.

Let me write the script.
1:16
1:16
Write /work/solve.py
content · 139 lines · py
import json
from shapely.geometry import LineString, MultiLineString, shape
from shapely.ops import transform
from pyproj import CRS, Transformer
import math

# ------------------------------------------------------------
# 1. Read input
# ------------------------------------------------------------
with open('/work/fiji_transects_wgs84.geojson') as f:
    raw = json.load(f)

features = raw["features"]

# ------------------------------------------------------------
# 2. CRS set-up
# ------------------------------------------------------------
wgs84 = CRS.from_epsg(4326)
fmg   = CRS.from_epsg(3460)          # Fiji Map Grid (metres)
tfm   = Transformer.from_crs(wgs84, fmg, always_xy=True).transform

# ------------------------------------------------------------
# 3. Helper: split a coordinate list at the antimeridian (180°)
#    Returns list of coordinate-lists, one per part.
# ------------------------------------------------------------
def split_at_antimeridian(coords):
    """
    coords : list of [lon, lat] pairs (in -180..180).
    Returns list of lists-of-pairs, each part not crossing the antimeridian.
    """
    parts = []
    current = [list(coords[0])]

    for i in range(1, len(coords)):
        prev = coords[i - 1]
        cur  = coords[i]

        lon_diff = abs(cur[0] - prev[0])

        if lon_diff > 180.0:
            # ----- segment crosses the antimeridian -----
            if prev[0] > 0 and cur[0] < 0:
                # East → West: crossing the 180° meridian
                # Adjust cur longitude by +360 so segment is continuous
                adj_cur = (cur[0] + 360.0, cur[1])
                # Interpolate where lon = 180
                t = (180.0 - prev[0]) / (adj_cur[0] - prev[0])
                xing_lat = prev[1] + t * (cur[1] - prev[1])

                # close current part on the +180 side
                current.append([180.0, xing_lat])
                parts.append(current)

                # start new part on the -180 side
                current = [[-180.0, xing_lat], list(cur)]

            elif prev[0] < 0 and cur[0] > 0:
                # West → East: crossing the -180° meridian
                adj_cur = (cur[0] - 360.0, cur[1])
                t = (-180.0 - prev[0]) / (adj_cur[0] - prev[0])
                xing_lat = prev[1] + t * (cur[1] - prev[1])

                current.append([-180.0, xing_lat])
                parts.append(current)

                current = [[180.0, xing_lat], list(cur)]
            else:
                # Shouldn't happen for normal Fiji data, but be safe
                current.append(list(cur))
        else:
            # No crossing – just continue
            current.append(list(cur))

    parts.append(current)
    return parts


# ------------------------------------------------------------
# 4. Process every feature
# ------------------------------------------------------------
out_features = []

for feat in features:
    props = feat["properties"]
    geom  = shape(feat["geometry"])

    coords = list(geom.coords)

    # Split at antimeridian if needed
    parts_coords = split_at_antimeridian(coords)

    # Build individual LineStrings
    line_strings = []
    for pts in parts_coords:
        ls = LineString(pts)
        # Reproject to FMG
        ls_fmg = transform(tfm, ls)
        line_strings.append(ls_fmg)

    # Combine into MultiLineString
    mls = MultiLineString(line_strings)

    # Calculate total length (metres) – sum of part lengths
    length_m = sum(ls.length for ls in line_strings)

    out_feat = {
        "type": "Feature",
        "properties": {
            "transect_id":  props["transect_id"],
            "vessel":       props["vessel"],
            "survey_date":  props["survey_date"],
            "length_m":     round(length_m, 2)
        },
        "geometry": {
            "type": "MultiLineString",
            "coordinates": [list(ls.coords) for ls in line_strings]
        }
    }

    out_features.append(out_feat)


# ------------------------------------------------------------
# 5. Write output GeoJSON
# ------------------------------------------------------------
out_collection = {
    "type": "FeatureCollection",
    "name": "fiji_transects_fmg",
    "crs": {
        "type": "name",
        "properties": {"name": "urn:ogc:def:crs:EPSG::3460"}
    },
    "features": out_features
}

with open("/work/fiji_transects_fmg.geojson", "w") as f:
    json.dump(out_collection, f, indent=2)

print(f"Wrote {len(out_features)} features to /work/fiji_transects_fmg.geojson")
Wrote /work/solve.py (4539 chars).
1:19
Let me run it and check the output.
1:19
Bash cd /work && python3 solve.py
Wrote 30 features to /work/fiji_transects_fmg.geojson
1:23
Let me verify the output by reading it and checking some key transects.
1:23
Read /work/fiji_transects_fmg.geojson
     1	{
     2	  "type": "FeatureCollection",
     3	  "name": "fiji_transects_fmg",
     4	  "crs": {
     5	    "type": "name",
     6	    "properties": {
     7	      "name": "urn:ogc:def:crs:EPSG::3460"
     8	    }
     9	  },
    10	  "features": [
    11	    {
    12	      "type": "Feature",
    13	      "properties": {
    14	        "transect_id": "T001",
    15	        "vessel": "Taveuni II",
    16	        "survey_date": "2025-08-15",
    17	        "length_m": 273335.11
    18	      },
    19	      "geometry": {
    20	        "type": "MultiLineString",
    21	        "coordinates": [
    22	          [
    23	            [
    24	              2020343.340583844,
    25	              3930017.4674364463
    26	            ],
    27	            [
    28	              2074969.3287187445,
    29	              3930832.111936373
    30	            ],
    31	            [
    32	              2129608.4030453707,
    33	              3931959.043532026
    34	            ],
    35	            [
    36	              2132641.3519591475,
    37	              3932030.6236885176
    38	            ]
    39	          ],
    40	          [
    41	            [
    42	              2132641.3519591503,
    43	              3932030.6236885176
    44	            ],
    45	            [
    46	              2184265.933617849,
    47	              3933178.8742693216
    48	            ],
    49	            [
    50	              2238946.8792888806,
    51	              3934438.0861816974
    52	            ],
    53	            [
    54	              2293630.6493575512,
    55	              3933970.5213900264
    56	            ]
    57	          ]
    58	        ]
    59	      }
    60	    },
    61	    {
    62	      "type": "Feature",
    63	      "properties": {
    64	        "transect_id": "T002",
    65	        "vessel": "Bligh",
    66	        "survey_date": "2025-08-12",
    67	        "length_m": 216575.29
    68	      },
    69	      "geometry": {
    70	        "type": "MultiLineString",
    71	        "coordinates": [
    72	          [
    73	            [
    74	              2034023.7576998495,
    75	              3962923.9288114174
    76	            ],
    77	            [
    78	              2103801.3645465984,
    79	              3980775.0173757505
    80	            ],
    81	            [
    82	              2133006.7821587846,
    83	              3988176.984284049
    84	            ]
    85	          ],
    86	          [
    87	            [
    88	              2133006.7821587874,
    89	              3988176.984284049
    90	            ],
    91	            [
    92	              2173711.8899896345,
    93	              3998417.276510603
    94	            ],
    95	            [
    96	              2243773.2911946434,
    97	              4016860.265945784
    98	            ]
    99	          ]
   100	        ]
   101	      }
   102	    },
   103	    {
   104	      "type": "Feature",
   105	      "properties": {
   106	        "transect_id": "T003",
   107	        "vessel": "Lomaiviti",
   108	        "survey_date": "2025-08-12",
   109	        "length_m": 351823.46
   110	      },
   111	      "geometry": {
   112	        "type": "MultiLineString",
   113	        "coordinates": [
   114	          [
   115	            [
   116	              1881698.8337329356,
   117	              3959945.940913004
   118	            ],
   119	            [
   120	              1969475.352082875,
   121	              3953932.1918599945
   122	            ],
   123	            [
   124	              2057192.4957280513,
   125	              3947717.5506673623
   126	            ],
   127	            [
   128	              2132707.1824515397,
   129	              3942028.7593159503
   130	            ]
   131	          ],
   132	          [
   133	            [
   134	              2132707.1824515425,
   135	              3942028.7593159503
   136	            ],
   137	            [
   138	              2144865.828376211,
   139	              3941086.0440104534
   140	            ],
   141	            [
   142	              2232501.11407936,
   143	              3933301.4671774227
   144	            ]
   145	          ]
   146	        ]
   147	      }
   148	    },
   149	    {
   150	      "type": "Feature",
   151	      "properties": {
   152	        "transect_id": "T004",
   153	        "vessel": "Vanua I",
   154	        "survey_date": "2025-08-15",
   155	        "length_m": 372666.09
   156	      },
   157	      "geometry": {
   158	        "type": "MultiLineString",
   159	        "coordinates": [
   160	          [
   161	            [
   162	              2013096.2318831745,
   163	              3911101.2374744187
   164	            ],
   165	            [
   166	              2084064.7331161185,
   167	              3933595.078164197
   168	            ],
   169	            [
   170	              2132746.0370150185,
   171	              3947953.374021069
   172	            ]
   173	          ],
   174	          [
   175	            [
   176	              2132746.037015021,
   177	              3947953.374021069
   178	            ],
   179	            [
   180	              2155191.552825498,
   181	              3954527.977713378
   182	            ],
   183	            [
   184	              2226505.8923469945,
   185	              3977271.8304685825
   186	            ],
   187	            [
   188	              2297989.454556443,
   189	              3998716.763596262
   190	            ],
   191	            [
   192	              2369647.398370236,
   193	              4019426.6353879017
   194	            ]
   195	          ]
   196	        ]
   197	      }
   198	    },
   199	    {
   200	      "type": "Feature",
   201	      "properties": {
   202	        "transect_id": "T005",
   203	        "vessel": "Bligh",
   204	        "survey_date": "2025-08-19",
   205	        "length_m": 362394.57
   206	      },
   207	      "geometry": {
   208	        "type": "MultiLineString",
   209	        "coordinates": [
   210	          [
   211	            [
   212	              1877826.2337985218,
   213	              3897452.1115597077
   214	            ],
   215	            [
   216	              1937585.6830181086,
   217	              3888095.4565095943
   218	            ],
   219	            [
   220	              1997281.7339928765,
   221	              3878356.8414042895
   222	            ],
   223	            [
   224	              2056921.5799520519,
   225	              3869852.4157240363
   226	            ],
   227	            [
   228	              2116501.4382828893,
   229	              3859064.775548195
   230	            ],
   231	            [
   232	              2132132.72367144,
   233	              3856392.831893989
   234	            ]
   235	          ],
   236	          [
   237	            [
   238	              2132132.723671443,
   239	              3856392.831893989
   240	            ],
   241	            [
   242	              2176031.798402194,
   243	              3848816.3934150883
   244	            ],
   245	            [
   246	              2235528.2870951835,
   247	              3839483.53885849
   248	            ]
   249	          ]
   250	        ]
   251	      }
   252	    },
   253	    {
   254	      "type": "Feature",
   255	      "properties": {
   256	        "transect_id": "T006",
   257	        "vessel": "Cakaulevu",
   258	        "survey_date": "2025-08-13",
   259	        "length_m": 393605.56
   260	      },
   261	      "geometry": {
   262	        "type": "MultiLineString",
   263	        "coordinates": [
   264	          [
   265	            [
   266	              1986477.0291858702,
   267	              3847052.749570283
   268	            ],
   269	            [
   270	              2048183.9264241843,
   271	              3868847.9958887855
   272	            ],
   273	            [
   274	              2110030.3122592983,
   275	              3889929.569491461
   276	            ],
   277	            [
   278	              2132414.0483812992,
   279	              3897883.660491682
   280	            ]
   281	          ],
   282	          [
   283	            [
   284	              2132414.048381302,
   285	              3897883.660491682
   286	            ],
   287	            [
   288	              2172028.247827847,
   289	              3911884.2606283487
   290	            ],
   291	            [
   292	              2234167.3185592326,
   293	              3932716.7800173583
   294	            ],
   295	            [
   296	              2296469.7202252313,
   297	              3954296.42636324
   298	            ],
   299	            [
   300	              2358907.291712429,
   301	              3974351.608875371
   302	            ]
   303	          ]
   304	        ]
   305	      }
   306	    },
   307	    {
   308	      "type": "Feature",
   309	      "properties": {
   310	        "transect_id": "T007",
   311	        "vessel": "Vanua I",
   312	        "survey_date": "2025-08-19",
   313	        "length_m": 414594.38
   314	      },
   315	      "geometry": {
   316	        "type": "MultiLineString",
   317	        "coordinates": [
   318	          [
   319	            [
   320	              1911692.438271574,
   321	              3983231.465846738
   322	            ],
   323	            [
   324	              1994362.6345828045,
   325	              3988871.9466625084
   326	            ],
   327	            [
   328	              2077074.393066105,
   329	              3993892.378778944
   330	            ],
   331	            [
   332	              2133065.3654978485,
   333	              3997328.8452844336
   334	            ]
   335	          ],
   336	          [
   337	            [
   338	              2133065.3654978513,
   339	              3997328.8452844336
   340	            ],
   341	            [
   342	              2159841.5664019543,
   343	              3998918.8506064746
   344	            ],
   345	            [
   346	              2242670.474942513,
   347	              4003071.442188108
   348	            ],
   349	            [
   350	              2325581.1283138376,
   351	              4007239.653809817
   352	            ]
   353	          ]
   354	        ]
   355	      }
   356	    },
   357	    {
   358	      "type": "Feature",
   359	      "properties": {
   360	        "transect_id": "T008",
   361	        "vessel": "Taveuni II",
   362	        "survey_date": "2025-08-12",
   363	        "length_m": 146792.55
   364	      },
   365	      "geometry": {
   366	        "type": "MultiLineString",
   367	        "coordinates": [
   368	          [
   369	            [
   370	              2068958.3651469543,
   371	              3896474.8093812363
   372	            ],
   373	            [
   374	              2097941.3062179913,
   375	              3900199.435533137
   376	            ],
   377	            [
   378	              2126942.1228124853,
   379	              3904630.4103711965
   380	            ],
   381	            [
   382	              2132465.642506932,
   383	              3905584.342467365
   384	            ]
   385	          ],
   386	          [
   387	            [
   388	              2132465.6425069347,
   389	              3905584.342467365
   390	            ],
   391	            [
   392	              2155963.4499872266,
   393	              3909624.458919142
   394	            ],
   395	            [
   396	              2184998.036693292,
   397	              3914066.6121028704
   398	            ],
   399	            [
   400	              2214051.662654211,
   401	              3918654.097943046
   402	            ]
   403	          ]
   404	        ]
   405	      }
   406	    },
   407	    {
   408	      "type": "Feature",
   409	      "properties": {
   410	        "transect_id": "T009",
   411	        "vessel": "Vanua I",
   412	        "survey_date": "2025-08-13",
   413	        "length_m": 263388.29
   414	      },
   415	      "geometry": {
   416	        "type": "MultiLineString",
   417	        "coordinates": [
   418	          [
   419	            [
   420	              1927285.4610478787,
   421	              4037732.1943981266
   422	            ],
   423	            [
   424	              1979888.171983514,
   425	              4034317.8200324415
   426	            ],
   427	            [
   428	              2032472.1715915422,
   429	              4030761.5922226436
   430	            ],
   431	            [
   432	              2085042.7925657453,
   433	              4027610.627861323
   434	            ],
   435	            [
   436	              2133238.856866916,
   437	              4024688.3579825987
   438	            ]
   439	          ],
   440	          [
   441	            [
   442	              2133238.856866919,
   443	              4024688.3579825987
   444	            ],
   445	            [
   446	              2137604.3518881057,
   447	              4024418.1879896913
   448	            ],
   449	            [
   450	              2190162.2360857013,
   451	              4021349.754676055
   452	            ]
   453	          ]
   454	        ]
   455	      }
   456	    },
   457	    {
   458	      "type": "Feature",
   459	      "properties": {
   460	        "transect_id": "T010",
   461	        "vessel": "Vanua I",
   462	        "survey_date": "2025-08-15",
   463	        "length_m": 489842.48
   464	      },
   465	      "geometry": {
   466	        "type": "MultiLineString",
   467	        "coordinates": [
   468	          [
   469	            [
   470	              1878020.6287486383,
   471	              3968978.967213469
   472	            ],
   473	            [
   474	              2040133.8855144326,
   475	              3948137.8948760154
   476	            ],
   477	            [
   478	              2132667.393619207,
   479	              3935979.8021080676
   480	            ]
   481	          ],
   482	          [
   483	            [
   484	              2132667.39361921,
   485	              3935979.8021080676
   486	            ],
   487	            [
   488	              2201937.698953716,
   489	              3926588.128825637
   490	            ],
   491	            [
   492	              2363529.5082588177,
   493	              3904005.3603546056
   494	            ]
   495	          ]
   496	        ]
   497	      }
   498	    },
   499	    {
   500	      "type": "Feature",
   501	      "properties": {
   502	        "transect_id": "T011",
   503	        "vessel": "Taveuni II",
   504	        "survey_date": "2025-08-20",
   505	        "length_m": 78492.17
   506	      },
   507	      "geometry": {
   508	        "type": "MultiLineString",
   509	        "coordinates": [
   510	          [
   511	            [
   512	              2465344.860581143,
   513	              3906767.4726070557
   514	            ],
   515	            [
   516	              2452339.7066555577,
   517	              3904904.8687637383
   518	            ],
   519	            [
   520	              2439358.6785597224,
   521	              3903920.698017729
   522	            ],
   523	            [
   524	              2426380.6456198604,
   525	              3902914.5859909956
   526	            ],
   527	            [
   528	              2413382.539078825,
   529	              3900783.353759157
   530	            ],
   531	            [
   532	              2400405.893514905,
   533	              3899474.351449523
   534	            ],
   535	            [
   536	              2387423.5467098975,
   537	              3897686.467113443
   538	            ]
   539	          ]
   540	        ]
   541	      }
   542	    },
   543	    {
   544	      "type": "Feature",
   545	      "properties": {
   546	        "transect_id": "T012",
   547	        "vessel": "Taveuni II",
   548	        "survey_date": "2025-08-20",
   549	        "length_m": 84537.56
   550	      },
   551	      "geometry": {
   552	        "type": "MultiLineString",
   553	        "coordinates": [
   554	          [
   555	            [
   556	              1741748.7332561535,
   557	              3890283.693144509
   558	            ],
   559	            [
   560	              1746692.5945271784,
   561	              3918471.030985262
   562	            ],
   563	            [
   564	              1751658.9788316165,
   565	              3946432.2638834873
   566	            ],
   567	            [
   568	              1756655.23549125,
   569	              3973496.030364219
   570	            ]
   571	          ]
   572	        ]
   573	      }
   574	    },
   575	    {
   576	      "type": "Feature",
   577	      "properties": {
   578	        "transect_id": "T013",
   579	        "vessel": "Bligh",
   580	        "survey_date": "2025-08-19",
   581	        "length_m": 179800.48
   582	      },
   583	      "geometry": {
   584	        "type": "MultiLineString",
   585	        "coordinates": [
   586	          [
   587	            [
   588	              2482137.408760446,
   589	              3917127.8950326387
   590	            ],
   591	            [
   592	              2428688.657510872,
   593	              3889083.6235283166
   594	            ],
   595	            [
   596	              2375443.2052126382,
   597	              3862380.253960575
   598	            ],
   599	            [
   600	              2322350.650514273,
   601	              3834700.4346561665
   602	            ]
   603	          ]
   604	        ]
   605	      }
   606	    },
   607	    {
   608	      "type": "Feature",
   609	      "properties": {
   610	        "transect_id": "T014",
   611	        "vessel": "Lomaiviti",
   612	        "survey_date": "2025-08-13",
   613	        "length_m": 148392.88
   614	      },
   615	      "geometry": {
   616	        "type": "MultiLineString",
   617	        "coordinates": [
   618	          [
   619	            [
   620	              1763975.2418630726,
   621	              4043578.795124353
   622	            ],
   623	            [
   624	              1798590.965242443,
   625	              4030582.772307513
   626	            ],
   627	            [
   628	              1833155.9390679915,
   629	              4017897.3350352263
   630	            ],
   631	            [
   632	              1867693.298104288,
   633	              4002219.6929108296
   634	            ],
   635	            [
   636	              1902160.329611775,
   637	              3989702.4129796983
   638	            ]
   639	          ]
   640	        ]
   641	      }
   642	    },
   643	    {
   644	      "type": "Feature",
   645	      "properties": {
   646	        "transect_id": "T015",
   647	        "vessel": "Vanua I",
   648	        "survey_date": "2025-08-15",
   649	        "length_m": 124738.16
   650	      },
   651	      "geometry": {
   652	        "type": "MultiLineString",
   653	        "coordinates": [
   654	          [
   655	            [
   656	              2423739.783700946,
   657	              4026263.28896241
   658	            ],
   659	            [
   660	              2403163.542824007,
   661	              4022543.302237784
   662	            ],
   663	            [
   664	              2382622.078231965,
   665	              4020081.2554188394
   666	            ],
   667	            [
   668	              2362078.3244465566,
   669	              4016938.6757560875
   670	            ],
   671	            [
   672	              2341534.154948448,
   673	              4013127.314926124
   674	            ],
   675	            [
   676	              2321005.3259064667,
   677	              4009569.4162317035
   678	            ],
   679	            [
   680	              2300505.4150438267,
   681	              4007278.1846613027
   682	            ]
   683	          ]
   684	        ]
   685	      }
   686	    },
   687	    {
   688	      "type": "Feature",
   689	      "properties": {
   690	        "transect_id": "T016",
   691	        "vessel": "Taveuni II",
   692	        "survey_date": "2025-08-15",
   693	        "length_m": 53310.24
   694	      },
   695	      "geometry": {
   696	        "type": "MultiLineString",
   697	        "coordinates": [
   698	          [
   699	            [
   700	              1967763.1376268503,
   701	              3864348.9772176393
   702	            ],
   703	            [
   704	              1981044.9340631447,
   705	              3864774.370362437
   706	            ],
   707	            [
   708	              1994327.5364892795,
   709	              3864095.7190000876
   710	            ],
   711	            [
   712	              2007608.7888293017,
   713	              3862426.337582078
   714	            ],
   715	            [
   716	              2020890.884403137,
   717	              3863623.624927437
   718	            ]
   719	          ]
   720	        ]
   721	      }
   722	    },
   723	    {
   724	      "type": "Feature",
   725	      "properties": {
   726	        "transect_id": "T017",
   727	        "vessel": "Taveuni II",
   728	        "survey_date": "2025-08-12",
   729	        "length_m": 152432.38
   730	      },
   731	      "geometry": {
   732	        "type": "MultiLineString",
   733	        "coordinates": [
   734	          [
   735	            [
   736	              2459196.783273682,
   737	              4040076.8577193925
   738	            ],
   739	            [
   740	              2445503.0422038976,
   741	              4017855.351608406
   742	            ],
   743	            [
   744	              2431865.897774811,
   745	              3997180.8985599047
   746	            ],
   747	            [
   748	              2418220.5069328533,
   749	              3974931.1076368974
   750	            ],
   751	            [
   752	              2404624.705595245,
   753	              3953897.7538502435
   754	            ],
   755	            [
   756	              2391055.945635675,
   757	              3932981.1069712103
   758	            ],
   759	            [
   760	              2377499.6209094804,
   761	              3911400.2397073773
   762	            ]
   763	          ]
   764	        ]
   765	      }
   766	    },
   767	    {
   768	      "type": "Feature",
   769	      "properties": {
   770	        "transect_id": "T018",
   771	        "vessel": "Bligh",
   772	        "survey_date": "2025-08-19",
   773	        "length_m": 112421.62
   774	      },
   775	      "geometry": {
   776	        "type": "MultiLineString",
   777	        "coordinates": [
   778	          [
   779	            [
   780	              1718720.2972681404,
   781	              4014591.143533892
   782	            ],
   783	            [
   784	              1738197.5781078157,
   785	              3994553.0214466406
   786	            ],
   787	            [
   788	              1757642.797153981,
   789	              3974080.649730659
   790	            ],
   791	            [
   792	              1777042.657001174,
   793	              3954256.1167427967
   794	            ],
   795	            [
   796	              1796415.9225681531,
   797	              3933347.3340493958
   798	            ]
   799	          ]
   800	        ]
   801	      }
   802	    },
   803	    {
   804	      "type": "Feature",
   805	      "properties": {
   806	        "transect_id": "T019",
   807	        "vessel": "Lomaiviti",
   808	        "survey_date": "2025-08-12",
   809	        "length_m": 179435.73
   810	      },
   811	      "geometry": {
   812	        "type": "MultiLineString",
   813	        "coordinates": [
   814	          [
   815	            [
   816	              1921232.177273387,
   817	              3921611.4164991337
   818	            ],
   819	            [
   820	              1877615.3144519601,
   821	              3932437.2333025597
   822	            ],
   823	            [
   824	              1833949.291065143,
   825	              3942738.01477121
   826	            ],
   827	            [
   828	              1790234.490579545,
   829	              3952596.93857858
   830	            ],
   831	            [
   832	              1746468.6202754881,
   833	              3962251.7484134217
   834	            ]
   835	          ]
   836	        ]
   837	      }
   838	    },
   839	    {
   840	      "type": "Feature",
   841	      "properties": {
   842	        "transect_id": "T020",
   843	        "vessel": "Taveuni II",
   844	        "survey_date": "2025-08-13",
   845	        "length_m": 215352.23
   846	      },
   847	      "geometry": {
   848	        "type": "MultiLineString",
   849	        "coordinates": [
   850	          [
   851	            [
   852	              1799842.78527887,
   853	              3989614.6337389858
   854	            ],
   855	            [
   856	              1850089.5464570043,
   857	              3969622.1670543184
   858	            ],
   859	            [
   860	              1900223.5116513204,
   861	              3950791.606715858
   862	            ],
   863	            [
   864	              1950261.0912236797,
   865	              3930816.037580312
   866	            ],
   867	            [
   868	              2000196.12611439,
   869	              3910677.6427223445
   870	            ]
   871	          ]
   872	        ]
   873	      }
   874	    },
   875	    {
   876	      "type": "Feature",
   877	      "properties": {
   878	        "transect_id": "T021",
   879	        "vessel": "Vanua I",
   880	        "survey_date": "2025-08-16",
   881	        "length_m": 230219.24
   882	      },
   883	      "geometry": {
   884	        "type": "MultiLineString",
   885	        "coordinates": [
   886	          [
   887	            [
   888	              1734792.6614569672,
   889	              3988023.0114604924
   890	            ],
   891	            [
   892	              1796140.996215118,
   893	              3941226.4356850684
   894	            ],
   895	            [
   896	              1857192.2097571124,
   897	              3895079.338822874
   898	            ],
   899	            [
   900	              1917953.2043430656,
   901	              3848549.896766379
   902	            ]
   903	          ]
   904	        ]
   905	      }
   906	    },
   907	    {
   908	      "type": "Feature",
   909	      "properties": {
   910	        "transect_id": "T022",
   911	        "vessel": "Vanua I",
   912	        "survey_date": "2025-08-15",
   913	        "length_m": 50981.78
   914	      },
   915	      "geometry": {
   916	        "type": "MultiLineString",
   917	        "coordinates": [
   918	          [
   919	            [
   920	              1826735.497725808,
   921	              3908468.0307612177
   922	            ],
   923	            [
   924	              1833530.8357058733,
   925	              3915690.085356508
   926	            ],
   927	            [
   928	              1840325.6909893686,
   929	              3923592.9662667327
   930	            ],
   931	            [
   932	              1847131.1924793813,
   933	              3930812.0080819936
   934	            ],
   935	            [
   936	              1853932.773435727,
   937	              3939251.123958868
   938	            ],
   939	            [
   940	              1860748.965022611,
   941	              3946407.5329954834
   942	            ]
   943	          ]
   944	        ]
   945	      }
   946	    },
   947	    {
   948	      "type": "Feature",
   949	      "properties": {
   950	        "transect_id": "T023",
   951	        "vessel": "Lomaiviti",
   952	        "survey_date": "2025-08-12",
   953	        "length_m": 81980.09
   954	      },
   955	      "geometry": {
   956	        "type": "MultiLineString",
   957	        "coordinates": [
   958	          [
   959	            [
   960	              2430814.5176551496,
   961	              3920116.8471598867
   962	            ],
   963	            [
   964	              2415479.5967341997,
   965	              3913735.5872768546
   966	            ],
   967	            [
   968	              2400171.1034651063,
   969	              3908063.181956481
   970	            ],
   971	            [
   972	              2384901.9803659474,
   973	              3903846.206101202
   974	            ],
   975	            [
   976	              2369582.6457509208,
   977	              3896469.9735108716
   978	            ],
   979	            [
   980	              2354312.0603208095,
   981	              3891057.5105217276
   982	            ]
   983	          ]
   984	        ]
   985	      }
   986	    },
   987	    {
   988	      "type": "Feature",
   989	      "properties": {
   990	        "transect_id": "T024",
   991	        "vessel": "Vanua I",
   992	        "survey_date": "2025-08-12",
   993	        "length_m": 251074.91
   994	      },
   995	      "geometry": {
   996	        "type": "MultiLineString",
   997	        "coordinates": [
   998	          [
   999	            [
  1000	              2228238.4566725227,
  1001	              4015411.736894843
  1002	            ],
  1003	            [
  1004	              2276757.963919763,
  1005	              4002318.5037398003
  1006	            ],
  1007	            [
  1008	              2325229.232446313,
  1009	              3988882.404731997
  1010	            ],
  1011	            [
  1012	              2373665.340709087,
  1013	              3975810.063902585
  1014	            ],
  1015	            [
  1016	              2422085.660914305,
  1017	              3963774.4034233717
  1018	            ],
  1019	            [
  1020	              2470420.227856475,
  1021	              3949290.9864591043
  1022	            ]
  1023	          ]
  1024	        ]
  1025	      }
  1026	    },
  1027	    {
  1028	      "type": "Feature",
  1029	      "properties": {
  1030	        "transect_id": "T025",
  1031	        "vessel": "Taveuni II",
  1032	        "survey_date": "2025-08-19",
  1033	        "length_m": 108459.05
  1034	      },
  1035	      "geometry": {
  1036	        "type": "MultiLineString",
  1037	        "coordinates": [
  1038	          [
  1039	            [
  1040	              1769898.113943761,
  1041	              3863034.971961179
  1042	            ],
  1043	            [
  1044	              1769580.71284751,
  1045	              3898636.037103303
  1046	            ],
  1047	            [
  1048	              1769258.2869353632,
  1049	              3935337.3281767596
  1050	            ],
  1051	            [
  1052	              1768950.0859736353,
  1053	              3971489.878227382
  1054	            ]
  1055	          ]
  1056	        ]
  1057	      }
  1058	    },
  1059	    {
  1060	      "type": "Feature",
  1061	      "properties": {
  1062	        "transect_id": "T026",
  1063	        "vessel": "Cakaulevu",
  1064	        "survey_date": "2025-08-19",
  1065	        "length_m": 100661.48
  1066	      },
  1067	      "geometry": {
  1068	        "type": "MultiLineString",
  1069	        "coordinates": [
  1070	          [
  1071	            [
  1072	              1987271.4052228667,
  1073	              3939376.2990370244
  1074	            ],
  1075	            [
  1076	              1967307.9907347183,
  1077	              3936889.1958410414
  1078	            ],
  1079	            [
  1080	              1947350.861923434,
  1081	              3933738.235256531
  1082	            ],
  1083	            [
  1084	              1927393.682270505,
  1085	              3932163.1557427393
  1086	            ],
  1087	            [
  1088	              1907448.9126200052,
  1089	              3928390.8376744
  1090	            ],
  1091	            [
  1092	              1887498.9116150867,
  1093	              3926697.0667341426
  1094	            ]
  1095	          ]
  1096	        ]
  1097	      }
  1098	    },
  1099	    {
  1100	      "type": "Feature",
  1101	      "properties": {
  1102	        "transect_id": "T027",
  1103	        "vessel": "Vanua I",
  1104	        "survey_date": "2025-08-12",
  1105	        "length_m": 130089.67
  1106	      },
  1107	      "geometry": {
  1108	        "type": "MultiLineString",
  1109	        "coordinates": [
  1110	          [
  1111	            [
  1112	              2369948.7263461673,
  1113	              3976319.9325690367
  1114	            ],
  1115	            [
  1116	              2346287.470686171,
  1117	              3964968.188987548
  1118	            ],
  1119	            [
  1120	              2322678.80831227,
  1121	              3955012.8928886973
  1122	            ],
  1123	            [
  1124	              2299080.230015055,
  1125	              3943891.124994715
  1126	            ],
  1127	            [
  1128	              2275520.6251862263,
  1129	              3933450.761366028
  1130	            ],
  1131	            [
  1132	              2251971.126515633,
  1133	              3921591.3665094175
  1134	            ]
  1135	          ]
  1136	        ]
  1137	      }
  1138	    },
  1139	    {
  1140	      "type": "Feature",
  1141	      "properties": {
  1142	        "transect_id": "T028",
  1143	        "vessel": "Vanua I",
  1144	        "survey_date": "2025-08-12",
  1145	        "length_m": 173047.04
  1146	      },
  1147	      "geometry": {
  1148	        "type": "MultiLineString",
  1149	        "coordinates": [
  1150	          [
  1151	            [
  1152	              2330479.7686202456,
  1153	              4050623.346325348
  1154	            ],
  1155	            [
  1156	              2372415.289708903,
  1157	              4039380.3649832667
  1158	            ],
  1159	            [
  1160	              2414329.386504559,
  1161	              4028381.670683045
  1162	            ],
  1163	            [
  1164	              2456265.7878334904,
  1165	              4019496.345153804
  1166	            ],
  1167	            [
  1168	              2498125.9280114328,
  1169	              4007925.0495241787
  1170	            ]
  1171	          ]
  1172	        ]
  1173	      }
  1174	    },
  1175	    {
  1176	      "type": "Feature",
  1177	      "properties": {
  1178	        "transect_id": "T029",
  1179	        "vessel": "Lomaiviti",
  1180	        "survey_date": "2025-08-19",
  1181	        "length_m": 205262.64
  1182	      },
  1183	      "geometry": {
  1184	        "type": "MultiLineString",
  1185	        "coordinates": [
  1186	          [
  1187	            [
  1188	              2496390.5070293318,
  1189	              3872926.5081186867
  1190	            ],
  1191	            [
  1192	              2456887.5880763554,
  1193	              3906639.2715288056
  1194	            ],
  1195	            [
  1196	              2417234.1074046907,
  1197	              3939224.290901031
  1198	            ],
  1199	            [
  1200	              2377443.041219402,
  1201	              3970892.0161980125
  1202	            ],
  1203	            [
  1204	              2337541.907860386,
  1205	              4002897.035326764
  1206	            ]
  1207	          ]
  1208	        ]
  1209	      }
  1210	    },
  1211	    {
  1212	      "type": "Feature",
  1213	      "properties": {
  1214	        "transect_id": "T030",
  1215	        "vessel": "Cakaulevu",
  1216	        "survey_date": "2025-08-19",
  1217	        "length_m": 163829.39
  1218	      },
  1219	      "geometry": {
  1220	        "type": "MultiLineString",
  1221	        "coordinates": [
  1222	          [
  1223	            [
  1224	              2370599.7528943215,
  1225	              4007936.284838661
  1226	            ],
  1227	            [
  1228	              2348033.804542877,
  1229	              3992395.776298311
  1230	            ],
  1231	            [
  1232	              2325521.730368626,
  1233	              3977972.568507736
  1234	            ],
  1235	            [
  1236	              2303009.840542533,
  1237	              3961256.978484933
  1238	            ],
  1239	            [
  1240	              2280550.736391237,
  1241	              3945560.2422843603
  1242	            ],
  1243	            [
  1244	              2258135.8435976296,
  1245	              3930440.8739923015
  1246	            ],
  1247	            [
  1248	              2235752.355614778,
  1249	              3914958.146484169
  1250	            ]
  1251	          ]
  1252	        ]
  1253	      }
  1254	    }
  1255	  ]
  1256	}
1:54
Let me verify the output looks correct. Let me check a few things:

1. All features are MultiLineString ✓
2. The antimeridian-crossing features (T001-T010) have been split into multiple parts ✓
3. The non-antimeridian features (T011-T030) should ideally also be MultiLineString but might show with a single part - let me check that's the case.

Wait, looking at the output more carefully, I notice something potentially wrong with the antimeridian handling. Let me look at T001:

Original coordinates: [178.94, -17.63], [179.46, -17.62], [179.97, -17.61], [-179.51, -17.60], [-178.99, -17.58], [-178.48, -17.58]

The split happens between [179.97, -17.61] and [-179.51, -17.60]. 

The algorithm:
1. prev=[179.97, -17.61], cur=[-179.51, -17.60]
2. prev[0] > 0 and cur[0] < 0 → East to West crossing
3. adj_cur = (-179.51 + 360, -17.60) = (180.49, -17.60)
4. t = (180 - 179.97) / (180.49 - 179.97) = 0.03 / 0.52 ≈ 0.0577
5. xing_lat = -17.61 + 0.0577 * (-17.60 - (-17.61)) = -17.61 + 0.0577 * 0.01 = -17.6094...

So current part 1 gets [..., [180.0, -17.6094]]
And part 2 gets [[-180.0, -17.6094], [-179.51, -17.60], ...]

Then when reprojecting to FMG:
- For part 1: coords are [178.94, -17.63], [179.46, -17.62], [179.97, -17.61], [180.0, -17.6094] → these are all in the "east" side, should project fine
- For part 2: coords are [-180.0, -17.6094], [-179.51, -17.60], [-178.99, -17.58], [-178.48, -17.58] → these are all in the "west" side, should project fine

Wait, but there's a problem. The reprojection happens using the actual longitude values (-180.0, not 180.0). Let me check what EPSG:3460's area of use is.

Fiji 1986 / Fiji Map Grid covers Fiji islands which span from about 177°E to 179°W. So coordinates like 180° or -180° might be at the edge of the projection or problematic.

Actually, Fiji Map Grid should handle coordinates in the Fiji area fine. The coordinates at 180° and -180° are both at the antimeridian but the projection should handle them. Let me verify by checking the projection bounds.

Actually, looking at the output for T001:
Part 1 coordinates (FM reprojected):
[2020343, 3930017], [2074969, 3930832], [2129608, 3931959], [2132641, 3932030]

Part 2 coordinates (FM reprojected):
[2132641, 3932030], [2184265, 3933178], [2238946, 3934438], [2293630, 3933970]

The two parts meet at [2132641, 3932030] which is consistent - the insertion point matches. Good.

But wait - the issue might be that points at exactly 180.0 or -180.0 might not project correctly with EPSG:3460. Let me verify quickly.

Actually, EPSG:3460 (Fiji 1986 / Fiji Map Grid) has this projection:
- Projection: Transverse Mercator
- Central meridian: 178°E
- False easting: 2,000,000 m
- False northing: 0 m

So a point at lon=180° would be 2° east of the central meridian, which should be fine.

But wait, I think there might be a subtle issue. When we split, we insert [180.0, xing_lat] at the end of part 1 and [-180.0, xing_lat] at the start of part 2. But these are the same geographic point - just expressed differently. When projected to FMG, they should come out as the same coordinates (or very close). Let me check T001 output:

Part 1 last coord: [2132641.3519591475, 3932030.6236885176]
Part 2 first coord: [2132641.3519591503, 3932030.6236885176]

Those are very slightly different (1e-12 difference in x) due to floating point. That's fine.

Now for the non-antimeridian features - they should still be MultiLineString but with a single part. Let me check T011:
Yes, it has a single array of coordinates wrapped in another array. That's correct MultiLineString with one line.

Wait, I need to double check something though. For the features that cross the antimeridian, the split_at_antimeridian function adds an extra vertex at 180°/-180°. But the original features already have vertices crossing the antimeridian. Let me trace through T001 more carefully.

Original T001 coords (lon, lat):
[178.941879580782086, -17.632301816020771]
[179.456655009654696, -17.623768593111961]
[179.971430438527307, -17.611072392823225]
[-179.513794132600054, -17.596198176111951]
[-178.999018703727444, -17.579632069513806]
[-178.484243274854833, -17.577321872344196]

Step 0: i=0, no split, current = [[178.94..., -17.63...]]
Step 1: i=1, prev=[178.94...], cur=[179.46...], lon_diff=0.51 < 180, no split. current = [[178.94..., -17.63...], [179.46..., -17.62...]]
Step 2: i=2, prev=[179.46...], cur=[179.97...], lon_diff=0.51 < 180, no split. current = [[178.94...], [179.46...], [179.97...]]
Step 3: i=3, prev=[179.97...], cur=[-179.51...], lon_diff=359.48 > 180. prev[0] > 0 and cur[0] < 0 → East→West crossing.
  adj_cur = (-179.51 + 360, -17.60) = (180.49, -17.60)
  t = (180 - 179.97) / (180.49 - 179.97) = 0.03/0.52 = 0.0577
  xing_lat = -17.611 + 0.0577 * (-17.596 - (-17.611)) = -17.611 + 0.0577 * 0.015 = -17.6101

  current becomes [[178.94...], [179.46...], [179.97...], [180.0, -17.6101]]
  parts = [current]
  current = [[-180.0, -17.6101], [-179.51..., -17.60...]]

Step 4: i=4, prev=[-179.51...], cur=[-178.99...], lon_diff=0.51 < 180. current = [[-180.0], [-179.51], [-178.99]]
Step 5: i=5, prev=[-178.99...], cur=[-178.48...], lon_diff=0.51 < 180. current = [[-180.0], [-179.51], [-178.99], [-178.48]]

End: parts = [part1, part2]

This looks correct! The antimeridian features are properly split into two parts.

Now let me also check that all features are MultiLineString. Looking at the output, each geometry has type "MultiLineString" with coordinates being an array of arrays. For single-part features (like T011), it's a single array wrapped in an outer array. That's valid GeoJSON MultiLineString.

Everything looks good. The output file is at `/work/fiji_transects_fmg.geojson` as requested.
1:54
1:54
Bash cd /work && python3 -c "
cd /work && python3 -c "
import json

with open('fiji_transects_fmg.geojson') as f:
    data = json.load(f)

print(f'Number of features: {len(data[\"features\"])}')
print(f'CRS: {data[\"crs\"]}')

for feat in data['features']:
    props = feat['properties']
    gtype = feat['geometry']['type']
    n_parts = len(feat['geometry']['coordinates'])
    tid = props['transect_id']
    print(f'{tid}: type={gtype}, parts={n_parts}, length_m={props[\"length_m\"]}, vessel={props[\"vessel\"]}, survey_date={props[\"survey_date\"]}')
"
Number of features: 30
CRS: {'type': 'name', 'properties': {'name': 'urn:ogc:def:crs:EPSG::3460'}}
T001: type=MultiLineString, parts=2, length_m=273335.11, vessel=Taveuni II, survey_date=2025-08-15
T002: type=MultiLineString, parts=2, length_m=216575.29, vessel=Bligh, survey_date=2025-08-12
T003: type=MultiLineString, parts=2, length_m=351823.46, vessel=Lomaiviti, survey_date=2025-08-12
T004: type=MultiLineString, parts=2, length_m=372666.09, vessel=Vanua I, survey_date=2025-08-15
T005: type=MultiLineString, parts=2, length_m=362394.57, vessel=Bligh, survey_date=2025-08-19
T006: type=MultiLineString, parts=2, length_m=393605.56, vessel=Cakaulevu, survey_date=2025-08-13
T007: type=MultiLineString, parts=2, length_m=414594.38, vessel=Vanua I, survey_date=2025-08-19
T008: type=MultiLineString, parts=2, length_m=146792.55, vessel=Taveuni II, survey_date=2025-08-12
T009: type=MultiLineString, parts=2, length_m=263388.29, vessel=Vanua I, survey_date=2025-08-13
T010: type=MultiLineString, parts=2, length_m=489842.48, vessel=Vanua I, survey_date=2025-08-15
T011: type=MultiLineString, parts=1, length_m=78492.17, vessel=Taveuni II, survey_date=2025-08-20
T012: type=MultiLineString, parts=1, length_m=84537.56, vessel=Taveuni II, survey_date=2025-08-20
T013: type=MultiLineString, parts=1, length_m=179800.48, vessel=Bligh, survey_date=2025-08-19
T014: type=MultiLineString, parts=1, length_m=148392.88, vessel=Lomaiviti, survey_date=2025-08-13
T015: type=MultiLineString, parts=1, length_m=124738.16, vessel=Vanua I, survey_date=2025-08-15
T016: type=MultiLineString, parts=1, length_m=53310.24, vessel=Taveuni II, survey_date=2025-08-15
T017: type=MultiLineString, parts=1, length_m=152432.38, vessel=Taveuni II, survey_date=2025-08-12
T018: type=MultiLineString, parts=1, length_m=112421.62, vessel=Bligh, survey_date=2025-08-19
T019: type=MultiLineString, parts=1, length_m=179435.73, vessel=Lomaiviti, survey_date=2025-08-12
T020: type=MultiLineString, parts=1, length_m=215352.23, vessel=Taveuni II, survey_date=2025-08-13
T021: type=MultiLineString, parts=1, length_m=230219.24, vessel=Vanua I, survey_date=2025-08-16
T022: type=MultiLineString, parts=1, length_m=50981.78, vessel=Vanua I, survey_date=2025-08-15
T023: type=MultiLineString, parts=1, length_m=81980.09, vessel=Lomaiviti, survey_date=2025-08-12
T024: type=MultiLineString, parts=1, length_m=251074.91, vessel=Vanua I, survey_date=2025-08-12
T025: type=MultiLineString, parts=1, length_m=108459.05, vessel=Taveuni II, survey_date=2025-08-19
T026: type=MultiLineString, parts=1, length_m=100661.48, vessel=Cakaulevu, survey_date=2025-08-19
T027: type=MultiLineString, parts=1, length_m=130089.67, vessel=Vanua I, survey_date=2025-08-12
T028: type=MultiLineString, parts=1, length_m=173047.04, vessel=Vanua I, survey_date=2025-08-12
T029: type=MultiLineString, parts=1, length_m=205262.64, vessel=Lomaiviti, survey_date=2025-08-19
T030: type=MultiLineString, parts=1, length_m=163829.39, vessel=Cakaulevu, survey_date=2025-08-19
2:01
The results look good. Let me verify that:

1. All 30 features are present
2. All are MultiLineString type
3. The antimeridian-crossing transects (T001-T010) have 2 parts each (split properly)
4. The non-crossing transects (T011-T030) have 1 part each
5. Every feature has transect_id, vessel, survey_date, and length_m
6. The CRS is EPSG:3460 (Fiji Map Grid)

Everything checks out. Let me do one final validation to make sure the GeoJSON is valid.
2:01
Bash cd /work && python3 -c "
cd /work && python3 -c "
import json, sys
with open('fiji_transects_fmg.geojson') as f:
    data = json.load(f)
# Basic GeoJSON conformance checks
assert data['type'] == 'FeatureCollection'
for feat in data['features']:
    assert feat['type'] == 'Feature'
    assert feat['geometry']['type'] == 'MultiLineString'
    assert feat['geometry']['coordinates']
    props = feat['properties']
    for key in ['transect_id', 'vessel', 'survey_date', 'length_m']:
        assert key in props
    # Check coordinates are 3-4 digit precision EPSG:3460 values (metres)
    for part in feat['geometry']['coordinates']:
        for coord in part:
            assert len(coord) == 2
            assert isinstance(coord[0], (int, float))
            assert isinstance(coord[1], (int, float))
print('All validations passed!')
"
All validations passed!
2:15
Everything looks good. Let me summarize what was done:

1. **Problem**: The antimeridian-crossing transects (T001-T010) had coordinates crossing the 180° line, which caused rendering engines to draw arcs spanning the entire globe instead of short local segments.

2. **Solution**: 
   - I wrote a `split_at_antimeridian()` function that detects when a segment crosses the 180° meridian (longitude difference > 180°, or sign change) and splits the line at the antimeridian.
   - When crossing from East to West (e.g., +179° → -179°), it interpolates the crossing point at longitude +180°/-180°, closes the first part, and starts a new part on the other side.
   - Each part becomes a separate LineString within a MultiLineString.
   - All features are converted to MultiLineString (even non-crossing ones become single-part MultiLineString).
   - The geometry is reprojected from WGS84 (EPSG:4326) to Fiji Map Grid (EPSG:3460) in metres.
   - Each feature gets a `length_m` attribute (sum of part lengths in metres).
   - Original `transect_id`, `vessel`, and `survey_date` are preserved.

3. **Results**: 
   - 30 features, all MultiLineString type
   - T001-T010 (antimeridian-crossing) each have 2 parts
   - T011-T030 (non-crossing) each have 1 part
   - Lengths computed in metres
   - CRS set to `urn:ogc:def:crs:EPSG::3460`
2:15