crs-l2-fiji-antimeridian

Status: done
Score: 1.000
Duration: 8:21
Cost: 1.07¢
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 reading the input file to understand its structure 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:49
Let me analyze the problem. Lines that cross the antimeridian (180° longitude) have coordinates like:

For T001:
```
[ [ 178.941..., -17.632... ], [ 179.456..., -17.623... ], [ 179.971..., -17.611... ], [ -179.513..., -17.596... ], ... ]
```

When rendered, these coordinates go from 179.97 to -179.51, which wraps around the entire globe instead of crossing the antimeridian locally. The fix is to shift the longitudes for points on the "wrong side" of the antimeridian by adding or subtracting 360.

For points crossing from east to west across the antimeridian (180°):
- Points with longitudes > 180 (or > 180 in the Eastern hemisphere) should stay as is
- Points that have been represented as negative (west of 180°, e.g., -179.5) should be converted to their equivalent positive value (e.g., 180.5) to show the actual continuous path.

Wait, let me think more carefully. The issue is that when you have coordinates like:
- 179.97 (east of 180°)
- -179.51 (west of 180°, i.e., 180.49°E)

If you just plot these, the line will go from 179.97 to -179.51, which wraps the long way around the globe. The fix is to represent points west of the antimeridian as > 180 (e.g., -179.51 → 180.49), which creates a continuous path across the antimeridian.

Actually, let me think about this differently. The geojson uses WGS84 with longitudes in range [-180, 180]. When a line crosses the antimeridian, we need to "unwrap" the longitudes so they form a continuous path.

For T001:
- 178.94, 179.46, 179.97 (east side)
- -179.51, -179.00, -178.48 (west side, but wrapped to negative)

To make it continuous, we need to add 360 to the west-side coordinates:
- 178.94, 179.46, 179.97 (east side)
- 180.49 (= -179.51+360), 181.00 (= -179.00+360), 181.52 (= -178.48+360)

But wait - these are still in WGS84. The problem is that GeoJSON normally uses -180 to 180 for longitudes. But we're going to project to Fiji's national metric grid anyway, so we just need to make the geometry correct in WGS84 first, then project.

Actually, the standard approach is:
1. For each transect that crosses the antimeridian, detect which coordinates need to be unwrapped
2. Split into segments at the antimeridian
3. Each segment should be a continuous line
4. The result should be a MultiLineString

Let me figure out Fiji's national metric grid. Fiji uses the following projected CRS:
- EPSG:3460 - Fiji 1956 / Fiji Central Meridian 178°E
- Actually, more commonly used is EPSG:3460 or EPSG:3139? Let me check.

Actually, for Fiji, the common national grid is "Fiji 1956 / Fiji Map Grid" (EPSG:3139) or similar. But I think the modern one is EPSG:3460 (Fiji 1956 / Fiji Central Meridian 178°E).

Wait, let me think about what "Fiji's national metric grid" refers to. Fiji has used several:
- Fiji 1956 / Fiji Central (EPSG:3139) - uses central meridian of 178°E
- Also there's EPSG:3460 (Fiji 1956 / Fiji Central Meridian 178°E)

Actually EPSG:3139 (Fiji 1956 / Fiji Central Meridian 178°E) and EPSG:3460 are the same thing? Let me check... no, EPSG:3139 is "Fiji 1956 / Fiji Central Meridian 178°E" and EPSG:3460 is "Fiji 1956 / Fiji Central Meridian 180°E".

Wait, looking at EPSG definitions:
- EPSG:3139: Fiji 1956 / Fiji Central Meridian 178°E
- EPSG:3460: Fiji 1956 / Fiji Central Meridian 180°E? No...

Actually, let me just look it up. The common Fiji metric grid projection parameters:
- Projection: Transverse Mercator
- Central meridian: 178°E (for the main Fiji group)
- Scale factor: 0.9999 (or 1.0?)
- False easting: 0
- False northing: 0
- Datum: Fiji 1956

EPSG:3139 is "Fiji 1956 / Fiji Central Meridian 178°E" with these parameters.

Let me also look at EPSG:3460 - this might be "Fiji 1956 / Fiji Central Meridian 180°E" for the eastern islands.

Actually, I think the simplest approach is to use pyproj.CRS to find the right one. Let me write a script.

Let me plan the Python script:

1. Read the GeoJSON
2. For each feature:
   a. Check if it crosses the antimeridian (the `crosses_antimeridian_flag` property tells us)
   b. If it does, fix the geometry by unwrapping longitudes and splitting into segments
   c. Convert to MultiLineString if it's a LineString
3. Project to Fiji's national metric grid (EPSG:3139 or similar)
4. Calculate length_m for each transect
5. Write as GeoJSON

For the antimeridian crossing fix:
- Find where the longitude jumps across the antimeridian (from near +180 to near -180 or vice versa)
- Split into line segments on each side
- Each segment gets its longitudes adjusted (add 360 to the negative side) so they're continuous
- Return as MultiLineString

Let me write a comprehensive script.

Actually wait, let me reconsider. The points that cross the antimeridian need to be split into multiple line segments. For example, T001 has:
- [ 178.94, -17.63 ], [ 179.46, -17.62 ], [ 179.97, -17.61 ], [ -179.51, -17.60 ], [ -179.00, -17.58 ], [ -178.48, -17.58 ]

The segment crossing the antimeridian is between [179.97, -17.61] and [-179.51, -17.60]. On the east side, the longitude goes up to 179.97, then on the west side it continues at -179.51 (= 180.49).

To fix this, I need to:
1. Find where consecutive coordinates cross the 180° meridian
2. At each crossing, split the line and create separate segments
3. For the western segments, add 360° to longitudes to make them continuous
4. Project to Fiji grid
5. Combine into MultiLineString

Actually, a simpler approach: instead of splitting, I can just "unwrap" the longitudes by adding 360 to the negative values when the line crosses from east to west. But the result would have longitudes > 180 which isn't standard WGS84. However, since we're going to project to a metric grid anyway, it should work fine for the projection step.

Let me think again... Actually, if I just add 360 to the negative values for transects that cross the antimeridian, then project to Fiji grid, that should work. The projection function should handle longitudes > 180 correctly.

Wait, but the instruction says "the problematic ones must end up as multi-part geometries that faithfully represent the actual survey path." So they need to be MultiLineString with separate segments on each side of the antimeridian.

Let me think about this more carefully. A transect that crosses the antimeridian - the actual survey path goes continuously across. So maybe the approach is:

1. For transects crossing the antimeridian, "unwrap" longitudes by adding 360 to negative values
2. Project to Fiji grid
3. But... the resulting geometry would still be a LineString, just with unwrapped coordinates

Hmm, but the user says "the problematic ones must end up as multi-part geometries that faithfully represent the actual survey path." So maybe they want each side of the antimeridian as a separate part of a MultiLineString?

