import { MultiPolygon , Pair , Ring , BBox } from '../types.js' ; import { clipMultipolygon } from './clipped.js' ; import { Wgs84 } from '../wgs84.js' ; const WorldBounds = [ - 180 , - 90 , 180 , 90 ] ; const NextWorldBounds = [ 180 , - 90 , 360 , 90 ] ; export type ConvertCoordinates = ( coordinates : number [ ] ) => number [ ] ; param frac param a param b function pointAtFrac ( frac , a , b ) { return [ a [ 0 ] + ( b [ 0 ] - a [ 0 ] ) * frac , a [ 1 ] + ( b [ 1 ] - a [ 1 ] ) * frac ] ; } param multipoly export function splitWgs84MultiPolygon ( multipoly ) { const result = [ ] ; for ( const poly of clipMultipolygon ( multipoly , WorldBounds ) ) { result . push ( poly ) ; } for ( const poly of clipMultipolygon ( multipoly , NextWorldBounds ) ) { result . push ( poly . map ( ( ring ) => ring . map ( ( point ) => [ point [ 0 ] - 360 , point [ 1 ] ] ) ) ) ; } return result ; } param multipoly param toWgs84 param split export function multiPolygonToWgs84 ( multipoly , toWgs84 , split = true ) { let polyCrossesAM = false ; let crossing = false ; const result = multipoly . map ( ( sPoly ) => sPoly . map ( ( sRing ) => { const wRing = [ ] ; if ( sRing . length === 0 ) return wRing ; let sPrev = sRing [ 0 ] ; let wPrev = null ; let pLon = 0 ; for ( const sPoint of sRing ) { const wPoint = toWgs84 ( sPoint ) as Pair ; const wLon = wPoint [ 0 ] ; if ( wPrev != null ) { const lineCrosses = Wgs84 . crossesAM ( pLon , wLon ) ; if ( lineCrosses ) { polyCrossesAM = true ; crossing = ! crossing ; } if ( crossing ) { if ( wLon < 0 ) { wPoint [ 0 ] = wLon + 360 ; } else { wPrev [ 0 ] = pLon + 360 ; } } if ( lineCrosses ) { const frac = ( 180 - wPoint [ 0 ] ) / ( wPrev [ 0 ] - wPoint [ 0 ] ) ; const midPoint = toWgs84 ( pointAtFrac ( frac , sPoint , sPrev ) ) ; wRing . push ( [ 180 , midPoint [ 1 ] ] ) ; } } wRing . push ( wPoint ) ; sPrev = sPoint ; wPrev = wPoint ; pLon = wLon ; } return wRing ; } ) ) ; if ( polyCrossesAM && split ) { return splitWgs84MultiPolygon ( result ) ; } return result ; }