SOLVED

Azure maps: Trying to draw direct line between two point at two corners of world

%3CLINGO-SUB%20id%3D%22lingo-sub-1613237%22%20slang%3D%22en-US%22%3EAzure%20maps%3A%20Trying%20to%20draw%20direct%20line%20between%20two%20point%20at%20two%20corners%20of%20world%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1613237%22%20slang%3D%22en-US%22%3E%3CP%3EAm%20trying%20to%20plot%20direct%20line%20between%20%22green%20arrow%20location%22%20(right%20top%20corner)%20to%20%22destination%20popup%20point%22.%20But%20it's%20moving%20all%20around%20world%20as%20shown%20in%20picture.%20Any%20suggestion%3F%20Please%20find%20image%20for%20reference.%3C%2FP%3E%3CP%3EOther%20lines%20whose%20points%20are%20not%20on%20world%20edges%20are%20working%20fine.%3C%2FP%3E%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%22Screen%20Shot%202020-08-26%20at%209.21.05%20pm.png%22%20style%3D%22width%3A%20999px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F214785iAF3659F513611B46%2Fimage-size%2Flarge%3Fv%3D1.0%26amp%3Bpx%3D999%22%20title%3D%22Screen%20Shot%202020-08-26%20at%209.21.05%20pm.png%22%20alt%3D%22Screen%20Shot%202020-08-26%20at%209.21.05%20pm.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-1615618%22%20slang%3D%22en-US%22%3ERe%3A%20Azure%20maps%3A%20Trying%20to%20draw%20direct%20line%20between%20two%20point%20at%20two%20corners%20of%20world%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1615618%22%20slang%3D%22en-US%22%3E%3CP%3E%3CSPAN%3EI%20believe%2C%20i%20understand%20the%20issue%20now%20but%20still%20don't%20have%20solution%20for%20it.%20I%20have%20added%202%20images%20'third%20quadrant%20coordinates'%20and%20'fourth%20quadrant%20coordinates'%20for%20your%20reference.%20See%20the%20'position'%20coords%20in%20console%20and%20how%20they%20are%20varying%20when%20popup%20point%20is%20clicked%2C%20depending%20on%20its%20position%20in%20map.%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3EWhy%20it%20is%20not%20returning%20the%20same%20co-ordinates%20irrespective%20of%20map%20position%3F%20I%20think%20answer%20to%20this%20will%20help%20to%20fix%20this%20issue%3C%2FSPAN%3E%3CBR%20%2F%3E%3CBR%20%2F%3E%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-1617575%22%20slang%3D%22en-US%22%3ERe%3A%20Azure%20maps%3A%20Trying%20to%20draw%20direct%20line%20between%20two%20point%20at%20two%20corners%20of%20world%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1617575%22%20slang%3D%22en-US%22%3E%3CP%3E%3CA%20href%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F771762%22%20target%3D%22_blank%22%3E%40welcomenxj%3C%2FA%3E%26nbsp%3BAdditional%20details%20and%20comments%20here%3A%26nbsp%3B%3CA%20href%3D%22https%3A%2F%2Fstackoverflow.com%2Fquestions%2F63596623%2Fazure-maps-trying-to-draw-direct-line-between-two-point-at-two-corners-of-world%22%20target%3D%22_blank%22%20rel%3D%22nofollow%20noopener%20noreferrer%22%3Ehttps%3A%2F%2Fstackoverflow.com%2Fquestions%2F63596623%2Fazure-maps-trying-to-draw-direct-line-between-two-point-at-two-corners-of-world%3C%2FA%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EDoes%20the%20last%20comment%20help%3F%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-1621842%22%20slang%3D%22en-US%22%3ERe%3A%20Azure%20maps%3A%20Trying%20to%20draw%20direct%20line%20between%20two%20point%20at%20two%20corners%20of%20world%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1621842%22%20slang%3D%22en-US%22%3E%3CP%3E%3CA%20href%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F351462%22%20target%3D%22_blank%22%3E%40ricky_brundritt%3C%2FA%3E%26nbsp%3Bthanks%20for%20the%20response%20Ricky.%20With%20your%20last%20response%2C%20am%20able%20to%20understand%20what%20SHOULD%20be%20happening%20under%20the%20hood.%20But%20I%20don't%20understand%20why%20its%20not%20happening%20for%20me%20when%20i%20try%20to%20cross%20pacific%20with%20these%20line%20coords%20from%20north%20america%20to%20melbourne%26nbsp%3B%3CSPAN%3Eline%20co-ords%20%5B%7BLng%3A%20-118.1948%2C%20Lat%3A%2033.767109%7D%2C%20%7BLng%3A%20144.9586%2C%20Lat%3A%20-37.848381%7D%5D%3C%2FSPAN%3E%3F%20Is%20there%20any%20Map%20configuration%20which%20i%20need%20to%20enable%20to%20draw%20direct%20line%20between%20these%20two%20points%20crossing%20the%20pacific%3F%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-1621865%22%20slang%3D%22en-US%22%3ERe%3A%20Azure%20maps%3A%20Trying%20to%20draw%20direct%20line%20between%20two%20point%20at%20two%20corners%20of%20world%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1621865%22%20slang%3D%22en-US%22%3ECan%20you%20verify%20you%20are%20using%20version%202%20of%20the%20SDK%3F%20Look%20at%20the%20script%20URL%20and%20you%20should%20see%20%2F2%2F%20in%20it.%20If%20you%20don't%20see%20that%20you%20likely%20are%20pointing%20to%20v1%20which%20didn't%20support%20%22world%20wrap%22%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-1622131%22%20slang%3D%22en-US%22%3ERe%3A%20Azure%20maps%3A%20Trying%20to%20draw%20direct%20line%20between%20two%20point%20at%20two%20corners%20of%20world%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1622131%22%20slang%3D%22en-US%22%3E%3CP%3E%3CA%20href%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F351462%22%20target%3D%22_blank%22%3E%40ricky_brundritt%3C%2FA%3E%26nbsp%3BThanks%20for%20checking%20back.%3CBR%20%2F%3EAm%20using%20latest%20version%20of%20'Azure%20Map%20Web%20SDK'%20as%20npm%20package%26nbsp%3B%3C%2FP%3E%3CDIV%3E%3CDIV%3E%3CSPAN%3E%22azure-maps-control%22%3C%2FSPAN%3E%3CSPAN%3E%3A%20%3C%2FSPAN%3E%3CSPAN%3E%22%5E2.0.28%22.%3CBR%20%2F%3E%3C%2FSPAN%3EIs%20this%20okay%3F%20Is%20there%20anything%20else%20i%20need%20to%20configure%20while%20creating%20Map%20instance%20or%20setting%20any%20property%20explicitly%3F%3C%2FDIV%3E%3CDIV%3E%26nbsp%3B%3C%2FDIV%3E%3C%2FDIV%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-1630379%22%20slang%3D%22en-US%22%3ERe%3A%20Azure%20maps%3A%20Trying%20to%20draw%20direct%20line%20between%20two%20point%20at%20two%20corners%20of%20world%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1630379%22%20slang%3D%22en-US%22%3E%3CP%3E%3CA%20href%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F771762%22%20target%3D%22_blank%22%3E%40welcomenxj%3C%2FA%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EManaged%20to%20reproduce%20the%20issue%20and%20after%20talking%20with%20one%20of%20our%20architects%20I%20was%20reminded%20that%20the%20GeoJSON%20specification%20does%20not%20allow%20shapes%20to%20cross%20the%20antemeridian.%20I'm%20not%20a%20fan%20of%20this%2C%20luckily%20there%20are%20a%20few%20ways%20around%20this%3A%3C%2FP%3E%0A%3CP%3EOptions%201%3A%3C%2FP%3E%0A%3CUL%3E%0A%3CLI%3E%3CP%3ESimilar%20to%20above%2C%20but%20break%20the%20line%20into%20segments%20to%20minimize%20complexity%20and%20shift%20longitude%20values%20outside%20of%20the%20-180%2F180%20range%20as%20needed.%20Then%20create%20a%20MultiLineString%20from%20the%20segments.%3C%2FP%3E%0A%3C%2FLI%3E%0A%3CLI%3E%3CP%3EYou%20end%20up%20with%20a%20line%20with%20coordinates%20outside%20of%20the%20standard%20range%20but%20should%20render%20any%20line%20back%20and%20forth%20over%20the%20antemeridian%20as%20needed.%3C%2FP%3E%0A%3C%2FLI%3E%0A%3C%2FUL%3E%0A%3CP%3EOption%202%3A%3C%2FP%3E%0A%3CUL%3E%0A%3CLI%3E%3CP%3ELeverage%20a%20library%20to%20split%20the%20line%20segments%20on%20the%20antemeridian%20and%20create%20a%20MultiLineString.%3C%2FP%3E%0A%3C%2FLI%3E%0A%3CLI%3E%3CP%3EThis%20method%20is%20a%20lot%20more%20work%20and%20and%20might%20not%20be%20as%20accurate%2C%20but%20should%20also%20work%20with%20any%20line.%3C%2FP%3E%0A%3C%2FLI%3E%0A%3C%2FUL%3E%0A%3CP%3EHere%20is%20a%20code%20sample%20showing%20all%20two%20options%3A%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CPRE%20class%3D%22lia-code-sample%20language-html%22%3E%3CCODE%3E%0A%0A%0A%20%20%20%20%3CTITLE%3E%3C%2FTITLE%3E%0A%0A%20%20%20%20%26lt%3Bmeta%20charset%3D%22utf-8%22%20%2F%26gt%3B%0A%20%20%20%20%26lt%3Bmeta%20http-equiv%3D%22x-ua-compatible%22%20content%3D%22IE%3DEdge%22%20%2F%26gt%3B%0A%20%20%20%20%26lt%3Bmeta%20name%3D%22viewport%22%20content%3D%22width%3Ddevice-width%2C%20initial-scale%3D1%2C%20shrink-to-fit%3Dno%22%20%2F%26gt%3B%0A%0A%20%20%20%20%3C!--%20Add%20references%20to%20the%20Azure%20Maps%20Map%20control%20JavaScript%20and%20CSS%20files.%20--%3E%0A%20%20%20%20%3CLINK%20rel%3D%22stylesheet%22%20href%3D%22https%3A%2F%2Fatlas.microsoft.com%2Fsdk%2Fjavascript%2Fmapcontrol%2F2%2Fatlas.min.css%22%20type%3D%22text%2Fcss%22%20%2F%3E%0A%20%20%20%20%3CSCRIPT%20src%3D%22https%3A%2F%2Fatlas.microsoft.com%2Fsdk%2Fjavascript%2Fmapcontrol%2F2%2Fatlas.js%22%3E%3C%2FSCRIPT%3E%0A%20%0A%20%3C!--%20Load%20turf.js%20a%20spatial%20math%20library.%20https%3A%2F%2Fturfjs.org%2F%20--%3E%0A%20%20%20%20%3CSCRIPT%20src%3D%22https%3A%2F%2Fnpmcdn.com%2F%40turf%2Fturf%2Fturf.min.js%22%3E%3C%2FSCRIPT%3E%0A%0A%20%20%20%20%3CSCRIPT%20type%3D%22text%2Fjavascript%22%3E%0A%20%20%20%20%20%20%20%20var%20map%2C%20datasource%3B%0A%20%20%0A%20%20var%20data%20%3D%20%20%7B%0A%20%20%20%20%20%22type%22%3A%20%22Feature%22%2C%0A%20%20%20%20%20%22properties%22%3A%20%7B%7D%2C%0A%20%20%20%20%20%22geometry%22%3A%20%7B%0A%20%20%20%20%20%20%22type%22%3A%20%22LineString%22%2C%0A%20%20%20%20%20%20%22coordinates%22%3A%20%5B%0A%20%20%20%20%20%20%20%5B%0A%20%20%20%20%20%20%20%20144.9586%2C%0A%20%20%20%20%20%20%20%20-37.848381%0A%20%20%20%20%20%20%20%5D%2C%0A%20%20%20%20%20%20%20%5B%0A%20%20%20%20%20%20%20%20-118.1948%2C%0A%20%20%20%20%20%20%20%2033.767109%0A%20%20%20%20%20%20%20%5D%0A%20%20%20%20%20%20%5D%0A%20%20%20%20%20%7D%0A%20%20%20%20%7D%3B%0A%0A%20%20%20%20%20%20%20%20function%20GetMap()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2FInitialize%20a%20map%20instance.%0A%20%20%20%20%20%20%20%20%20%20%20%20map%20%3D%20new%20atlas.Map('myMap'%2C%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20view%3A%20'Auto'%2C%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2FAdd%20your%20Azure%20Maps%20subscription%20client%20ID%20to%20the%20map%20SDK.%20Get%20an%20Azure%20Maps%20client%20ID%20at%20https%3A%2F%2Fazure.com%2Fmaps%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20authOptions%3A%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20authType%3A%20'subscriptionKey'%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20subscriptionKey%3A%20'%26amp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Blt%3BYour%20Azure%20Maps%20Key%26amp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bgt%3B'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D)%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2FWait%20until%20the%20map%20resources%20are%20ready.%0A%20%20%20%20%20%20%20%20%20%20%20%20map.events.add('ready'%2C%20function%20()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2FCreate%20a%20data%20source%20to%20add%20your%20data%20to.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20datasource%20%3D%20new%20atlas.source.DataSource()%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20map.sources.add(datasource)%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2FAdd%20a%20layer%20for%20rendering%20data.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20map.layers.add(new%20atlas.layer.LineLayer(datasource))%3B%0A%20%20%20%20%0A%20%20%20%20map.setCamera(%7B%0A%20%20%20%20%20bounds%3A%20atlas.data.BoundingBox.fromData(data)%0A%20%20%20%20%7D)%3B%0A%20%20%20%7D)%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%0A%20%20function%20option1%20()%20%7B%0A%20%20%20%2F%2FTrick%20map%20to%20render%20one%20of%20the%20points%20on%20an%20adjacent%20map.%20Doing%20a%20deep%20copy%20of%20the%20coordinates%20to%20be%20safe%20since%20reusing%20in%20sample.%0A%20%20%20var%20c%20%3D%20data.geometry.coordinates.map(function(arr)%20%7B%0A%20%20%20%20%20return%20arr.slice()%3B%0A%20%20%20%20%7D)%3B%0A%20%20%20%0A%20%20%20var%20lastCoord%20%3D%20c%5B0%5D%3B%0A%20%20%20var%20newCoords%20%3D%20%5B%5D%3B%0A%20%20%20var%20newCoord%3B%0A%20%20%20%20%20%20%0A%20%20%20for(var%20i%20%3D%201%2C%20len%20%3D%20c.length%3B%20i%20%26amp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Blt%3B%20len%3B%20i%2B%2B)%7B%0A%20%20%20%20let%20diff%20%3D%20lastCoord%5B0%5D%20-%20c%5Bi%5D%5B0%5D%3B%0A%20%20%20%20%0A%20%20%20%20if(diff%20%26amp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bgt%3B%20180)%7B%0A%20%20%20%20%20%2F%2FLine%20going%20left%20to%20right%2C%20but%20should%20go%20opposite%20direction.%0A%20%20%20%20%20newCoord%20%3D%20%5Bc%5Bi%5D%5B0%5D%20%2B%20360%2C%20c%5Bi%5D%5B1%5D%5D%3B%0A%20%20%20%20%7D%20else%20if%20(diff%20%26amp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Blt%3B%20-180)%20%7B%0A%20%20%20%20%20%2F%2FLine%20going%20right%20to%20left%2C%20but%20should%20go%20opposite%20direction.%0A%20%20%20%20%20newCoord%20%3D%20%5Bc%5Bi%5D%5B0%5D%20-%20360%2C%20c%5Bi%5D%5B1%5D%5D%3B%20%20%20%20%20%0A%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%2F%2FLeave%20coord%20as%20is.%0A%20%20%20%20%20newCoord%20%3D%20c%5Bi%5D%3B%20%20%20%20%20%0A%20%20%20%20%7D%0A%20%20%20%20%0A%20%20%20%20newCoords.push(%5BlastCoord%2C%20newCoord%5D)%3B%0A%20%20%20%20lastCoord%20%3D%20c%5Bi%5D%3B%0A%20%20%20%7D%0A%20%20%20%0A%20%20%20datasource.setShapes(new%20atlas.data.MultiLineString(newCoords))%3B%0A%20%20%7D%0A%0A%20%20function%20option2()%20%7B%0A%20%20%20%2F%2FSplit%20the%20line%20into%20segments%20and%20split%20each%20segment%20on%20the%20antimeridian%2C%20then%20create%20a%20MultuLineString%20from%20the%20segments.%0A%20%20%20var%20c%20%3D%20data.geometry.coordinates%3B%0A%20%20%20%0A%20%20%20var%20newCoords%20%3D%20%5B%5D%3B%0A%20%20%20%0A%20%20%20for(var%20i%20%3D%201%2C%20len%20%3D%20c.length%3B%20i%20%26amp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Blt%3B%20len%3B%20i%2B%2B)%7B%0A%20%20%20%20newCoords%20%3D%20newCoords.concat(splitLineSegment(c%5Bi%20-%201%5D%2C%20c%5Bi%5D))%3B%20%0A%20%20%20%7D%0A%20%20%20%0A%20%20%20datasource.setShapes(new%20atlas.data.MultiLineString(newCoords))%3B%0A%20%20%7D%0A%20%20%0A%20%20function%20splitLineSegment(fromPos%2C%20toPos)%20%7B%0A%20%20%20var%20path%3B%0A%0A%20%20%20%2F%2FCheck%20to%20see%20if%20path%20should%20cross%20anti-meridian.%0A%20%20%20if%20(Math.abs(fromPos%5B0%5D%20-%20toPos%5B0%5D)%20%26amp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bgt%3B%20180%20%26amp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3B%26amp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3B%20Math.abs(fromPos%5B0%5D)%20%26amp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bgt%3B%2090)%20%7B%0A%20%20%20%20var%20l1%2C%20l2%3B%0A%0A%20%20%20%20var%20rightMostPos%20%3D%20toPos%3B%0A%20%20%20%20var%20leftMostPos%20%3D%20fromPos%3B%0A%0A%20%20%20%20if%20(fromPos%5B0%5D%20%26amp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bgt%3B%20toPos%5B0%5D)%20%7B%0A%20%20%20%20%20rightMostPos%20%3D%20fromPos%3B%0A%20%20%20%20%20leftMostPos%20%3D%20toPos%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20%2F%2FWrap%20the%20left%20most%20coordinate%20to%20a%20value%20between%20180%20and%20540%2C%20then%20split%20on%20anti-meridian.%0A%20%20%20%20var%20fc%20%3D%20turf.lineSplit(%0A%20%20%20%20%20%2F%2FLine%20to%20split.%0A%20%20%20%20%20turf.lineString(%5BrightMostPos%2C%20%5BleftMostPos%5B0%5D%20%2B%20360%2C%20leftMostPos%5B1%5D%5D%5D)%2C%0A%0A%20%20%20%20%20%2F%2FLine%20to%20split%20with.%0A%20%20%20%20%20turf.lineString(%5B%5B180%2C%2090%5D%2C%20%5B180%2C%20-90%5D%5D))%3B%0A%0A%20%20%20%20%2F%2FGet%20the%20first%20line%20segment.%20%0A%20%20%20%20var%20seg1%20%3D%20fc.features%5B0%5D.geometry.coordinates%3B%20%20%20%20%20%20%20%20%0A%20%20%20%20shiftPositions(seg1%5B0%5D%2C%20seg1%5B1%5D)%3B%0A%20%20%20%20%0A%20%20%20%20%2F%2FIts%20possible%20that%20there%20is%20a%20shared%20coordinate%20in%20the%20two%20line%20segments%2C%20do%20a%20deep%20copy%20of%20the%20second%20segment%20cooridnates%20to%20be%20safe.%0A%20%20%20%20var%20seg2%20%3D%20fc.features%5B1%5D.geometry.coordinates.map(function(arr)%20%7B%0A%20%20%20%20%20return%20arr.slice()%3B%0A%20%20%20%20%7D)%3B%0A%20%20%20%20%0A%20%20%20%20shiftPositions(seg2%5B0%5D%2C%20seg2%5B1%5D)%3B%0A%20%20%20%0A%20%20%20%20return%20%5B%0A%20%20%20%20%20%2F%2FSegment%201%0A%20%20%20%20%20seg1%2C%0A%20%20%20%20%20%0A%20%20%20%20%20%2F%2FSegment%202%0A%20%20%20%20%20seg2%0A%20%20%20%20%5D%3B%20%20%20%0A%20%20%20%7D%20else%20%7B%0A%20%20%20%20%2F%2FOnly%20a%20single%20line%20segment.%0A%20%20%20%20return%20%5B%5BfromPos%2C%20toPos%5D%5D%3B%0A%20%20%20%7D%0A%20%20%7D%0A%20%20%0A%20%20function%20shiftPositions(p1%2C%20p2)%20%7B%0A%20%20%20%2F%2FIf%20either%20position%20has%20a%20longitude%20value%20outside%20of%20the%20-180%20to%20180%20range%2C%20shift%20the%20longitude%20value%20of%20both%20positions%20as%20needed.%0A%20%20%20%0A%20%20%20if(p1%5B0%5D%20%26amp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bgt%3B%20180%20%7C%7C%20p2%5B0%5D%20%26amp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bgt%3B%20180)%7B%0A%20%20%20%20p1%5B0%5D%20-%3D%20360%3B%0A%20%20%20%20p2%5B0%5D%20-%3D%20360%3B%0A%20%20%20%7D%20else%20if(p1%5B0%5D%20%26amp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Blt%3B%20-180%20%7C%7C%20p2%5B0%5D%20%26amp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Blt%3B%20-180)%7B%0A%20%20%20%20p1%5B0%5D%20%2B%3D%20360%3B%0A%20%20%20%20p2%5B0%5D%20%2B%3D%20360%3B%0A%20%20%20%7D%20%0A%20%20%7D%0A%20%20%20%20%3C%2FSCRIPT%3E%0A%0A%0A%20%20%20%20%3CDIV%20id%3D%22myMap%22%20style%3D%22position%3Arelative%3Bwidth%3A100%25%3Bheight%3A600px%3B%22%3E%3C%2FDIV%3E%0A%20%0A%20%3CINPUT%20type%3D%22button%22%20onclick%3D%22option1()%22%20value%3D%22Option%201%22%20%2F%3E%0A%20%3CINPUT%20type%3D%22button%22%20onclick%3D%22option2()%22%20value%3D%22Option%202%22%20%2F%3E%0A%0A%3C%2FCODE%3E%3C%2FPRE%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-1630411%22%20slang%3D%22en-US%22%3ERe%3A%20Azure%20maps%3A%20Trying%20to%20draw%20direct%20line%20between%20two%20point%20at%20two%20corners%20of%20world%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1630411%22%20slang%3D%22en-US%22%3E%3CP%3E%3CA%20href%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F351462%22%20target%3D%22_blank%22%3E%40ricky_brundritt%3C%2FA%3E%26nbsp%3BGreat%20efforts!%20Thanks%20Ricky%20for%20investing%20your%20time%20in%20this%20and%20doing%20lot%20of%20trials%20on%20this%20topic.%26nbsp%3B%3C%2FP%3E%3CP%3EDay%20before%20yesterday%2CI%20tried%20similar%20solution%20as%20below%20which%20seems%20working%3A%3CBR%20%2F%3E%3CBR%20%2F%3E%3C%2FP%3E%3CDIV%3E%3CDIV%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%22Screen%20Shot%202020-09-03%20at%205.05.43%20pm.png%22%20style%3D%22width%3A%20999px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F216219i3FFA8D57EB747406%2Fimage-size%2Flarge%3Fv%3D1.0%26amp%3Bpx%3D999%22%20title%3D%22Screen%20Shot%202020-09-03%20at%205.05.43%20pm.png%22%20alt%3D%22Screen%20Shot%202020-09-03%20at%205.05.43%20pm.png%22%20%2F%3E%3C%2FSPAN%3E%3CSPAN%3Eif%3C%2FSPAN%3E%3CSPAN%3E%20(%3C%2FSPAN%3E%3CSPAN%3EMath%3C%2FSPAN%3E%3CSPAN%3E.%3C%2FSPAN%3E%3CSPAN%3Eabs%3C%2FSPAN%3E%3CSPAN%3E(%3C%2FSPAN%3E%3CSPAN%3EpreviousCoordinate%3C%2FSPAN%3E%3CSPAN%3E.%3C%2FSPAN%3E%3CSPAN%3ELng%3C%2FSPAN%3E%20%3CSPAN%3E-%3C%2FSPAN%3E%26nbsp%3BnextCoordinate%3CSPAN%3E.%3C%2FSPAN%3E%3CSPAN%3ELng%3C%2FSPAN%3E%3CSPAN%3E)%20%3C%2FSPAN%3E%3CSPAN%3E%26gt%3B%3C%2FSPAN%3E%20%3CSPAN%3E180%3C%2FSPAN%3E)%20%7B%3C%2FDIV%3E%3CDIV%3E%3CSPAN%3Elocation%3C%2FSPAN%3E%3CSPAN%3E.%3C%2FSPAN%3E%3CSPAN%3ELng%3C%2FSPAN%3E%20%3CSPAN%3E%3D%3C%2FSPAN%3E%20%3CSPAN%3Elocation%3C%2FSPAN%3E%3CSPAN%3E.%3C%2FSPAN%3E%3CSPAN%3ELng%3C%2FSPAN%3E%20%3CSPAN%3E-%3C%2FSPAN%3E%20%3CSPAN%3E360%3C%2FSPAN%3E%3CSPAN%3E%3B%3C%2FSPAN%3E%3C%2FDIV%3E%3CDIV%3E%3CSPAN%3E%7D%3CBR%20%2F%3E%3CBR%20%2F%3EBut%20i%20thought%20Azure%20Maps%20must%20be%20having%20better%2F%20standard%20way%20of%20handling%20it%20than%20this%20approach.%3CBR%20%2F%3E%3CBR%20%2F%3EThis%20works%20for%20both%20scenarios%20of%20line%20going%20from%20'left%20to%20right'%20and%20right%20to%20left'%3CBR%20%2F%3EI%20played%20along%20longitude%20only%20as%20latitude%20doesn't%20cause%20any%20issue%20in%20crossing%20pacific.%3CBR%20%2F%3EDo%20you%20see%20any%20other%20issue%20with%20this%20approach%20that%20i%20must%20test%3F%3CBR%20%2F%3E%3C%2FSPAN%3E%3C%2FDIV%3E%3C%2FDIV%3E%3C%2FLINGO-BODY%3E
Occasional Contributor