Actually, I think the real problem is rendering. When you have a LineString that goes from +179.97 to -179.51, most GIS software will draw the line across the entire globe (passing through longitude 0). The fix is to split into two segments:
1. Segment on the east side: from 178.94 to 179.97 (normal longitudes)
2. Segment on the west side: from -179.51 to -178.48 (or equivalently, from 180.49 to 181.52)

But these two segments, when rendered in WGS84, would still have the gap issue if we keep them as separate features. However, if we project them first to Fiji grid, they'll connect properly.

Actually, rethinking: Let me unwrap all the coordinates first, then project, then check if the projected geometry is a single continuous line or if it needs to be split.

Let me take the approach:
1. For transects that cross the antimeridian, unwrap longitude by adding 360 to negative values so the path is continuous
2. Project to Fiji grid
3. Calculate length
4. Store as MultiLineString (wrapping single LineStrings in MultiLineString if needed)

For transects that don't cross the antimeridian, just project directly.

Actually, I need to be more careful. Let me look at the data again.

For T001 (crosses antimeridian):
- East side: 178.94, 179.46, 179.97
- West side: -179.51, -179.00, -178.48
If I add 360 to west side: 180.49, 181.00, 181.52

So the unwrapped path is: 178.94, 179.46, 179.97, 180.49, 181.00, 181.52

This will project correctly to Fiji grid and form a continuous line.

But wait, the user says "the problematic ones must end up as multi-part geometries that faithfully represent the actual survey path." So maybe they DO want separate parts?

Let me re-read: "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."

So:
- All features should be MultiLineString (even if they have just one part)
- Problematic ones (crossing antimeridian) should have multiple parts

For the problematic ones, I think the expectation is:
- Part 1: The segment(s) on the east side of 180°
- Part 2: The segment(s) on the west side of 180°

This way, when rendered, each part stays on its own side of the antimeridian and doesn't wrap around the globe.

But how to split? Let me find where the actual crossing occurs and split the line there.

For T001:
Points: [178.94, -17.63], [179.46, -17.62], [179.97, -17.61], [-179.51, -17.60], [-179.00, -17.58], [-178.48, -17.58]

The crossing occurs between point 3 (179.97) and point 4 (-179.51). So:
- Part 1 (east side): [178.94, ...], [179.46, ...], [179.97, ...]
- Part 2 (west side): [-179.51, ...], [-179.00, ...], [-178.48, ...]

For the projection, each part is projected separately from WGS84 to Fiji grid.

Let me now write the script.

Actually, I realize I need to figure out the Fiji grid CRS. Let me look up what's available.

Common Fiji projected CRS options:
- EPSG:3139 - Fiji 1956 / Fiji Central Meridian 178°E (Transverse Mercator, central meridian 178°E)
- EPSG:3460 - This might be something else

Let me just use pyproj to query CRS info.

Actually, I think "Fiji's national metric grid" is likely EPSG:3139 (Fiji 1956 / Fiji Map Grid / Central Meridian 178°E). But let me also check EPSG:3460.

Let me also look at what packages are available and just write the script.

Let me start by exploring what CRS options are available.

For the approach:
1. Read the GeoJSON
2. For each feature:
   - If it's a LineString, wrap in MultiLineString
   - If it crosses the antimeridian, split into segments
3. For each segment of each feature:
   a. If the segment contains negative longitudes and the feature crosses the antimeridian, add 360 to those longitudes
   b. Actually no, let me think about this differently.

OK let me think about this more carefully. The issue is reproduction in a projected coordinate system. 

When we have coordinates like:
- East of 180: 179.97°E
- West of 180: 179.51°W = -179.51° (in lon/lat), which is 180.49°E

If I just project these as-is to a Fiji grid (which has central meridian at 178°E), both coordinates will project correctly:
- 179.97°E → some positive easting
- -179.51° (which is 180.49°E) → some positive easting

But the issue is the line between them. In WGS84, the software might interpret this as going from 179.97 to -179.51 through 0° longitude, which is the long way around.

Actually, I think the simplest fix that addresses the user's concern is:

For antimeridian-crossing transects, split into two LineStrings:
1. Points with longitude < 0 (west of antimeridian): longitudes are in [-180, 0), but they're actually just west of 180°E
2. Points with longitude > 0 (east of antimeridian): longitudes in (0, 180]

But wait, some points might be on both sides. Let me look at T001:
- East side (> 0): 178.94, 179.46, 179.97 
- West side (< 0): -179.51, -179.00, -178.48

So I split at the antimeridian crossing point (between 179.97 and -179.51).

For rendering, each part is within a normal longitude range and won't wrap.

But for projection, the west side points (-179.51, -179.00, -178.48) need to be interpreted correctly. Since we're in a Fiji projection centered near 178°E, these should project to the far east of the grid. Actually, in a Transverse Mercator projection with central meridian at 178°E, longitude -179.51° (= 180.49°E) is only 2.49° from the central meridian, so it should project fine.

But wait, if I pass -179.51 to the projection, will it know that it should be 180.49°E? In pyproj, if I project (-179.51, -17.60) from EPSG:4326 to EPSG:3139, it should handle it correctly because the projection covers the full globe.

Let me just try it.

Let me write the script now.

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

# Read the GeoJSON
gdf = gpd.read_file('/work/fiji_transects_wgs84.geojson')

# Define the CRS
# Fiji 1956 / Fiji Central Meridian 178°E
fiji_crs = CRS.from_epsg(3139)

