Calculating correct longitude when it's over |180|?











up vote
7
down vote

favorite












I'm trying to develop a "formula" to correct the lat-lng values.



I'm using vue-leaflet but when you pan outside the "first" world you get big numbers. Over +180 or under -180.



For example: when I pan to America to the right (east direction), I get as lng 215.
In my mind, I would just correct it with 215-360=-145



The same is for when I pan to east russia to the left (west direction) and I get for example -222. Now I need to calculate -222+360=138



However, since the world is indefinite the user could pan to the 8th world and I had to adjust the values.



Is it possible to calculate the right longitude? (and another requirement is when the user is in the first world, 24 lng should still be 24 lng.










share|improve this question









New contributor




Shadrix is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
























    up vote
    7
    down vote

    favorite












    I'm trying to develop a "formula" to correct the lat-lng values.



    I'm using vue-leaflet but when you pan outside the "first" world you get big numbers. Over +180 or under -180.



    For example: when I pan to America to the right (east direction), I get as lng 215.
    In my mind, I would just correct it with 215-360=-145



    The same is for when I pan to east russia to the left (west direction) and I get for example -222. Now I need to calculate -222+360=138



    However, since the world is indefinite the user could pan to the 8th world and I had to adjust the values.



    Is it possible to calculate the right longitude? (and another requirement is when the user is in the first world, 24 lng should still be 24 lng.










    share|improve this question









    New contributor




    Shadrix is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.






















      up vote
      7
      down vote

      favorite









      up vote
      7
      down vote

      favorite











      I'm trying to develop a "formula" to correct the lat-lng values.



      I'm using vue-leaflet but when you pan outside the "first" world you get big numbers. Over +180 or under -180.



      For example: when I pan to America to the right (east direction), I get as lng 215.
      In my mind, I would just correct it with 215-360=-145



      The same is for when I pan to east russia to the left (west direction) and I get for example -222. Now I need to calculate -222+360=138



      However, since the world is indefinite the user could pan to the 8th world and I had to adjust the values.



      Is it possible to calculate the right longitude? (and another requirement is when the user is in the first world, 24 lng should still be 24 lng.










      share|improve this question









      New contributor




      Shadrix is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.











      I'm trying to develop a "formula" to correct the lat-lng values.



      I'm using vue-leaflet but when you pan outside the "first" world you get big numbers. Over +180 or under -180.



      For example: when I pan to America to the right (east direction), I get as lng 215.
      In my mind, I would just correct it with 215-360=-145



      The same is for when I pan to east russia to the left (west direction) and I get for example -222. Now I need to calculate -222+360=138



      However, since the world is indefinite the user could pan to the 8th world and I had to adjust the values.



      Is it possible to calculate the right longitude? (and another requirement is when the user is in the first world, 24 lng should still be 24 lng.







      leaflet javascript latitude-longitude






      share|improve this question









      New contributor




      Shadrix is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.











      share|improve this question









      New contributor




      Shadrix is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.









      share|improve this question




      share|improve this question








      edited 6 hours ago









      PolyGeo

      52.7k1779236




      52.7k1779236






      New contributor




      Shadrix is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.









      asked 22 hours ago









      Shadrix

      1384




      1384




      New contributor




      Shadrix is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.





      New contributor





      Shadrix is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.






      Shadrix is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.






















          5 Answers
          5






          active

          oldest

          votes

















          up vote
          10
          down vote



          accepted










          You need to repeatedly add (or subtract) 360 to your value until it lies in the range of -180 - 180. So usually a pair of loops like:



          lon = -187;
          while(lon < -180){
          lon +=360;
          }
          while (lon > 180){
          lon -= 360;
          }





          share|improve this answer























          • signs wrong way round? Should be lon +=360 in first case.
            – JimT
            21 hours ago






          • 2




            bleeugh, coding before coffee. Thanks
            – Ian Turton
            21 hours ago






          • 2




            you can do it with only one loop while (Math.abs(lon) > 180) { lon -= Math.sign(lon) * 360 } I am not providing it as an answer though because your version actually matches the explanation, while my version is just an optimization that likely doesn't make any difference. I keep it as a comment only as a reminder that things can be done in multiple ways, some more optimized than others.
            – Andrei
            20 hours ago






          • 1




            I don't think I would ever use that one as it uses 2 function calls per loop and only one of my loops would ever execute. Probably makes no difference in this example but that's my prejudice
            – Ian Turton
            20 hours ago






          • 2




            You can't do lon %= 180?
            – Nic Hartley
            13 hours ago


















          up vote
          7
          down vote













          An answer that avoids conditionals and function calls:



          longitude = (longitude % 360 + 540) % 360 - 180


          I wrote a quick microbenchmark at https://jsperf.com/longitude-normalisation and the conditional code seems to be faster (in Chrome on my machine) for 'reasonable' ranges of input values. In general you probably shouldn't be worrying in advance about performance in small calculations like this, giving more weight to readability and consistency with the rest of your codebase.



          Probably more important in this case is the question of whether your code could ever come across extreme input values (1e10, Infinity etc.). If so, the looping implementation could end up running really slowly or silently hanging your program. This might occur with calculations performed near the poles, e.g. trying to pan east or west by some distance (rather than angle) from a pole could easily result in an infinite longitude.






          share|improve this answer










          New contributor




          Joe Lee-Moyet is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
          Check out our Code of Conduct.














          • 1




            Interesting. Let's race a conditional jmp against a FP divide. Hmmm I wonder.
            – Joshua
            11 hours ago






          • 1




            @Joshua You can't use a conditional jump. You have to use multiple conditional jumps, aka a loop. (Plus the loop contains floating point additional, which isn't free.) How many iterations the loop needs depends on the input. So you have to know something about the data to look at performance. If the vast majority are near the desired range and require few iterations, sure, the addition loop might be faster, but it isn't as obvious as your sarcasm suggests.
            – jpmc26
            9 hours ago








          • 1




            @jpmc26: In this case, expecting to go around the loop more than once is silly.
            – Joshua
            9 hours ago






          • 1




            There was no sarcasm. I actually don't know which way it would fall.
            – Joshua
            9 hours ago






          • 1




            @Joshua yep, I wasn't sure either :). I added more to the answer on performance (and a potential failure case of the loop code)
            – Joe Lee-Moyet
            6 hours ago


















          up vote
          3
          down vote













          One-liner:



          normalized = remainder(longitude, 360);


          Explanation: You want to know what remains after you disregard full rotations (360°).



          This process is called normalizing.



          Example (cpp.sh)






          share|improve this answer










          New contributor




          Peter Paff is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
          Check out our Code of Conduct.














          • 1




            Wouldn't this result in a [0, 360) value, not [-180, 180] as Shadrix requested?
            – The Guy with The Hat
            15 hours ago










          • @TheGuywithTheHat Check this example: cpp.sh/7uy2v
            – Peter Paff
            14 hours ago










          • Ah, didn't know this was C++. In Shadrix's context of JavaScript, I interpreted remainder as modulus. Modulus in JS would result in [0, 360).
            – The Guy with The Hat
            14 hours ago












          • @TheGuywithTheHat subtract 180 from the result and done.
            – Peter Paff
            14 hours ago










          • I don't think that would work. You would need to subtract 360 iff result > 180. Another problem I just realized with JavaScript is that modulo is symmetrical across 0, e.g. -1 % 3 is -1, not 2 as would be necessary for it to work here. remainder is a great C++ solution, but unfortunately there's just no function/operator in JS that's similar enough to be useful.
            – The Guy with The Hat
            13 hours ago


















          up vote
          0
          down vote













          Another option: longitude = atan2(cos(long), sin(long))






          share|improve this answer

















          • 1




            This doesn't seem like a good idea. It's very hard to understand, computationally expensive and potentially subject to rounding errors.
            – David Richerby
            12 hours ago


















          up vote
          0
          down vote













          If the programming language you're using supports the % (mod) operator on floating point numbers (like Python and Ruby), I'd recommend using that. Otherwise, some other languages (like C and C++) allow you to use fmod().



          (Whichever mod operator you use, make sure ahead of time that it will do mod operations on floating-point numbers. Otherwise you'll get a nasty surprise later when many of your lat/lon points are not correct.)



          Use it like this:



          # Put the longitude in the range of [0,360):
          longitude %= 360

          # Put the longitude in the range of [-180,180):
          if longitude >= 180:
          longitude -= 360


          If you'd prefer to do it all in one line:



          # Put the longitude in the range of [-180,180):
          longitude = (longitude + 180) % 360 - 180


          These approaches have no loops, so they'll normalize longitude values without needing to repeatedly add or subtract, no matter how many times your observation has circled around the earth.



          Edit:



          Hmmm... I just noticed that Javascript doesn't seem to handle % with negative values like I thought it would.



          In that case, try this one-liner:



          longitude = (longitude + 36180) % 360 - 180


          The 36180 we're adding is 36,000 + 180. The 36,000 is to move a negative value into the positive domain, and the 180 is to shift it over so that when it is modded by 360, it'll be in the range of [0,360). The - 180 part shifts it back to the range of [-180,180).



          Here's another one-liner, one that doesn't rely on 36,000 being big enough:



          longitude = (longitude % 360 + 360 + 180) % 360 - 180


          The longitude % 360 + 360 part will ensure the value stays in the positive domain when it's later modded by 360. The + 180 part shifts it over so that when it later gets 180 subtracted from it (with - 180), it'll be in the desired range of [-180,180).






          share|improve this answer










          New contributor




          J-L is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
          Check out our Code of Conduct.


















          • Note: C,C++ fmod(longitude, 360) --> (-360.0 ... +360.0) and ilongitude % 360 --> [-359 ... +359].
            – chux
            1 hour ago













          Your Answer








          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "79"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          convertImagesToLinks: false,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });






          Shadrix is a new contributor. Be nice, and check out our Code of Conduct.










           

          draft saved


          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fgis.stackexchange.com%2fquestions%2f303300%2fcalculating-correct-longitude-when-its-over-180%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          5 Answers
          5






          active

          oldest

          votes








          5 Answers
          5






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          10
          down vote



          accepted










          You need to repeatedly add (or subtract) 360 to your value until it lies in the range of -180 - 180. So usually a pair of loops like:



          lon = -187;
          while(lon < -180){
          lon +=360;
          }
          while (lon > 180){
          lon -= 360;
          }





          share|improve this answer























          • signs wrong way round? Should be lon +=360 in first case.
            – JimT
            21 hours ago






          • 2




            bleeugh, coding before coffee. Thanks
            – Ian Turton
            21 hours ago






          • 2




            you can do it with only one loop while (Math.abs(lon) > 180) { lon -= Math.sign(lon) * 360 } I am not providing it as an answer though because your version actually matches the explanation, while my version is just an optimization that likely doesn't make any difference. I keep it as a comment only as a reminder that things can be done in multiple ways, some more optimized than others.
            – Andrei
            20 hours ago






          • 1




            I don't think I would ever use that one as it uses 2 function calls per loop and only one of my loops would ever execute. Probably makes no difference in this example but that's my prejudice
            – Ian Turton
            20 hours ago






          • 2




            You can't do lon %= 180?
            – Nic Hartley
            13 hours ago















          up vote
          10
          down vote



          accepted










          You need to repeatedly add (or subtract) 360 to your value until it lies in the range of -180 - 180. So usually a pair of loops like:



          lon = -187;
          while(lon < -180){
          lon +=360;
          }
          while (lon > 180){
          lon -= 360;
          }





          share|improve this answer























          • signs wrong way round? Should be lon +=360 in first case.
            – JimT
            21 hours ago






          • 2




            bleeugh, coding before coffee. Thanks
            – Ian Turton
            21 hours ago






          • 2




            you can do it with only one loop while (Math.abs(lon) > 180) { lon -= Math.sign(lon) * 360 } I am not providing it as an answer though because your version actually matches the explanation, while my version is just an optimization that likely doesn't make any difference. I keep it as a comment only as a reminder that things can be done in multiple ways, some more optimized than others.
            – Andrei
            20 hours ago






          • 1




            I don't think I would ever use that one as it uses 2 function calls per loop and only one of my loops would ever execute. Probably makes no difference in this example but that's my prejudice
            – Ian Turton
            20 hours ago






          • 2




            You can't do lon %= 180?
            – Nic Hartley
            13 hours ago













          up vote
          10
          down vote



          accepted







          up vote
          10
          down vote



          accepted






          You need to repeatedly add (or subtract) 360 to your value until it lies in the range of -180 - 180. So usually a pair of loops like:



          lon = -187;
          while(lon < -180){
          lon +=360;
          }
          while (lon > 180){
          lon -= 360;
          }





          share|improve this answer














          You need to repeatedly add (or subtract) 360 to your value until it lies in the range of -180 - 180. So usually a pair of loops like:



          lon = -187;
          while(lon < -180){
          lon +=360;
          }
          while (lon > 180){
          lon -= 360;
          }






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited 21 hours ago

























          answered 21 hours ago









          Ian Turton

          46.7k546109




          46.7k546109












          • signs wrong way round? Should be lon +=360 in first case.
            – JimT
            21 hours ago






          • 2




            bleeugh, coding before coffee. Thanks
            – Ian Turton
            21 hours ago






          • 2




            you can do it with only one loop while (Math.abs(lon) > 180) { lon -= Math.sign(lon) * 360 } I am not providing it as an answer though because your version actually matches the explanation, while my version is just an optimization that likely doesn't make any difference. I keep it as a comment only as a reminder that things can be done in multiple ways, some more optimized than others.
            – Andrei
            20 hours ago






          • 1




            I don't think I would ever use that one as it uses 2 function calls per loop and only one of my loops would ever execute. Probably makes no difference in this example but that's my prejudice
            – Ian Turton
            20 hours ago






          • 2




            You can't do lon %= 180?
            – Nic Hartley
            13 hours ago


















          • signs wrong way round? Should be lon +=360 in first case.
            – JimT
            21 hours ago






          • 2




            bleeugh, coding before coffee. Thanks
            – Ian Turton
            21 hours ago






          • 2




            you can do it with only one loop while (Math.abs(lon) > 180) { lon -= Math.sign(lon) * 360 } I am not providing it as an answer though because your version actually matches the explanation, while my version is just an optimization that likely doesn't make any difference. I keep it as a comment only as a reminder that things can be done in multiple ways, some more optimized than others.
            – Andrei
            20 hours ago






          • 1




            I don't think I would ever use that one as it uses 2 function calls per loop and only one of my loops would ever execute. Probably makes no difference in this example but that's my prejudice
            – Ian Turton
            20 hours ago






          • 2




            You can't do lon %= 180?
            – Nic Hartley
            13 hours ago
















          signs wrong way round? Should be lon +=360 in first case.
          – JimT
          21 hours ago




          signs wrong way round? Should be lon +=360 in first case.
          – JimT
          21 hours ago




          2




          2




          bleeugh, coding before coffee. Thanks
          – Ian Turton
          21 hours ago




          bleeugh, coding before coffee. Thanks
          – Ian Turton
          21 hours ago




          2




          2




          you can do it with only one loop while (Math.abs(lon) > 180) { lon -= Math.sign(lon) * 360 } I am not providing it as an answer though because your version actually matches the explanation, while my version is just an optimization that likely doesn't make any difference. I keep it as a comment only as a reminder that things can be done in multiple ways, some more optimized than others.
          – Andrei
          20 hours ago




          you can do it with only one loop while (Math.abs(lon) > 180) { lon -= Math.sign(lon) * 360 } I am not providing it as an answer though because your version actually matches the explanation, while my version is just an optimization that likely doesn't make any difference. I keep it as a comment only as a reminder that things can be done in multiple ways, some more optimized than others.
          – Andrei
          20 hours ago




          1




          1




          I don't think I would ever use that one as it uses 2 function calls per loop and only one of my loops would ever execute. Probably makes no difference in this example but that's my prejudice
          – Ian Turton
          20 hours ago




          I don't think I would ever use that one as it uses 2 function calls per loop and only one of my loops would ever execute. Probably makes no difference in this example but that's my prejudice
          – Ian Turton
          20 hours ago




          2




          2




          You can't do lon %= 180?
          – Nic Hartley
          13 hours ago




          You can't do lon %= 180?
          – Nic Hartley
          13 hours ago












          up vote
          7
          down vote













          An answer that avoids conditionals and function calls:



          longitude = (longitude % 360 + 540) % 360 - 180


          I wrote a quick microbenchmark at https://jsperf.com/longitude-normalisation and the conditional code seems to be faster (in Chrome on my machine) for 'reasonable' ranges of input values. In general you probably shouldn't be worrying in advance about performance in small calculations like this, giving more weight to readability and consistency with the rest of your codebase.



          Probably more important in this case is the question of whether your code could ever come across extreme input values (1e10, Infinity etc.). If so, the looping implementation could end up running really slowly or silently hanging your program. This might occur with calculations performed near the poles, e.g. trying to pan east or west by some distance (rather than angle) from a pole could easily result in an infinite longitude.






          share|improve this answer










          New contributor




          Joe Lee-Moyet is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
          Check out our Code of Conduct.














          • 1




            Interesting. Let's race a conditional jmp against a FP divide. Hmmm I wonder.
            – Joshua
            11 hours ago






          • 1




            @Joshua You can't use a conditional jump. You have to use multiple conditional jumps, aka a loop. (Plus the loop contains floating point additional, which isn't free.) How many iterations the loop needs depends on the input. So you have to know something about the data to look at performance. If the vast majority are near the desired range and require few iterations, sure, the addition loop might be faster, but it isn't as obvious as your sarcasm suggests.
            – jpmc26
            9 hours ago








          • 1




            @jpmc26: In this case, expecting to go around the loop more than once is silly.
            – Joshua
            9 hours ago






          • 1




            There was no sarcasm. I actually don't know which way it would fall.
            – Joshua
            9 hours ago






          • 1




            @Joshua yep, I wasn't sure either :). I added more to the answer on performance (and a potential failure case of the loop code)
            – Joe Lee-Moyet
            6 hours ago















          up vote
          7
          down vote













          An answer that avoids conditionals and function calls:



          longitude = (longitude % 360 + 540) % 360 - 180


          I wrote a quick microbenchmark at https://jsperf.com/longitude-normalisation and the conditional code seems to be faster (in Chrome on my machine) for 'reasonable' ranges of input values. In general you probably shouldn't be worrying in advance about performance in small calculations like this, giving more weight to readability and consistency with the rest of your codebase.



          Probably more important in this case is the question of whether your code could ever come across extreme input values (1e10, Infinity etc.). If so, the looping implementation could end up running really slowly or silently hanging your program. This might occur with calculations performed near the poles, e.g. trying to pan east or west by some distance (rather than angle) from a pole could easily result in an infinite longitude.






          share|improve this answer










          New contributor




          Joe Lee-Moyet is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
          Check out our Code of Conduct.














          • 1




            Interesting. Let's race a conditional jmp against a FP divide. Hmmm I wonder.
            – Joshua
            11 hours ago






          • 1




            @Joshua You can't use a conditional jump. You have to use multiple conditional jumps, aka a loop. (Plus the loop contains floating point additional, which isn't free.) How many iterations the loop needs depends on the input. So you have to know something about the data to look at performance. If the vast majority are near the desired range and require few iterations, sure, the addition loop might be faster, but it isn't as obvious as your sarcasm suggests.
            – jpmc26
            9 hours ago








          • 1




            @jpmc26: In this case, expecting to go around the loop more than once is silly.
            – Joshua
            9 hours ago






          • 1




            There was no sarcasm. I actually don't know which way it would fall.
            – Joshua
            9 hours ago






          • 1




            @Joshua yep, I wasn't sure either :). I added more to the answer on performance (and a potential failure case of the loop code)
            – Joe Lee-Moyet
            6 hours ago













          up vote
          7
          down vote










          up vote
          7
          down vote









          An answer that avoids conditionals and function calls:



          longitude = (longitude % 360 + 540) % 360 - 180


          I wrote a quick microbenchmark at https://jsperf.com/longitude-normalisation and the conditional code seems to be faster (in Chrome on my machine) for 'reasonable' ranges of input values. In general you probably shouldn't be worrying in advance about performance in small calculations like this, giving more weight to readability and consistency with the rest of your codebase.



          Probably more important in this case is the question of whether your code could ever come across extreme input values (1e10, Infinity etc.). If so, the looping implementation could end up running really slowly or silently hanging your program. This might occur with calculations performed near the poles, e.g. trying to pan east or west by some distance (rather than angle) from a pole could easily result in an infinite longitude.






          share|improve this answer










          New contributor




          Joe Lee-Moyet is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
          Check out our Code of Conduct.









          An answer that avoids conditionals and function calls:



          longitude = (longitude % 360 + 540) % 360 - 180


          I wrote a quick microbenchmark at https://jsperf.com/longitude-normalisation and the conditional code seems to be faster (in Chrome on my machine) for 'reasonable' ranges of input values. In general you probably shouldn't be worrying in advance about performance in small calculations like this, giving more weight to readability and consistency with the rest of your codebase.



          Probably more important in this case is the question of whether your code could ever come across extreme input values (1e10, Infinity etc.). If so, the looping implementation could end up running really slowly or silently hanging your program. This might occur with calculations performed near the poles, e.g. trying to pan east or west by some distance (rather than angle) from a pole could easily result in an infinite longitude.







          share|improve this answer










          New contributor




          Joe Lee-Moyet is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
          Check out our Code of Conduct.









          share|improve this answer



          share|improve this answer








          edited 6 hours ago





















          New contributor




          Joe Lee-Moyet is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
          Check out our Code of Conduct.









          answered 14 hours ago









          Joe Lee-Moyet

          1713




          1713




          New contributor




          Joe Lee-Moyet is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
          Check out our Code of Conduct.





          New contributor





          Joe Lee-Moyet is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
          Check out our Code of Conduct.






          Joe Lee-Moyet is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
          Check out our Code of Conduct.








          • 1




            Interesting. Let's race a conditional jmp against a FP divide. Hmmm I wonder.
            – Joshua
            11 hours ago






          • 1




            @Joshua You can't use a conditional jump. You have to use multiple conditional jumps, aka a loop. (Plus the loop contains floating point additional, which isn't free.) How many iterations the loop needs depends on the input. So you have to know something about the data to look at performance. If the vast majority are near the desired range and require few iterations, sure, the addition loop might be faster, but it isn't as obvious as your sarcasm suggests.
            – jpmc26
            9 hours ago








          • 1




            @jpmc26: In this case, expecting to go around the loop more than once is silly.
            – Joshua
            9 hours ago






          • 1




            There was no sarcasm. I actually don't know which way it would fall.
            – Joshua
            9 hours ago






          • 1




            @Joshua yep, I wasn't sure either :). I added more to the answer on performance (and a potential failure case of the loop code)
            – Joe Lee-Moyet
            6 hours ago














          • 1




            Interesting. Let's race a conditional jmp against a FP divide. Hmmm I wonder.
            – Joshua
            11 hours ago






          • 1




            @Joshua You can't use a conditional jump. You have to use multiple conditional jumps, aka a loop. (Plus the loop contains floating point additional, which isn't free.) How many iterations the loop needs depends on the input. So you have to know something about the data to look at performance. If the vast majority are near the desired range and require few iterations, sure, the addition loop might be faster, but it isn't as obvious as your sarcasm suggests.
            – jpmc26
            9 hours ago








          • 1




            @jpmc26: In this case, expecting to go around the loop more than once is silly.
            – Joshua
            9 hours ago






          • 1




            There was no sarcasm. I actually don't know which way it would fall.
            – Joshua
            9 hours ago






          • 1




            @Joshua yep, I wasn't sure either :). I added more to the answer on performance (and a potential failure case of the loop code)
            – Joe Lee-Moyet
            6 hours ago








          1




          1




          Interesting. Let's race a conditional jmp against a FP divide. Hmmm I wonder.
          – Joshua
          11 hours ago




          Interesting. Let's race a conditional jmp against a FP divide. Hmmm I wonder.
          – Joshua
          11 hours ago




          1




          1




          @Joshua You can't use a conditional jump. You have to use multiple conditional jumps, aka a loop. (Plus the loop contains floating point additional, which isn't free.) How many iterations the loop needs depends on the input. So you have to know something about the data to look at performance. If the vast majority are near the desired range and require few iterations, sure, the addition loop might be faster, but it isn't as obvious as your sarcasm suggests.
          – jpmc26
          9 hours ago






          @Joshua You can't use a conditional jump. You have to use multiple conditional jumps, aka a loop. (Plus the loop contains floating point additional, which isn't free.) How many iterations the loop needs depends on the input. So you have to know something about the data to look at performance. If the vast majority are near the desired range and require few iterations, sure, the addition loop might be faster, but it isn't as obvious as your sarcasm suggests.
          – jpmc26
          9 hours ago






          1




          1




          @jpmc26: In this case, expecting to go around the loop more than once is silly.
          – Joshua
          9 hours ago




          @jpmc26: In this case, expecting to go around the loop more than once is silly.
          – Joshua
          9 hours ago




          1




          1




          There was no sarcasm. I actually don't know which way it would fall.
          – Joshua
          9 hours ago




          There was no sarcasm. I actually don't know which way it would fall.
          – Joshua
          9 hours ago




          1




          1




          @Joshua yep, I wasn't sure either :). I added more to the answer on performance (and a potential failure case of the loop code)
          – Joe Lee-Moyet
          6 hours ago




          @Joshua yep, I wasn't sure either :). I added more to the answer on performance (and a potential failure case of the loop code)
          – Joe Lee-Moyet
          6 hours ago










          up vote
          3
          down vote













          One-liner:



          normalized = remainder(longitude, 360);


          Explanation: You want to know what remains after you disregard full rotations (360°).



          This process is called normalizing.



          Example (cpp.sh)






          share|improve this answer










          New contributor




          Peter Paff is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
          Check out our Code of Conduct.














          • 1




            Wouldn't this result in a [0, 360) value, not [-180, 180] as Shadrix requested?
            – The Guy with The Hat
            15 hours ago










          • @TheGuywithTheHat Check this example: cpp.sh/7uy2v
            – Peter Paff
            14 hours ago










          • Ah, didn't know this was C++. In Shadrix's context of JavaScript, I interpreted remainder as modulus. Modulus in JS would result in [0, 360).
            – The Guy with The Hat
            14 hours ago












          • @TheGuywithTheHat subtract 180 from the result and done.
            – Peter Paff
            14 hours ago










          • I don't think that would work. You would need to subtract 360 iff result > 180. Another problem I just realized with JavaScript is that modulo is symmetrical across 0, e.g. -1 % 3 is -1, not 2 as would be necessary for it to work here. remainder is a great C++ solution, but unfortunately there's just no function/operator in JS that's similar enough to be useful.
            – The Guy with The Hat
            13 hours ago















          up vote
          3
          down vote













          One-liner:



          normalized = remainder(longitude, 360);


          Explanation: You want to know what remains after you disregard full rotations (360°).



          This process is called normalizing.



          Example (cpp.sh)






          share|improve this answer










          New contributor




          Peter Paff is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
          Check out our Code of Conduct.














          • 1




            Wouldn't this result in a [0, 360) value, not [-180, 180] as Shadrix requested?
            – The Guy with The Hat
            15 hours ago










          • @TheGuywithTheHat Check this example: cpp.sh/7uy2v
            – Peter Paff
            14 hours ago










          • Ah, didn't know this was C++. In Shadrix's context of JavaScript, I interpreted remainder as modulus. Modulus in JS would result in [0, 360).
            – The Guy with The Hat
            14 hours ago












          • @TheGuywithTheHat subtract 180 from the result and done.
            – Peter Paff
            14 hours ago










          • I don't think that would work. You would need to subtract 360 iff result > 180. Another problem I just realized with JavaScript is that modulo is symmetrical across 0, e.g. -1 % 3 is -1, not 2 as would be necessary for it to work here. remainder is a great C++ solution, but unfortunately there's just no function/operator in JS that's similar enough to be useful.
            – The Guy with The Hat
            13 hours ago













          up vote
          3
          down vote










          up vote
          3
          down vote









          One-liner:



          normalized = remainder(longitude, 360);


          Explanation: You want to know what remains after you disregard full rotations (360°).



          This process is called normalizing.



          Example (cpp.sh)






          share|improve this answer










          New contributor




          Peter Paff is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
          Check out our Code of Conduct.









          One-liner:



          normalized = remainder(longitude, 360);


          Explanation: You want to know what remains after you disregard full rotations (360°).



          This process is called normalizing.



          Example (cpp.sh)







          share|improve this answer










          New contributor




          Peter Paff is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
          Check out our Code of Conduct.









          share|improve this answer



          share|improve this answer








          edited 14 hours ago





















          New contributor




          Peter Paff is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
          Check out our Code of Conduct.









          answered 16 hours ago









          Peter Paff

          312




          312




          New contributor




          Peter Paff is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
          Check out our Code of Conduct.





          New contributor





          Peter Paff is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
          Check out our Code of Conduct.






          Peter Paff is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
          Check out our Code of Conduct.








          • 1




            Wouldn't this result in a [0, 360) value, not [-180, 180] as Shadrix requested?
            – The Guy with The Hat
            15 hours ago










          • @TheGuywithTheHat Check this example: cpp.sh/7uy2v
            – Peter Paff
            14 hours ago










          • Ah, didn't know this was C++. In Shadrix's context of JavaScript, I interpreted remainder as modulus. Modulus in JS would result in [0, 360).
            – The Guy with The Hat
            14 hours ago












          • @TheGuywithTheHat subtract 180 from the result and done.
            – Peter Paff
            14 hours ago










          • I don't think that would work. You would need to subtract 360 iff result > 180. Another problem I just realized with JavaScript is that modulo is symmetrical across 0, e.g. -1 % 3 is -1, not 2 as would be necessary for it to work here. remainder is a great C++ solution, but unfortunately there's just no function/operator in JS that's similar enough to be useful.
            – The Guy with The Hat
            13 hours ago














          • 1




            Wouldn't this result in a [0, 360) value, not [-180, 180] as Shadrix requested?
            – The Guy with The Hat
            15 hours ago










          • @TheGuywithTheHat Check this example: cpp.sh/7uy2v
            – Peter Paff
            14 hours ago










          • Ah, didn't know this was C++. In Shadrix's context of JavaScript, I interpreted remainder as modulus. Modulus in JS would result in [0, 360).
            – The Guy with The Hat
            14 hours ago












          • @TheGuywithTheHat subtract 180 from the result and done.
            – Peter Paff
            14 hours ago










          • I don't think that would work. You would need to subtract 360 iff result > 180. Another problem I just realized with JavaScript is that modulo is symmetrical across 0, e.g. -1 % 3 is -1, not 2 as would be necessary for it to work here. remainder is a great C++ solution, but unfortunately there's just no function/operator in JS that's similar enough to be useful.
            – The Guy with The Hat
            13 hours ago








          1




          1




          Wouldn't this result in a [0, 360) value, not [-180, 180] as Shadrix requested?
          – The Guy with The Hat
          15 hours ago




          Wouldn't this result in a [0, 360) value, not [-180, 180] as Shadrix requested?
          – The Guy with The Hat
          15 hours ago












          @TheGuywithTheHat Check this example: cpp.sh/7uy2v
          – Peter Paff
          14 hours ago




          @TheGuywithTheHat Check this example: cpp.sh/7uy2v
          – Peter Paff
          14 hours ago












          Ah, didn't know this was C++. In Shadrix's context of JavaScript, I interpreted remainder as modulus. Modulus in JS would result in [0, 360).
          – The Guy with The Hat
          14 hours ago






          Ah, didn't know this was C++. In Shadrix's context of JavaScript, I interpreted remainder as modulus. Modulus in JS would result in [0, 360).
          – The Guy with The Hat
          14 hours ago














          @TheGuywithTheHat subtract 180 from the result and done.
          – Peter Paff
          14 hours ago




          @TheGuywithTheHat subtract 180 from the result and done.
          – Peter Paff
          14 hours ago












          I don't think that would work. You would need to subtract 360 iff result > 180. Another problem I just realized with JavaScript is that modulo is symmetrical across 0, e.g. -1 % 3 is -1, not 2 as would be necessary for it to work here. remainder is a great C++ solution, but unfortunately there's just no function/operator in JS that's similar enough to be useful.
          – The Guy with The Hat
          13 hours ago




          I don't think that would work. You would need to subtract 360 iff result > 180. Another problem I just realized with JavaScript is that modulo is symmetrical across 0, e.g. -1 % 3 is -1, not 2 as would be necessary for it to work here. remainder is a great C++ solution, but unfortunately there's just no function/operator in JS that's similar enough to be useful.
          – The Guy with The Hat
          13 hours ago










          up vote
          0
          down vote













          Another option: longitude = atan2(cos(long), sin(long))






          share|improve this answer

















          • 1




            This doesn't seem like a good idea. It's very hard to understand, computationally expensive and potentially subject to rounding errors.
            – David Richerby
            12 hours ago















          up vote
          0
          down vote













          Another option: longitude = atan2(cos(long), sin(long))






          share|improve this answer

















          • 1




            This doesn't seem like a good idea. It's very hard to understand, computationally expensive and potentially subject to rounding errors.
            – David Richerby
            12 hours ago













          up vote
          0
          down vote










          up vote
          0
          down vote









          Another option: longitude = atan2(cos(long), sin(long))






          share|improve this answer












          Another option: longitude = atan2(cos(long), sin(long))







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered 12 hours ago









          Andres

          163211




          163211








          • 1




            This doesn't seem like a good idea. It's very hard to understand, computationally expensive and potentially subject to rounding errors.
            – David Richerby
            12 hours ago














          • 1




            This doesn't seem like a good idea. It's very hard to understand, computationally expensive and potentially subject to rounding errors.
            – David Richerby
            12 hours ago








          1




          1




          This doesn't seem like a good idea. It's very hard to understand, computationally expensive and potentially subject to rounding errors.
          – David Richerby
          12 hours ago




          This doesn't seem like a good idea. It's very hard to understand, computationally expensive and potentially subject to rounding errors.
          – David Richerby
          12 hours ago










          up vote
          0
          down vote













          If the programming language you're using supports the % (mod) operator on floating point numbers (like Python and Ruby), I'd recommend using that. Otherwise, some other languages (like C and C++) allow you to use fmod().



          (Whichever mod operator you use, make sure ahead of time that it will do mod operations on floating-point numbers. Otherwise you'll get a nasty surprise later when many of your lat/lon points are not correct.)



          Use it like this:



          # Put the longitude in the range of [0,360):
          longitude %= 360

          # Put the longitude in the range of [-180,180):
          if longitude >= 180:
          longitude -= 360


          If you'd prefer to do it all in one line:



          # Put the longitude in the range of [-180,180):
          longitude = (longitude + 180) % 360 - 180


          These approaches have no loops, so they'll normalize longitude values without needing to repeatedly add or subtract, no matter how many times your observation has circled around the earth.



          Edit:



          Hmmm... I just noticed that Javascript doesn't seem to handle % with negative values like I thought it would.



          In that case, try this one-liner:



          longitude = (longitude + 36180) % 360 - 180


          The 36180 we're adding is 36,000 + 180. The 36,000 is to move a negative value into the positive domain, and the 180 is to shift it over so that when it is modded by 360, it'll be in the range of [0,360). The - 180 part shifts it back to the range of [-180,180).



          Here's another one-liner, one that doesn't rely on 36,000 being big enough:



          longitude = (longitude % 360 + 360 + 180) % 360 - 180


          The longitude % 360 + 360 part will ensure the value stays in the positive domain when it's later modded by 360. The + 180 part shifts it over so that when it later gets 180 subtracted from it (with - 180), it'll be in the desired range of [-180,180).






          share|improve this answer










          New contributor




          J-L is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
          Check out our Code of Conduct.


















          • Note: C,C++ fmod(longitude, 360) --> (-360.0 ... +360.0) and ilongitude % 360 --> [-359 ... +359].
            – chux
            1 hour ago

















          up vote
          0
          down vote













          If the programming language you're using supports the % (mod) operator on floating point numbers (like Python and Ruby), I'd recommend using that. Otherwise, some other languages (like C and C++) allow you to use fmod().



          (Whichever mod operator you use, make sure ahead of time that it will do mod operations on floating-point numbers. Otherwise you'll get a nasty surprise later when many of your lat/lon points are not correct.)



          Use it like this:



          # Put the longitude in the range of [0,360):
          longitude %= 360

          # Put the longitude in the range of [-180,180):
          if longitude >= 180:
          longitude -= 360


          If you'd prefer to do it all in one line:



          # Put the longitude in the range of [-180,180):
          longitude = (longitude + 180) % 360 - 180


          These approaches have no loops, so they'll normalize longitude values without needing to repeatedly add or subtract, no matter how many times your observation has circled around the earth.



          Edit:



          Hmmm... I just noticed that Javascript doesn't seem to handle % with negative values like I thought it would.



          In that case, try this one-liner:



          longitude = (longitude + 36180) % 360 - 180


          The 36180 we're adding is 36,000 + 180. The 36,000 is to move a negative value into the positive domain, and the 180 is to shift it over so that when it is modded by 360, it'll be in the range of [0,360). The - 180 part shifts it back to the range of [-180,180).



          Here's another one-liner, one that doesn't rely on 36,000 being big enough:



          longitude = (longitude % 360 + 360 + 180) % 360 - 180


          The longitude % 360 + 360 part will ensure the value stays in the positive domain when it's later modded by 360. The + 180 part shifts it over so that when it later gets 180 subtracted from it (with - 180), it'll be in the desired range of [-180,180).






          share|improve this answer










          New contributor




          J-L is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
          Check out our Code of Conduct.


















          • Note: C,C++ fmod(longitude, 360) --> (-360.0 ... +360.0) and ilongitude % 360 --> [-359 ... +359].
            – chux
            1 hour ago















          up vote
          0
          down vote










          up vote
          0
          down vote









          If the programming language you're using supports the % (mod) operator on floating point numbers (like Python and Ruby), I'd recommend using that. Otherwise, some other languages (like C and C++) allow you to use fmod().



          (Whichever mod operator you use, make sure ahead of time that it will do mod operations on floating-point numbers. Otherwise you'll get a nasty surprise later when many of your lat/lon points are not correct.)



          Use it like this:



          # Put the longitude in the range of [0,360):
          longitude %= 360

          # Put the longitude in the range of [-180,180):
          if longitude >= 180:
          longitude -= 360


          If you'd prefer to do it all in one line:



          # Put the longitude in the range of [-180,180):
          longitude = (longitude + 180) % 360 - 180


          These approaches have no loops, so they'll normalize longitude values without needing to repeatedly add or subtract, no matter how many times your observation has circled around the earth.



          Edit:



          Hmmm... I just noticed that Javascript doesn't seem to handle % with negative values like I thought it would.



          In that case, try this one-liner:



          longitude = (longitude + 36180) % 360 - 180


          The 36180 we're adding is 36,000 + 180. The 36,000 is to move a negative value into the positive domain, and the 180 is to shift it over so that when it is modded by 360, it'll be in the range of [0,360). The - 180 part shifts it back to the range of [-180,180).



          Here's another one-liner, one that doesn't rely on 36,000 being big enough:



          longitude = (longitude % 360 + 360 + 180) % 360 - 180


          The longitude % 360 + 360 part will ensure the value stays in the positive domain when it's later modded by 360. The + 180 part shifts it over so that when it later gets 180 subtracted from it (with - 180), it'll be in the desired range of [-180,180).






          share|improve this answer










          New contributor




          J-L is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
          Check out our Code of Conduct.









          If the programming language you're using supports the % (mod) operator on floating point numbers (like Python and Ruby), I'd recommend using that. Otherwise, some other languages (like C and C++) allow you to use fmod().



          (Whichever mod operator you use, make sure ahead of time that it will do mod operations on floating-point numbers. Otherwise you'll get a nasty surprise later when many of your lat/lon points are not correct.)



          Use it like this:



          # Put the longitude in the range of [0,360):
          longitude %= 360

          # Put the longitude in the range of [-180,180):
          if longitude >= 180:
          longitude -= 360


          If you'd prefer to do it all in one line:



          # Put the longitude in the range of [-180,180):
          longitude = (longitude + 180) % 360 - 180


          These approaches have no loops, so they'll normalize longitude values without needing to repeatedly add or subtract, no matter how many times your observation has circled around the earth.



          Edit:



          Hmmm... I just noticed that Javascript doesn't seem to handle % with negative values like I thought it would.



          In that case, try this one-liner:



          longitude = (longitude + 36180) % 360 - 180


          The 36180 we're adding is 36,000 + 180. The 36,000 is to move a negative value into the positive domain, and the 180 is to shift it over so that when it is modded by 360, it'll be in the range of [0,360). The - 180 part shifts it back to the range of [-180,180).



          Here's another one-liner, one that doesn't rely on 36,000 being big enough:



          longitude = (longitude % 360 + 360 + 180) % 360 - 180


          The longitude % 360 + 360 part will ensure the value stays in the positive domain when it's later modded by 360. The + 180 part shifts it over so that when it later gets 180 subtracted from it (with - 180), it'll be in the desired range of [-180,180).







          share|improve this answer










          New contributor




          J-L is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
          Check out our Code of Conduct.









          share|improve this answer



          share|improve this answer








          edited 6 hours ago





















          New contributor




          J-L is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
          Check out our Code of Conduct.









          answered 11 hours ago









          J-L

          1011




          1011




          New contributor




          J-L is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
          Check out our Code of Conduct.





          New contributor





          J-L is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
          Check out our Code of Conduct.






          J-L is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
          Check out our Code of Conduct.












          • Note: C,C++ fmod(longitude, 360) --> (-360.0 ... +360.0) and ilongitude % 360 --> [-359 ... +359].
            – chux
            1 hour ago




















          • Note: C,C++ fmod(longitude, 360) --> (-360.0 ... +360.0) and ilongitude % 360 --> [-359 ... +359].
            – chux
            1 hour ago


















          Note: C,C++ fmod(longitude, 360) --> (-360.0 ... +360.0) and ilongitude % 360 --> [-359 ... +359].
          – chux
          1 hour ago






          Note: C,C++ fmod(longitude, 360) --> (-360.0 ... +360.0) and ilongitude % 360 --> [-359 ... +359].
          – chux
          1 hour ago












          Shadrix is a new contributor. Be nice, and check out our Code of Conduct.










           

          draft saved


          draft discarded


















          Shadrix is a new contributor. Be nice, and check out our Code of Conduct.













          Shadrix is a new contributor. Be nice, and check out our Code of Conduct.












          Shadrix is a new contributor. Be nice, and check out our Code of Conduct.















           


          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fgis.stackexchange.com%2fquestions%2f303300%2fcalculating-correct-longitude-when-its-over-180%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          404 Error Contact Form 7 ajax form submitting

          How to know if a Active Directory user can login interactively

          TypeError: fit_transform() missing 1 required positional argument: 'X'