Am trying to plot direct line between "green arrow location" (right top corner) to "destination popup point". But it's moving all around world as shown in picture. Any suggestion? Please find image for reference.

Other lines whose points are not on world edges are working fine.

Screen Shot 2020-08-26 at 9.21.05 pm.png

7 Replies

I believe, i understand the issue now but still don't have solution for it. I have added 2 images 'third quadrant coordinates' and 'fourth quadrant coordinates' for your reference. See the 'position' coords in console and how they are varying when popup point is clicked, depending on its position in map.
Why it is not returning the same co-ordinates irrespective of map position? I think answer to this will help to fix this issue

@rbrundritt thanks for the response Ricky. With your last response, am able to understand what SHOULD be happening under the hood. But I don't understand why its not happening for me when i try to cross pacific with these line coords from north america to melbourne line co-ords [{Lng: -118.1948, Lat: 33.767109}, {Lng: 144.9586, Lat: -37.848381}]? Is there any Map configuration which i need to enable to draw direct line between these two points crossing the pacific?

 

Can you verify you are using version 2 of the SDK? Look at the script URL and you should see /2/ in it. If you don't see that you likely are pointing to v1 which didn't support "world wrap"

@rbrundritt Thanks for checking back.
Am using latest version of 'Azure Map Web SDK' as npm package 