# Or check what's available
print(CRS.from_epsg(3139))
```

Actually, let me just write a full script and run it.

For fixing antimeridian crossing:
1. For each feature with crosses_antimeridian_flag = True
2. Get the coordinates
3. Find where the longitude jumps from positive to negative (or vice versa) with abs(delta_lon) > 180
4. Split the coordinates into segments at each crossing
5. For the western segments (negative longitudes), add 360 to make them continuous for projection
6. Project each segment to Fiji grid
7. Calculate lengths
8. Combine segments into MultiLineString

For features without antimeridian crossing:
1. Just wrap LineString in MultiLineString
2. Project to Fiji grid
3. Calculate length

Let me write this out.

Actually, let me first check what EPSG codes are available for Fiji.

Let me write a quick exploration script.
0:49
Bash cd /work && python3 -c "
cd /work && python3 -c "
from pyproj import CRS
# Check Fiji-related CRS
for code in [3139, 3460, 3159, 3140, 3141, 3142]:
    try:
        crs = CRS.from_epsg(code)
        print(f'EPSG:{code} -> {crs.name}')
    except:
        print(f'EPSG:{code} -> not available')
"
EPSG:3139 -> Vanua Levu 1915 / Vanua Levu Grid
EPSG:3460 -> Fiji 1986 / Fiji Map Grid
EPSG:3159 -> NAD83(CSRS) / UTM zone 15N
EPSG:3140 -> Viti Levu 1912 / Viti Levu Grid
EPSG:3141 -> Fiji 1956 / UTM zone 60S
EPSG:3142 -> Fiji 1956 / UTM zone 1S
33:51
Let me check the Fiji Map Grid (EPSG:3460) more carefully. This seems like the national metric grid for Fiji.

Let me also understand the problem: the features that "cross the antimeridian" have coordinates that span from positive longitudes (e.g., 179.xx) to negative longitudes (e.g., -179.xx). When rendered naively, a line from 179.9 to -179.9 will go all the way around the globe instead of crossing the 180° meridian locally.

The fix is to adjust the longitudes of points on one side so that they are continuous. For points crossing the antimeridian, we can convert negative longitudes (west of anti-meridian) to their equivalent positive values by adding 360 (so -179.5 becomes 180.5), then the line will be continuous. After projecting, we can optionally break it into segments that properly represent the actual path.

Wait, but the instruction says "the problematic ones must end up as multi-part geometries that faithfully represent the actual survey path." So the idea is:

1. For antimeridian-crossing lines, adjust coordinates so the line correctly crosses the 180° meridian
2. Then project to Fiji Map Grid
3. Split the projected geometry at the antimeridian (or wherever needed) to create a MultiLineString with parts on each side

Actually, let me think again. The issue is that GeoJSON uses longitude -180 to 180. When a line goes from 179 to -179, the renderer draws a line across the entire globe instead of the short segment that crosses the date line.

The approach:
1. For antimeridian-crossing lines: convert negative longitudes (west of 180) to positive values by adding 360, making coordinates continuous
2. Then intersect/split the line at the antimeridian (x=180°) to create a multipart geometry
3. Then shift the eastern part back to negative longitudes for proper GeoJSON representation
4. Project each part to the Fiji Map Grid
5. Calculate lengths

Actually, a simpler approach: 
1. For each feature, determine if it crosses the antimeridian
2. For those that do, adjust longitudes to make them continuous (add 360 to negative longitudes)
3. Now the line goes smoothly across
4. Project to Fiji Map Grid
5. The projected line might span a large x-range, but that's actually correct in the projected CRS
6. Then... we need to make it a MultiLineString

Wait, the problem is about rendering arcs spanning the globe. In WGS84 longitude/latitude, a line from 179 to -179 goes the "long way" around (358 degrees) instead of the short way (2 degrees). 

To fix this, we need to adjust coordinates so they "unwrap" the antimeridian. For a line crossing the dateline going westwards (longitudes going from positive to negative), we add 360 to the negative longitudes. For going eastwards (negative to positive), we subtract 360 from positive ones.

Let me look at the coordinates:

T001: 178.94, 179.46, 179.97, -179.51, -178.99, -178.48
This goes eastwards crossing the dateline. So we need to add 360 to the negative values to make them continuous:
178.94, 179.46, 179.97, 180.49, 181.01, 181.52

Actually wait -179.51 + 360 = 180.49, -178.99 + 360 = 181.01, -178.48 + 360 = 181.52. That makes sense, the line goes from 178.94 to 181.52, crossing the 180° line.

Then after projecting, the line will be in Fiji Map Grid coordinates. The issue is that the projected coordinates might wrap around or have a gap.

Actually, let me think about this differently. The approach in many GIS workflows:

1. "Unwrap" the longitudes across the antimeridian by adding/subtracting 360 where needed
2. Project the unwrapped line to the target CRS
3. If needed, split the projected line where it crossed the antimeridian (the 180° meridian) to create a MultiLineString

But for the Fiji Map Grid (EPSG:3460), which is a projected CRS for Fiji, the antimeridian issue might not be relevant since the projection will handle it naturally once we unwrap the coordinates.

Let me check what EPSG:3460 actually is.

Actually, let me just use a practical approach:

For each feature:
1. If it crosses the antimeridian, shift coordinates so they're continuous (add 360 to negative longitudes)
2. Create a Shapely LineString with the adjusted coordinates
3. Project to EPSG:3460 (Fiji Map Grid)
4. For antimeridian-crossing ones, split the line at the 180° meridian (which after unwrapping is at x=180 in the original CRS, but in the projected CRS it'll be some value). Actually, the split should happen in the original CRS before projection.

Wait, I think the simplest approach is:

1. For lines crossing the antimeridian, "unwrap" them by converting to a continuous coordinate system (add 360 to negative longitudes)
2. In this unwrapped space, split the line at the antimeridian (longitude = 180°)
3. This gives us two LineStrings, one on each side
4. Convert the eastern part back to normal longitude (subtract 360 if > 180)
5. Now we have a proper multi-part geometry in WGS84
6. Project each part to EPSG:3460
7. Compute length

Actually, let me think about this more carefully. The goal is:
- Fix geometries so they render correctly (no global-spanning arcs)
- Convert to Fiji's national metric grid (EPSG:3460 - Fiji 1986 / Fiji Map Grid)
- Each transect as one MultiLineString feature
- Add length_m attribute

Let me write a Python script:

```python
import geopandas as gpd
import shapely
import shapely.ops
from shapely.geometry import LineString, MultiLineString, Point
import json

# Read the GeoJSON
gdf = gpd.read_file('/work/fiji_transects_wgs84.geojson')

# Target CRS
target_crs = 'EPSG:3460'  # Fiji 1986 / Fiji Map Grid

def fix_antimeridian_line(coords):
    """
    Unwrap a line that crosses the antimeridian.
    Returns a list of (wrapped) linestrings that, when combined, form a MultiLineString.
    """
    # First, adjust coordinates to be continuous across the antimeridian
    # by adding 360 to negative longitudes
    adjusted_coords = []
    for lon, lat in coords:
        adjusted_coords.append((lon + 360 if lon < 0 else lon, lat))
    
    # Now find where the line crosses the 180° meridian
    # We'll split at x=180
    line = LineString(adjusted_coords)
    
    # Split at the meridian 180
    meridian = LineString([(180, -90), (180, 90)])
    
    # Use shapely's split
    from shapely.ops import split
    parts = split(line, meridian)
    
    # Now convert back: any x > 180 should have 360 subtracted
    fixed_parts = []
    for part in parts.geoms if hasattr(parts, 'geoms') else [parts]:
        new_coords = []
        for x, y in part.coords:
            if x > 180:
                new_coords.append((x - 360, y))
            else:
                new_coords.append((x, y))
        fixed_parts.append(LineString(new_coords))
    
    return fixed_parts

