utils.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. # -*- coding: utf-8 -*-
  2. #!/usr/bin/env python
  3. import calendar
  4. import datetime
  5. import math
  6. import numbers
  7. from django.conf import settings
  8. from pandas import date_range
  9. class CoordinateTrans(object):
  10. """
  11. 坐标系转换
  12. """
  13. def __init__(self, lng=0.0, lat=0.0):
  14. """
  15. :param lng: 经度
  16. :param lat: 维度
  17. """
  18. self._x_pi = 3.14159265358979324 * 3000.0 / 180.0
  19. self._lng = lng
  20. self._lat = lat
  21. def bd09_to_gcj02(self):
  22. """
  23. 百度坐标系到google坐标系的经纬度转换
  24. :return:
  25. """
  26. if self._lng == 0.0 or self._lat == 0.0:
  27. return self._lng, self._lat
  28. x = self._lng - 0.0065
  29. y = self._lat - 0.006
  30. z = math.sqrt(x * x + y * y) - 0.00002 * math.sin(y * self._x_pi)
  31. theta = math.atan2(y, x) - 0.000003 * math.cos(x * self._x_pi)
  32. gg_lng = z * math.cos(theta)
  33. gg_lat = z * math.sin(theta)
  34. return [gg_lng, gg_lat]
  35. def gcj02_to_bd09(self):
  36. """
  37. 高德/谷歌 坐标系 转百度
  38. :return:
  39. """
  40. if self._lng == 0.0 or self._lat == 0.0:
  41. return self._lng, self._lat
  42. z = math.sqrt(self._lng * self._lng + self._lat * self._lat) + 0.00002 * math.sin(self._lat * self._x_pi)
  43. theta = math.atan2(self._lat, self._lng) + 0.000003 * math.cos(self._lng * self._x_pi)
  44. bd_lng = z * math.cos(theta) + 0.0065
  45. bd_lat = z * math.sin(theta) + 0.006
  46. return [bd_lng, bd_lat]
  47. def __call__(self, lng, lat, _type="b_to_g"):
  48. """
  49. :param lng:
  50. :param lat:
  51. :param _type: b_to_g 百度转高德 g_to_b 高德转百度
  52. :return:
  53. """
  54. self._lng = lng
  55. self._lat = lat
  56. if _type == "b_to_g":
  57. return self.bd09_to_gcj02()
  58. elif _type == "g_to_b":
  59. return self.gcj02_to_bd09()
  60. else:
  61. pass
  62. coordinateHandler = CoordinateTrans()
  63. class IntToHex(object):
  64. """
  65. 数字转换16进制字符串
  66. """
  67. def __init__(self):
  68. self._number = None
  69. def _add_trans_number(self, number):
  70. if isinstance(number, numbers.Integral):
  71. self._number = number
  72. elif isinstance(number, str) and number.isdigit():
  73. self._number = int(number)
  74. else:
  75. raise TypeError("type of number must in <Integral,str>")
  76. @staticmethod
  77. def _reverse_hex(h):
  78. if not len(h):
  79. return ""
  80. return h[-2:] + IntToHex._reverse_hex(h[:-2])
  81. def __call__(self, number, lens=4, reverse=False):
  82. """
  83. :param number: 带转换的数字
  84. :type number: int
  85. :param lens: 转换后的长度
  86. :type lens: int
  87. :param reverse: 是否高低位互换
  88. :type reverse: bool
  89. :return:
  90. :rtype: str
  91. """
  92. if not isinstance(lens, numbers.Integral):
  93. raise TypeError("type of lens must be Integral")
  94. self._add_trans_number(number)
  95. formatStr = "{:0>%sX}" % lens
  96. numberHex = formatStr.format(self._number)
  97. if reverse:
  98. return IntToHex._reverse_hex(numberHex)
  99. return numberHex
  100. int_to_hex = IntToHex()
  101. def get_start_and_end_by_month(monthStr):
  102. # type:(str) -> (str, str)
  103. """根据月份获取 当月月初和月末"""
  104. year, month = map(lambda x: int(x), monthStr.split("-"))
  105. firstWeekDay, lastDay = calendar.monthrange(year, month)
  106. startTime = datetime.date(year, month, 1).strftime("%Y-%m-%d")
  107. endTime = datetime.date(year, month, lastDay).strftime("%Y-%m-%d")
  108. return startTime, endTime
  109. def get_start_and_end_by_year(yearStr):
  110. """
  111. 获取年初 和年尾
  112. :param yearStr:
  113. :return:
  114. """
  115. return "{}-01-01".format(yearStr), "{}-12-31".format(yearStr)
  116. def get_date_range(st, et, freq='D', reverse = True):
  117. if reverse:
  118. return list(reversed(date_range(st, et, freq=freq).tolist()))
  119. else:
  120. return list(date_range(st, et, freq = freq).tolist())
  121. def get_test_point(domain, key):
  122. import os
  123. return os.environ.get('test_{}_{}'.format(domain, key), None)
  124. def support_test_point(point):
  125. if not settings.DEBUG:
  126. return False
  127. import os
  128. test_point = os.environ.get(point, None)
  129. if test_point == 'yes':
  130. return True
  131. else:
  132. return False