convert-gps 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. #!/usr/bin/python
  2. #
  3. # Copyright (c) 2019 Clementine Computing LLC.
  4. #
  5. # This file is part of PopuFare.
  6. #
  7. # PopuFare is free software: you can redistribute it and/or modify
  8. # it under the terms of the GNU Affero General Public License as published by
  9. # the Free Software Foundation, either version 3 of the License, or
  10. # (at your option) any later version.
  11. #
  12. # PopuFare is distributed in the hope that it will be useful,
  13. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. # GNU Affero General Public License for more details.
  16. #
  17. # You should have received a copy of the GNU Affero General Public License
  18. # along with PopuFare. If not, see <https://www.gnu.org/licenses/>.
  19. #
  20. # Convert from/to different formats of GPS representations
  21. #
  22. # DD - decimal degree
  23. # DMS - degree/minut/second format
  24. # DMM - degree/decimal minute format
  25. #
  26. # 42.445512 -76.50726
  27. # 42.444988 -76.506852
  28. # 42.4444 -76.506444
  29. # DD example: 42.445512
  30. # DMS example: 42 3 3
  31. # DMM example: 42 3.1
  32. import sys
  33. def print_usage(fp):
  34. fp.write("\nusage:\n\n")
  35. fp.write(" convert-gps [dd|dms|dmm|dmmc][-(dd|dms|dmm|dmmc)] <gps_coord>\n\n")
  36. infmt = ""
  37. outfmt = "dmmc"
  38. coord = ""
  39. def is_float(x):
  40. f = False
  41. try:
  42. float(x)
  43. f = True
  44. except ValueError:
  45. f = False
  46. return f
  47. def guess_dd_dmmc(coord):
  48. if not is_float(coord): return ""
  49. tok = coord.split(".")
  50. if len(tok) > 2 or len(tok)==0: return ""
  51. tok_i = tok[0].split("-")
  52. #print ">>", len(tok_i), tok_i[-1], len(tok_i[-1])
  53. if len(tok_i[-1]) >= 3: return "dmmc"
  54. return "dd"
  55. if (len(sys.argv) < 2):
  56. print_usage(sys.stderr)
  57. sys.exit(-1)
  58. start_idx = 1
  59. if not is_float(sys.argv[1]):
  60. tok=sys.argv[1].split("-")
  61. if len(tok)==1:
  62. outfmt = tok[0]
  63. else:
  64. infmt = tok[0]
  65. outfmt = tok[1]
  66. start_idx = 2
  67. if ((outfmt != "dd") and (outfmt != "DD") and
  68. (outfmt != "dms") and (outfmt != "DMS") and
  69. (outfmt != "dmm") and (outfmt != "DMM") and
  70. (outfmt != "dmmc") and (outfmt != "DMMC")):
  71. sys.stderr.write("output format must be one of dd, dms, dmm, dmmc\n")
  72. print_usage(sys.stderr)
  73. sys.exit(-1)
  74. coord = []
  75. for val in sys.argv[start_idx:]:
  76. coord.append(val)
  77. if len(coord) == 1:
  78. if len(infmt) == 0:
  79. infmt = guess_dd_dmmc(coord[0])
  80. elif len(coord) == 2:
  81. if is_float(coord[0]) and is_float(coord[1]):
  82. infmt = "dmm"
  83. elif len(coord) == 3:
  84. if is_float(coord[0]) and is_float(coord[1]) and is_float(coord[2]):
  85. infmt = "dms"
  86. if ((infmt != "dd") and (infmt != "DD") and
  87. (infmt != "dms") and (infmt != "DMS") and
  88. (infmt != "dmm") and (infmt != "DMM") and
  89. (infmt != "dmmc") and (infmt != "DMMC")):
  90. sys.stderr.write("input format must be one of dd, dms, dmm, dmmc\n")
  91. print_usage(sys.stderr)
  92. sys.exit(-1)
  93. out_coord_dd = 0.0
  94. if infmt == "dd":
  95. out_coord_dd = float(coord[0])
  96. elif infmt == "dmm":
  97. out_coord_dd = float(coord[0]) + (float(coord[1])/60.0)
  98. elif infmt == "dms":
  99. out_coord_dd = float(coord[0]) + (float(coord[1])/60.0) + (float(coord[2])/(60.0*60.0))
  100. elif infmt == "dmmc":
  101. x = coord[0]
  102. is_neg = False
  103. if x[0] == '-':
  104. is_neg = True
  105. x = x[1:]
  106. tok = x.split(".")
  107. min_int_part = 0.0
  108. if len(tok[0][-2:])> 0:
  109. min_int_part = float(tok[0][-2:])
  110. min_rem_part = 0.0
  111. if (len(tok)>1):
  112. min_rem_part = float("0." + tok[1])
  113. ipart = 0.0
  114. if (len(tok[0][-4:-2])>0):
  115. ipart = float(tok[0][-4:-2])
  116. out_coord_dd = ipart + ((min_int_part + min_rem_part)/60.0)
  117. if is_neg: out_coord_dd *= -1.0
  118. out_coord = []
  119. if outfmt == "dd":
  120. out_coord = [str(out_coord_dd)]
  121. elif outfmt == "dms":
  122. x0 = float(int(out_coord_dd))
  123. x1 = float(int((out_coord_dd-x0)*60.0))
  124. x2 = float(int( ((out_coord_dd-x0)*60.0) - ((x1-60.0)/60.0) ))
  125. out_coord.append(str(x0))
  126. out_coord.append(str(x1))
  127. out_coord.append(str(x2))
  128. elif outfmt == "dmm":
  129. x0 = float(int(out_coord_dd))
  130. x1 = float(int((out_coord_dd-x0)*60.0))
  131. out_coord.append(str(x0))
  132. out_coord.append(str(x1))
  133. elif outfmt == "dmmc":
  134. x0 = float(int(out_coord_dd))
  135. x1 = abs(float((out_coord_dd-x0)*60.0))
  136. out_coord.append(str(int(x0)) + str(x1))
  137. #print infmt, outfmt, coord, "-->", out_coord_dd, " ".join(out_coord)
  138. print " ".join(out_coord)