# Process each feature
results = []
for idx, row in gdf.iterrows():
    geom = row.geometry
    props = {k: v for k, v in row.items() if k != 'geometry'}
    
    coords = list(geom.coords)
    
    # Check if this line crosses the antimeridian
    # A line crosses if adjacent coordinates have opposite signs near 180
    crosses = False
    for i in range(len(coords) - 1):
        lon1, lat1 = coords[i]
        lon2, lat2 = coords[i+1]
        if (lon1 > 170 and lon2 < -170) or (lon1 < -170 and lon2 > 170):
            crosses = True
            break
    
    if crosses:
        parts = fix_antimeridian_line(coords)
        # Create MultiLineString
        multi_line = MultiLineString(parts)
    else:
        # Still make it a MultiLineString but with one part
        multi_line = MultiLineString([geom])
    
    # Now project to target CRS
    from shapely.ops import transform
    import pyproj
    
    wgs84 = pyproj.CRS('EPSG:4326')
    fmg = pyproj.CRS(target_crs)
    project = pyproj.Transformer.from_crs(wgs84, fmg, always_xy=True).transform
    
    projected_geom = transform(project, multi_line)
    
    # Calculate length in metres
    length_m = projected_geom.length
    
    results.append({
        'geometry': projected_geom,
        'properties': {**props, 'length_m': round(length_m, 2)}
    })

# ... build output GeoJSON
```

Wait, but `shapely.ops.split` might not work perfectly. Let me think about this differently.

Actually, a simpler approach: 

For antimeridian-crossing lines:
1. Convert all coordinates to continuous longitudes (add 360 to negative ones)
2. Build the full line
3. Project the full line to Fiji Map Grid
4. The projected line should be continuous and correct
5. Then we don't need to split at all - just use it as a MultiLineString

But the problem says "the problematic ones must end up as multi-part geometries that faithfully represent the actual survey path." So maybe they want explicit multi-part geometries where each part is on one side of the dateline?

Let me re-read: "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."

So non-problematic ones should be MultiLineStrings with a single part. Problematic ones should have multiple parts.

I think the approach is:
1. For antimeridian-crossing lines: split them at the 180° meridian into parts on each side
2. Project each part to Fiji Map Grid
3. Combine into a MultiLineString

Let me write this more carefully.

Actually, I think the simplest way to handle this in Python with Shapely:

```python
def split_line_at_antimeridian(line):
    """
    Split a LineString at the antimeridian (180° longitude).
    Returns a list of LineStrings.
    """
    # Shift negative longitudes to positive (add 360)
    # to make the line continuous
    coords = list(line.coords)
    adjusted = []
    for lon, lat in coords:
        if lon < 0:
            adjusted.append((lon + 360, lat))
        else:
            adjusted.append((lon, lat))
    
    adjusted_line = LineString(adjusted)
    
    # Create a vertical line at the antimeridian (180°)
    meridian = LineString([(180, -90), (180, 90)])
    
    # Split
    from shapely.ops import split
    parts = split(adjusted_line, meridian)
    
    # Convert back to normal coordinates
    result_parts = []
    for part in parts.geoms:
        new_coords = []
        for x, y in part.coords:
            if x > 180:
                new_coords.append((x - 360, y))
            else:
                new_coords.append((x, y))
        result_parts.append(LineString(new_coords))
    
    return result_parts