"azure-maps-control": "^2.0.28".
Is this okay? Is there anything else i need to configure while creating Map instance or setting any property explicitly?
 
best response confirmed by welcomenxj (Occasional Contributor)
Solution

@welcomenxj 

Managed to reproduce the issue and after talking with one of our architects I was reminded that the GeoJSON specification does not allow shapes to cross the antemeridian. I'm not a fan of this, luckily there are a few ways around this:

Options 1:

  • Similar to above, but break the line into segments to minimize complexity and shift longitude values outside of the -180/180 range as needed. Then create a MultiLineString from the segments.

  • You end up with a line with coordinates outside of the standard range but should render any line back and forth over the antemeridian as needed.

Option 2:

  • Leverage a library to split the line segments on the antemeridian and create a MultiLineString.

  • This method is a lot more work and and might not be as accurate, but should also work with any line.

Here is a code sample showing all two options:

 

<!DOCTYPE html>
<html lang="en">
<head>
    <title></title>

    <meta charset="utf-8" />
    <meta http-equiv="x-ua-compatible" content="IE=Edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />

    <!-- Add references to the Azure Maps Map control JavaScript and CSS files. -->
    <link rel="stylesheet" href="#" type="text/css" />
    <script src="https://atlas.microsoft.com/sdk/javascript/mapcontrol/2/atlas.js"></script>
	
	<!-- Load turf.js a spatial math library. https://turfjs.org/ -->
    <script src='https://npmcdn.com/@turf/turf/turf.min.js'></script>

    <script type='text/javascript'>
        var map, datasource;
		
		var data =  {
					"type": "Feature",
					"properties": {},
					"geometry": {
						"type": "LineString",
						"coordinates": [
							[
								144.9586,
								-37.848381
							],
							[
								-118.1948,
								33.767109
							]
						]
					}
				};

        function GetMap() {
            //Initialize a map instance.
            map = new atlas.Map('myMap', {
                view: 'Auto',

                //Add your Azure Maps subscription client ID to the map SDK. Get an Azure Maps client ID at https://azure.com/maps
                authOptions: {
                    authType: 'subscriptionKey',
                    subscriptionKey: '<Your Azure Maps Key>'
                }
            });

            //Wait until the map resources are ready.
            map.events.add('ready', function () {
                //Create a data source to add your data to.
                datasource = new atlas.source.DataSource();
                map.sources.add(datasource);

                //Add a layer for rendering data.
                map.layers.add(new atlas.layer.LineLayer(datasource));
				
				map.setCamera({
					bounds: atlas.data.BoundingBox.fromData(data)
				});
			});
        }
				
		function option1 () {
			//Trick map to render one of the points on an adjacent map. Doing a deep copy of the coordinates to be safe since reusing in sample.
			var c = data.geometry.coordinates.map(function(arr) {
					return arr.slice();
				});
			
			var lastCoord = c[0];
			var newCoords = [];
			var newCoord;
						
			for(var i = 1, len = c.length; i < len; i++){
				let diff = lastCoord[0] - c[i][0];
				
				if(diff > 180){
					//Line going left to right, but should go opposite direction.
					newCoord = [c[i][0] + 360, c[i][1]];
				} else if (diff < -180) {
					//Line going right to left, but should go opposite direction.
					newCoord = [c[i][0] - 360, c[i][1]];					
				} else {
					//Leave coord as is.
					newCoord = c[i];					
				}
				
				newCoords.push([lastCoord, newCoord]);
				lastCoord = c[i];
			}
			
			datasource.setShapes(new atlas.data.MultiLineString(newCoords));
		}

		function option2() {
			//Split the line into segments and split each segment on the antimeridian, then create a MultuLineString from the segments.
			var c = data.geometry.coordinates;
			
			var newCoords = [];
			
			for(var i = 1, len = c.length; i < len; i++){
				newCoords = newCoords.concat(splitLineSegment(c[i - 1], c[i]));	
			}
			
			datasource.setShapes(new atlas.data.MultiLineString(newCoords));
		}
		
		function splitLineSegment(fromPos, toPos) {
			var path;

			//Check to see if path should cross anti-meridian.
			if (Math.abs(fromPos[0] - toPos[0]) > 180 && Math.abs(fromPos[0]) > 90) {
				var l1, l2;

				var rightMostPos = toPos;
				var leftMostPos = fromPos;

				if (fromPos[0] > toPos[0]) {
					rightMostPos = fromPos;
					leftMostPos = toPos;
				}

				//Wrap the left most coordinate to a value between 180 and 540, then split on anti-meridian.
				var fc = turf.lineSplit(
					//Line to split.
					turf.lineString([rightMostPos, [leftMostPos[0] + 360, leftMostPos[1]]]),

					//Line to split with.
					turf.lineString([[180, 90], [180, -90]]));

				//Get the first line segment. 
				var seg1 = fc.features[0].geometry.coordinates;								
				shiftPositions(seg1[0], seg1[1]);
				
				//Its possible that there is a shared coordinate in the two line segments, do a deep copy of the second segment cooridnates to be safe.
				var seg2 = fc.features[1].geometry.coordinates.map(function(arr) {
					return arr.slice();
				});
				
				shiftPositions(seg2[0], seg2[1]);
			
				return [
					//Segment 1
					seg1,
					
					//Segment 2
					seg2
				];			
			} else {
				//Only a single line segment.
				return [[fromPos, toPos]];
			}
		}
		
		function shiftPositions(p1, p2) {
			//If either position has a longitude value outside of the -180 to 180 range, shift the longitude value of both positions as needed.
			
			if(p1[0] > 180 || p2[0] > 180){
				p1[0] -= 360;
				p2[0] -= 360;
			} else if(p1[0] < -180 || p2[0] < -180){
				p1[0] += 360;
				p2[0] += 360;
			} 
		}
    </script>
</head>
<body onload="GetMap()">
    <div id="myMap" style="position:relative;width:100%;height:600px;"></div>
	
	<input type="button" onclick="option1()" value="Option 1"/>
	<input type="button" onclick="option2()" value="Option 2"/>
</body>
</html>

@rbrundritt Great efforts! Thanks Ricky for investing your time in this and doing lot of trials on this topic. 

Day before yesterday,I tried similar solution as below which seems working:

Screen Shot 2020-09-03 at 5.05.43 pm.pngif (Math.abs(previousCoordinate.Lng - nextCoordinate.Lng) > 180) {
location.Lng = location.Lng - 360;
}

But i thought Azure Maps must be having better/ standard way of handling it than this approach.

This works for both scenarios of line going from 'left to right' and right to left'
I played along longitude only as latitude doesn't cause any issue in crossing pacific.
Do you see any other issue with this approach that i must test?
www.000webhost.com