```

But `shapely.ops.split` might not always work well for this case. Let me try a different approach: manually find the intersection point and split.

Actually, let me just write the script and test it.
33:51
Bash cd /work && python3 -c "
cd /work && python3 -c "
import pyproj
crs = pyproj.CRS.from_epsg(3460)
print(crs.name)
print(crs.area_of_use)
"
Fiji 1986 / Fiji Map Grid
- name: Fiji - onshore. Includes Viti Levu, Vanua Levu, Taveuni, the Yasawa Group, the Kadavu Group, the Lau Islands and Rotuma Islands.
- bounds: (176.81, -20.81, -178.15, -12.42)
34:16
EPSG:3460 (Fiji 1986 / Fiji Map Grid) is the national metric grid for Fiji. Let's use that.

Now, the key problem is that some transects cross the antimeridian (longitude jumps from ~179.9 to -179.9 or similar). In WGS84, coordinates near 180°E/-180°W that cross the antimeridian will render as arcs across the globe on a map.

The fix is:
1. For features that cross the antimeridian, split the LineString at the antimeridian into multiple segments, each staying on the same "side" (east or west of 180°).
2. Convert to Fiji Map Grid (EPSG:3460)
3. Calculate length in metres
4. Output as MultiLineString always

Let me think about the antimeridian crossing issue more carefully.

The coordinates are in WGS84 (EPSG:4326). The antimeridian is at ±180° longitude.

For the crossing transects, the coordinates go from say ~179.9 to -179.9. This means the line literally goes from just east of the dateline to just west of it. But a naive plotting library would draw this as a line going across the entire globe (longitude -179.9 to 179.9 going the "long way" around).

The solution: For each segment that crosses the antimeridian (i.e., consecutive points where longitude jumps from > 179 to < -179 or vice versa), we need to insert a point at the antimeridian (±180°) and split into two parts.

Actually, for proper rendering, we need a different approach. Let me think...

The proper way to handle antimeridian crossing in a projected coordinate system like EPSG:3460 (Fiji Map Grid) is:

1. Shift coordinates that are negative (west of the dateline) by adding 360° to make them continuous, OR
2. Split the LineString at the antimeridian into multiple parts, each in a consistent longitude range.

Since EPSG:3460 has bounds (176.81, -20.81, -178.15, -12.42), it covers from 176.81°E to -178.15°W (i.e., 176.81°E to 181.85°E). So the grid covers longitudes from 176.81°E to about 181.85°E (which is -178.15°W).

For Fiji, the dateline area near 180° is included. Let me think about this differently.

When we have a transect crossing the antimeridian, e.g., T001:
[178.94, -17.63], [179.46, -17.62], [179.97, -17.61], [-179.51, -17.60], [-179.00, -17.58], [-178.48, -17.58]

The coordinates go from 178.94E → 179.46E → 179.97E → -179.51W (which is 180.49E) → -179.00W (181.00E) → -178.48W (181.52E).

In EPSG:3460, the longitude range is (176.81, -178.15) which is (176.81°E to 181.85°E). So negative longitudes in the range -178.15 to 0 are interpreted as 180 + that value (i.e., 180 + (-178.15) = 1.85°E... wait no.

Actually, EPSG:3460 bounds: x=(176.81, -178.15), y=(-20.81, -12.42). The x range goes from 176.81 to -178.15. That's not right in western hemisphere terms. Let me reconsider.

If we look at it, the Fiji Map Grid covers all of Fiji. The projection likely uses a central meridian that's different. Let me check:

EPSG:3460 - Fiji 1986 / Fiji Map Grid - this is a Transverse Mercator projection with central meridian at 177°E (or maybe 178°E?). 

Let me look it up.
34:16
Bash cd /work && python3 -c "
cd /work && python3 -c "
from pyproj import CRS
crs = CRS.from_epsg(3460)
print(crs.to_proj4())
print()
# Check the bounds in native CRS
print('Area of use:', crs.area_of_use)
"
+proj=tmerc +lat_0=-17 +lon_0=178.75 +k=0.99985 +x_0=2000000 +y_0=4000000 +ellps=WGS72 +units=m +no_defs +type=crs

Area of use: - name: Fiji - onshore. Includes Viti Levu, Vanua Levu, Taveuni, the Yasawa Group, the Kadavu Group, the Lau Islands and Rotuma Islands.
- bounds: (176.81, -20.81, -178.15, -12.42)
/usr/local/lib/python3.14/site-packages/pyproj/crs/crs.py:1295: UserWarning: You will likely lose important projection information when converting to a PROJ string from another format. See: https://proj.org/faq.html#what-is-the-best-format-for-describing-coordinate-reference-systems
  proj = self._crs.to_proj4(version=version)
35:02
Now I understand the situation. Let me analyze the data:

1. The features have coordinates in WGS84 (EPSG:4326), some crossing the antimeridian (180° longitude).
2. Fiji Map Grid (EPSG:3460) uses a central meridian of 178.75°E, so it handles the Fiji region well.
3. The "arcs spanning the globe" problem: when geometries cross the antimeridian (e.g., from +179.9° to -179.9°), a naive renderer draws a line going across the whole globe instead of the short local segment. The fix is to "un-cross" or split the geometry at the antimeridian.

Let me think about this more carefully:

Coordinates near Fiji range from about 176°E to 180° and then -180° to about -176° (which is equivalent to 180° to 184°E). When a line goes from, say, 179.97° to -179.96°, it actually crosses the 180° meridian but the naive interpolation goes the long way around.

The proper approach:
1. For antimeridian-crossing transects, I need to adjust the longitudes so they're continuous (e.g., add 360 to negative longitudes), then split at the antimeridian, then convert back if needed.
2. Then project to Fiji Map Grid (EPSG:3460).
3. Calculate length.
4. Output as MultiLineString.

Actually, let me think about the approach more carefully.

The Fiji Map Grid uses central meridian 178.75°E. It's a Transverse Mercator projection. The longitudes in the data range from about 176°E to -176°W (which is 184°E). 

Given that the data spans ~176°E to ~-176°W (184°E), and the central meridian is 178.75°E, all points are within about 5° of the central meridian. So projecting should work fine IF we handle the antimeridian crossing properly.

For the features that cross the antimeridian, the coordinates in the GeoJSON go from positive longitudes (e.g., 179.97°) to negative longitudes (e.g., -179.96°). When projected, these two points should be close to each other, but the intermediate points interpolated in the projection would be wrong.

The solution:
1. For features flagged as `crosses_antimeridian_flag: true`, I need to:
   - Shift the longitude of points with negative longitudes by adding 360 (making them continuous, e.g., -179.96° → 180.04°)
   - This creates a continuous coordinate sequence
   - Then split at the antimeridian (180° longitude) to create separate line segments
   - Each segment's coordinates need to be normalized back to [-180, 180] range for WGS84 before projection
   
Wait, actually let me think about this differently. The projection system can handle coordinates beyond -180/180. So I could:

1. For all points in a feature, normalize longitudes to be continuous: if longitude < 0 and there are also longitudes > 0, add 360 to negative ones.
2. Then find where the line crosses 180°, and split it into segments.
3. Project each segment.

Actually, a simpler approach: 

For each feature that crosses the antimeridian:
1. Convert all longitudes to a continuous range near the central meridian (178.75). So for longitudes < 0, add 360 to them.
2. The coordinates now range from about 176 to 184.
3. Find where the line crosses 180°, split into segments at those crossing points.
4. For each segment, its coordinates are all either < 180 or > 180. For those > 180, subtract 360 to get back to [-180, 180] range for WGS84.
5. Project each segment to EPSG:3460.
6. Combine into a MultiLineString.

Let me implement this.

Actually, I could also handle this more simply using shapely's `normalize` or `split` functionality. Let me think...

A cleaner approach using shapely and pyproj:

1. For each feature, if it crosses the antimeridian:
   - Shift all coordinates to [0, 360] range by adding 360 to negative longitudes
   - Use shapely to split the line at longitude=180
   - For each resulting part, shift the longitudes > 180 back by subtracting 360 (back to [-180, 180])
   - Now project each part and combine into a MultiLineString

Let me code this up.

Actually wait - let me also think about what "the problematic ones must end up as multi-part geometries that faithfully represent the actual survey path" means. For transects that DO cross the antimeridian, they should be split into multiple segments (a MultiLineString). For those that DON'T cross, they might still need to be MultiLineString if they have multiple parts, but the instruction says "Every feature must come out as a MultiLineString", so even simple ones should be MultiLineString with one part.

Let me write a Python script:

```python
import json
import geopandas as gpd
import shapely.geometry as geom
import shapely.ops as ops
from pyproj import Transformer
import numpy as np

# Read the GeoJSON
with open('/work/fiji_transects_wgs84.geojson', 'r') as f:
    data = json.load(f)

# Define the transformer
transformer = Transformer.from_crs("EPSG:4326", "EPSG:3460", always_xy=True)

def antimeridian_split(linestring):
    """
    Split a LineString that crosses the antimeridian into segments.
    Returns a list of LineStrings in WGS84 coordinates (lon in [-180, 180]).
    """
    coords = list(linestring.coords)
    
    # First, make longitudes continuous by shifting negative ones
    shifted = []
    for lon, lat in coords:
        if lon < 0:
            shifted.append((lon + 360, lat))
        else:
            shifted.append((lon, lat))
    
    # Now split at longitude=180
    segments = []
    current_seg = [shifted[0]]
    
    for i in range(1, len(shifted)):
        p1 = shifted[i-1]
        p2 = shifted[i]
        
        # Check if the segment crosses the 180° line
        if (p1[0] <= 180 and p2[0] >= 180) or (p1[0] >= 180 and p2[0] <= 180):
            # Find the intersection point at longitude=180
            # Linear interpolation
            lon1, lat1 = p1
            lon2, lat2 = p2
            
            if lon2 != lon1:
                frac = (180 - lon1) / (lon2 - lon1)
                lat_at_180 = lat1 + frac * (lat2 - lat1)
                intersection = (180, lat_at_180)
                
                # Finish current segment with the intersection point
                current_seg.append(intersection)
                segments.append(current_seg)
                
                # Start new segment with the intersection point
                current_seg = [intersection, p2]
            else:
                current_seg.append(p2)
        else:
            current_seg.append(p2)
    
    if current_seg and len(current_seg) >= 2:
        segments.append(current_seg)
    
    # Now convert each segment back to [-180, 180] range
    result_lines = []
    for seg in segments:
        wgs_coords = []
        for lon, lat in seg:
            if lon > 180:
                wgs_coords.append((lon - 360, lat))
            else:
                wgs_coords.append((lon, lat))
        result_lines.append(geom.LineString(wgs_coords))
    
    return result_lines

# Process each feature
features_out = []
for feature in data['features']:
    props = feature['properties']
    transect_id = props['transect_id']
    geometry = feature['geometry']
    
    line = geom.shape(geometry)
    
    if props.get('crosses_antimeridian_flag', False):
        # Split at antimeridian
        segments = antimeridian_split(line)
    else:
        segments = [line]
    
    # Project each segment to EPSG:3460
    projected_segments = []
    for seg in segments:
        # Project coordinates
        proj_coords = [transformer.transform(lon, lat) for lon, lat in seg.coords]
        projected_segments.append(geom.LineString(proj_coords))
    
    # Create MultiLineString
    multi_line = geom.MultiLineString(projected_segments)
    
    # Calculate length in meters
    length_m = multi_line.length
    
    # Create output feature
    out_feature = {
        "type": "Feature",
        "properties": {
            "transect_id": props['transect_id'],
            "vessel": props['vessel'],
            "survey_date": props['survey_date'],
            "length_m": round(length_m, 2)
        },
        "geometry": geom.mapping(multi_line)
    }
    features_out.append(out_feature)

# Write output
out_data = {
    "type": "FeatureCollection",
    "name": "fiji_transects_fmg",
    "crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:EPSG:3460" } },
    "features": features_out
}

with open('/work/fiji_transects_fmg.geojson', 'w') as f:
    json.dump(out_data, f, indent=2)
```

Wait, there's a subtlety. The antimeridian split function needs to handle the case where a point lands exactly at 180° (which is fine, it's the same in both systems). Let me also think about edge cases more carefully.

Also, for the split at antimeridian, I should be careful about the direction. When crossing from 179 to -179, in shifted coordinates it goes from 179 to 181, crossing 180. Good.

When crossing from -179 to 179, shifted goes from 181 to 179, also crossing 180.

Let me also think: after I split, do I need to handle the case where a segment has only 1 point? I check `len(current_seg) >= 2` so that should be fine. But actually the intersection point will be added, so there should be at least 2 points per segment.

Wait, there's another edge case: what if a coordinate is exactly at 180°? The GeoJSON shows things like -179.999... which is close but not exactly. Let me handle that robustly.

Actually, let me also be more careful. The antimeridian flag tells us which ones cross. Let me look at T001:
- Points: [178.94, -17.63], [179.46, -17.62], [179.97, -17.61], [-179.51, -17.60], [-178.99, -17.58], [-178.48, -17.58]

Shifted: [178.94], [179.46], [179.97], [180.49], [181.01], [181.52]

So the crossing happens between point 3 (179.97) and point 4 (180.49 = -179.51+360). The intersection at 180 would be between these two points.

Then I get segments:
1. From 178.94 through 179.46, 179.97 to 180 (intersection) → shifted back: 178.94 to 179.97, then 180 (which is -180)
2. From 180 (intersection) through 180.49, 181.01, 181.52 → shifted back: -180 through -179.51, -178.99, -178.48

This gives two valid LineStrings.

Let me refine my code a bit and run it.

Actually, I think I should handle the case where coordinates might be exactly at 180° more carefully. But let me just try running it first.

One more thing: for non-antimeridian-crossing features, I still need to output MultiLineString. So:

```python
if not isinstance(multi_line, geom.MultiLineString):
    multi_line = geom.MultiLineString([multi_line])
```

Wait, `geom.MultiLineString(projected_segments)` already returns a MultiLineString. If there's only one segment, it still returns a MultiLineString.

Actually, let me check: `shapely.geometry.MultiLineString([line])` - yes, this creates a MultiLineString with one part.

Let me also check: for T011 and others that are entirely in negative longitudes (west of 180), they don't cross the antimeridian and should project fine.

OK let me write the script.

One more thing about the length calculation: I should use the projected length (which will be in meters since EPSG:3460 uses meters). The `.length` property of a projected geometry will give the length in meters.

Let me write the script now.
35:02
Bash cd /work && python3 << 'PYEOF'
cd /work && python3 << 'PYEOF'
import json
import shapely.geometry as geom
import shapely.ops as ops
from pyproj import Transformer

# Read the GeoJSON
with open('/work/fiji_transects_wgs84.geojson', 'r') as f:
    data = json.load(f)

transformer = Transformer.from_crs("EPSG:4326", "EPSG:3460", always_xy=True)

def split_at_antimeridian(linestring):
    """Split a LineString crossing the antimeridian into multiple WGS84 segments."""
    coords = list(linestring.coords)
    
    # Shift negative longitudes by +360 to make continuous near 180°
    shifted = [(lon + 360 if lon < 0 else lon, lat) for lon, lat in coords]
    
    segments = []       # list of lists of (lon, lat) pairs, in shifted coords
    current = [shifted[0]]
    
    for i in range(1, len(shifted)):
        p1 = shifted[i-1]
        p2 = shifted[i]
        
        # Check if this edge crosses the 180° line
        # (one side <= 180, the other >= 180, and not both on the same side)
        lo, hi = sorted([p1[0], p2[0]])
        if lo < 180 < hi:
            # Linear interpolation to find the intersection at lon=180
            lon1, lat1 = p1
            lon2, lat2 = p2
            frac = (180 - lon1) / (lon2 - lon1)
            lat_at_180 = lat1 + frac * (lat2 - lat1)
            inter = (180.0, lat_at_180)
            
            current.append(inter)
            segments.append(current)
            current = [inter, p2]
        else:
            current.append(p2)
    
    if current and len(current) >= 2:
        segments.append(current)
    
    # Convert segments back to [-180, 180] longitude range
    result = []
    for seg in segments:
        wgs = [(lon - 360, lat) if lon > 180 else (lon, lat) for lon, lat in seg]
        result.append(geom.LineString(wgs))
    return result


features_out = []

for feature in data['features']:
    props = feature['properties']
    line = geom.shape(feature['geometry'])
    
    if props.get('crosses_antimeridian_flag', False):
        wgs_segments = split_at_antimeridian(line)
    else:
        wgs_segments = [line]
    
    # Project each segment to Fiji Map Grid (EPSG:3460)
    proj_segs = []
    for seg in wgs_segments:
        coords_proj = [transformer.transform(lon, lat) for lon, lat in seg.coords]
        proj_segs.append(geom.LineString(coords_proj))
    
    multi = geom.MultiLineString(proj_segs)
    length_m = round(multi.length, 2)
    
    out_feat = {
        "type": "Feature",
        "properties": {
            "transect_id": props["transect_id"],
            "vessel": props["vessel"],
            "survey_date": props["survey_date"],
            "length_m": length_m
        },
        "geometry": geom.mapping(multi)
    }
    features_out.append(out_feat)

out_collection = {
    "type": "FeatureCollection",
    "name": "fiji_transects_fmg",
    "crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:EPSG:3460" } },
    "features": features_out
}

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

print("Done. Wrote", len(features_out), "features.")
PYEOF
Done. Wrote 30 features.
35:08
Let me verify the output to make sure it's correct.
35:08
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.3519591475,
    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.7821587846,
    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.1824515397,
   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.0370150185,
   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.72367144,
   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.0483812992,
   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.3654978485,
   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.642506932,
   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.856866916,
   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.393619207,
   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	}
35:54
Let me verify a few things about the output:

1. All features are MultiLineString - ✓
2. The antimeridian-crossing ones (T001-T010 with crosses_antimeridian_flag=true) have been split into multi-part geometries - ✓
3. Survey attributes (vessel, survey_date) are preserved - ✓
4. transect_id is present - ✓
5. length_m in metres - ✓
6. CRS is EPSG:3460 (Fiji Map Grid) - ✓

Let me also double-check the antimeridian splitting logic more carefully. The issue is that coordinates like `[179.971..., -17.611...]` followed by `[-179.513..., -17.596...]` would render as an arc across the globe. My approach shifts negative longitudes by +360 to make them continuous.

Let me verify with T001:
- Original: [178.94, -17.63], [179.46, -17.62], [179.97, -17.61], [-179.51, -17.60], [-179.00, -17.58], [-178.48, -17.58]
- Shifted: [178.94, -17.63], [179.46, -17.62], [179.97, -17.61], [180.49, -17.60], [181.00, -17.58], [181.52, -17.58]

The crossings:
- Segment 3->4: 179.97 < 180 < 180.49 → crosses. Split at 180.
- Segment 4->5: 180.49 to 181.00, both > 180, no crossing.
- Segment 5->6: 181.00 to 181.52, both > 180, no crossing.

So first seg: [178.94, 179.46, 179.97, 180.0]
Second seg: [180.0, 180.49, 181.00, 181.52]

Convert back: first seg stays as is (all < 180 already), second becomes [180-360=-180, ...] wait...

Actually looking more carefully: the conversion back says `(lon - 360, lat) if lon > 180 else (lon, lat)`. So:
- First seg: [178.94, ...], [179.46,...], [179.97,...], [180.0,...] → all ≤ 180, so stays as is. But we need to check - is 180.0 > 180? No, 180.0 is not > 180. So it stays as (180, lat). But (180, lat) is the antimeridian.

Actually wait, the first seg after split: [178.94, -17.63], [179.46, -17.62], [179.97, -17.61], [180.0, -17.60] - these are all <= 180, so they stay as-is. Good.

Second seg: [180.0, -17.60], [180.49, -17.58], [181.00, -17.58], [181.52, -17.58] → 180.0 stays, 180.49 - 360 = -179.51, 181.00 - 360 = -179.00, 181.52 - 360 = -178.48. So the second seg becomes [180.0, -17.60], [-179.51, -17.58], [-179.00, -17.58], [-178.48, -17.58].

Hmm, 180.0 is still a valid longitude. That should be fine as a split point.

Actually wait, I want to check something. The coordinates in the output for T001 are:
```
[2020343.34, 3930017.47], [2074969.33, 3930832.11], [2129608.40, 3931959.04], [2132641.35, 3932030.62]
```
and
```
[2132641.35, 3932030.62], [2184265.93, 3933178.87], [2238946.88, 3934438.09], [2293630.65, 3933970.52]
```

These look reasonable for Fiji Map Grid coordinates (easting ~2,000,000 to ~2,300,000m, northing ~3,930,000 to ~3,934,000m which is near -17°S in the southern hemisphere).

Let me also verify T011 which doesn't cross the antimeridian - it should be MultiLineString with a single part.

Looking at T011 output:
```
"type": "MultiLineString",
"coordinates": [[[2465344.86, 3906767.47], ..., [2387423.55, 3897686.47]]]
```

Yes, it's a single-part MultiLineString. Good.

Now, I notice something about the output - the antimeridian-crossing transects have the split point at 180° which is fine. But let me verify that the projection of 180° lon to EPSG:3460 makes sense.

The Fiji Map Grid is a Transverse Mercator with central meridian at 178.75°E. So 180° is close to the central meridian. The coordinates at the split point for T001 are [2132641.35, 3932030.62] which is about 132,641m east of the central meridian, and about 3,932,031m north of the equator minus the false northing of 4,000,000... Actually the false northing is 4,000,000 and we're south of the equator (lat -17°), so northing = 4,000,000 - something ≈ 3,930,000 which checks out.

The output looks good! All features are MultiLineString, the antimeridian-crossing ones have been properly split, survey attributes are preserved, and lengths are calculated.

Let me also quickly verify the GeoJSON is valid.
35:54
35:54
Bash cd /work && python3 << 'PYEOF'
cd /work && python3 << 'PYEOF'
import json

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

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

for feat in data['features']:
    props = feat['properties']
    geom = feat['geometry']
    geom_type = geom['type']
    n_parts = len(geom['coordinates'])
    
    print(f"  {props['transect_id']:5s} | {props['vessel']:15s} | {props['survey_date']:12s} | {geom_type:15s} | {n_parts:2d} part(s) | length_m={props['length_m']:>8.2f}")
    
    assert geom_type == 'MultiLineString', f"NOT MultiLineString: {geom_type}"
    
print()
# Check that antimeridian crossers have multiple parts
for feat in data['features']:
    pid = feat['properties']['transect_id']
    n_parts = len(feat['geometry']['coordinates'])
    if pid in ['T001','T002','T003','T004','T005','T006','T007','T008','T009','T010']:
        assert n_parts == 2, f"{pid} should be 2 parts but got {n_parts}"
    else:
        assert n_parts == 1, f"{pid} should be 1 part but got {n_parts}"

print("All assertions passed!")
PYEOF
Type: FeatureCollection
CRS: {'type': 'name', 'properties': {'name': 'urn:ogc:def:crs:EPSG:3460'}}
Number of features: 30

  T001  | Taveuni II      | 2025-08-15   | MultiLineString |  2 part(s) | length_m=273335.11
  T002  | Bligh           | 2025-08-12   | MultiLineString |  2 part(s) | length_m=216575.29
  T003  | Lomaiviti       | 2025-08-12   | MultiLineString |  2 part(s) | length_m=351823.46
  T004  | Vanua I         | 2025-08-15   | MultiLineString |  2 part(s) | length_m=372666.09
  T005  | Bligh           | 2025-08-19   | MultiLineString |  2 part(s) | length_m=362394.57
  T006  | Cakaulevu       | 2025-08-13   | MultiLineString |  2 part(s) | length_m=393605.56
  T007  | Vanua I         | 2025-08-19   | MultiLineString |  2 part(s) | length_m=414594.38
  T008  | Taveuni II      | 2025-08-12   | MultiLineString |  2 part(s) | length_m=146792.55
  T009  | Vanua I         | 2025-08-13   | MultiLineString |  2 part(s) | length_m=263388.29
  T010  | Vanua I         | 2025-08-15   | MultiLineString |  2 part(s) | length_m=489842.48
  T011  | Taveuni II      | 2025-08-20   | MultiLineString |  1 part(s) | length_m=78492.17
  T012  | Taveuni II      | 2025-08-20   | MultiLineString |  1 part(s) | length_m=84537.56
  T013  | Bligh           | 2025-08-19   | MultiLineString |  1 part(s) | length_m=179800.48
  T014  | Lomaiviti       | 2025-08-13   | MultiLineString |  1 part(s) | length_m=148392.88
  T015  | Vanua I         | 2025-08-15   | MultiLineString |  1 part(s) | length_m=124738.16
  T016  | Taveuni II      | 2025-08-15   | MultiLineString |  1 part(s) | length_m=53310.24
  T017  | Taveuni II      | 2025-08-12   | MultiLineString |  1 part(s) | length_m=152432.38
  T018  | Bligh           | 2025-08-19   | MultiLineString |  1 part(s) | length_m=112421.62
  T019  | Lomaiviti       | 2025-08-12   | MultiLineString |  1 part(s) | length_m=179435.73
  T020  | Taveuni II      | 2025-08-13   | MultiLineString |  1 part(s) | length_m=215352.23
  T021  | Vanua I         | 2025-08-16   | MultiLineString |  1 part(s) | length_m=230219.24
  T022  | Vanua I         | 2025-08-15   | MultiLineString |  1 part(s) | length_m=50981.78
  T023  | Lomaiviti       | 2025-08-12   | MultiLineString |  1 part(s) | length_m=81980.09
  T024  | Vanua I         | 2025-08-12   | MultiLineString |  1 part(s) | length_m=251074.91
  T025  | Taveuni II      | 2025-08-19   | MultiLineString |  1 part(s) | length_m=108459.05
  T026  | Cakaulevu       | 2025-08-19   | MultiLineString |  1 part(s) | length_m=100661.48
  T027  | Vanua I         | 2025-08-12   | MultiLineString |  1 part(s) | length_m=130089.67
  T028  | Vanua I         | 2025-08-12   | MultiLineString |  1 part(s) | length_m=173047.04
  T029  | Lomaiviti       | 2025-08-19   | MultiLineString |  1 part(s) | length_m=205262.64
  T030  | Cakaulevu       | 2025-08-19   | MultiLineString |  1 part(s) | length_m=163829.39

All assertions passed!
37:17
Wait, I need to check that the antimeridian-crossing features are properly split. Let me look at T001 more carefully.

T001 coordinates in the original:
[ 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 it goes from 178.94 → 179.46 → 179.97 → -179.51 (crosses 180°!) → -179.00 → -178.48

My antimeridian splitting logic:
- Shifted coords: (178.94, -17.63), (179.46, -17.62), (179.97, -17.61), (180.49, -17.60), (181.00, -17.58), (181.52, -17.58)
  Wait, -179.51 + 360 = 180.49. -179.00 + 360 = 181.00. -178.48 + 360 = 181.52.

So the shifted coords are: (178.94, -17.63), (179.46, -17.62), (179.97, -17.61), (180.49, -17.60), (181.00, -17.58), (181.52, -17.58)

The crossing happens between (179.97, -17.61) and (180.49, -17.60). Since 179.97 < 180 < 180.49, we interpolate at lon=180.

So seg1 = [(178.94, -17.63), (179.46, -17.62), (179.97, -17.61), (180.0, lat_at_180)]
seg2 = [(180.0, lat_at_180), (180.49, -17.60), (181.00, -17.58), (181.52, -17.58)]

Then convert back:
seg1: (178.94, -17.63), (179.46, -17.62), (179.97, -17.61), (180, lat) → (180-360=-180, lat) = (-180, lat)
seg2: (180.49-360=-179.51, -17.60), (181.00-360=-179.00, -17.58), (181.52-360=-178.48, -17.58)

Wait, the interpolation point at lon=180 maps to -180 in WGS84. So both segments share (-180, lat_at_180). That's fine.

Now the projected result for T001 shows:
Part 1: 4 points (2020343, 3930017) → (2074969, 3930832) → (2129608, 3931959) → (2132641, 3932030)
Part 2: 4 points (2132641, 3932030) → (2184265, 3933178) → (2238946, 3934438) → (2293630, 3933970)

Wait, the first part has 4 points and the second part has 4 points (including the shared split point). Let me check...

Original has 6 points. After splitting:
- First segment: 3 original points (178.94, 179.46, 179.97) + interpolated point at 180 = 4 points
- Second segment: interpolated point + 3 remaining original points = 4 points

So 4+4=8 points total. That's correct.

But wait, looking at the output for T001 part 1 coordinates:
(2020343, 3930017) - first point
(2074969, 3930832) - second point
(2129608, 3931959) - third point
(2132641, 3932030) - fourth point (the split point at 180°)

Part 2:
(2132641, 3932030) - the split point
(2184265, 3933178) - next
(2238946, 3934438) - next
(2293630, 3933970) - last

Looks correct!

Now let me verify the non-antimeridian features are also MultiLineString (with 1 part). Looking at the output, all features are MultiLineString. T011-T030 have 1 part each, which is correct since they don't cross the antimeridian.

Wait, but there's a subtle issue. For non-antimeridian features, I just wrap them in a MultiLineString with 1 part. But the user said "Every feature must come out as a MultiLineString, so do not leave any transects as plain LineString" - which is satisfied. And "the problematic ones must end up as multi-part geometries that faithfully represent the actual survey path" - which is also satisfied.

Let me also verify the length calculation. The length is computed in the projected CRS (EPSG:3460, Fiji Map Grid), which uses metres. So `multi.length` should give the length in metres. Good.

Let me also double-check that the `crosses_antimeridian_flag` is used correctly for identifying which ones need splitting. Looking at the input:
- T001-T010: crosses_antimeridian_flag = true
- T011-T030: crosses_antimeridian_flag = false

And in my code, I use `props.get('crosses_antimeridian_flag', False)` to decide whether to split. That's correct.

The output looks good. Let me just verify the GeoJSON is valid by trying to load it with geopandas.
37:17
37:17
Bash cd /work && python3 << 'PYEOF'
cd /work && python3 << 'PYEOF'
import geopandas as gpd

# Read back the output
gdf = gpd.read_file('/work/fiji_transects_fmg.geojson')
print(gdf.head(3))
print(f"\nCRS: {gdf.crs}")
print(f"All geom types: {gdf.geometry.type.unique()}")
print(f"All MultiLineString: {(gdf.geometry.type == 'MultiLineString').all()}")
print(f"\nTotal features: {len(gdf)}")
PYEOF
  transect_id  ...                                           geometry
0        T001  ...  MULTILINESTRING ((2020343.341 3930017.467, 207...
1        T002  ...  MULTILINESTRING ((2034023.758 3962923.929, 210...
2        T003  ...  MULTILINESTRING ((1881698.834 3959945.941, 196...

[3 rows x 5 columns]

CRS: EPSG:3460
All geom types: <ArrowStringArray>
['MultiLineString']
Length: 1, dtype: str
All MultiLineString: True

Total features: 30
37:33
Everything looks good. The output file is valid, all features are MultiLineString, the antimeridian-crossing transects (T001-T010) are split into 2-part MultiLineStrings, and all attributes are carried through with the added length_m field.

Let me provide a summary.
37:33