bmap.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397
  1. import { requestRaw } from './network'
  2. import { env } from '../static/config'
  3. let navigator_id
  4. let geolocation
  5. // #ifdef H5
  6. geolocation=navigator.geolocation
  7. // #endif
  8. // #ifdef APP-PLUS
  9. geolocation=plus.geolocation
  10. // #endif
  11. export function getPosition (callback, start) {
  12. function returnPoint(longitude,latitude){
  13. convertPoint(longitude, latitude).then(result=>{
  14. if(result.status==0){
  15. let res = { code: 10000, message: '', result: { lng: result.result[0].x, lat: result.result[0].y } }
  16. callback(res)
  17. }else{
  18. let res = { code: 10001, message: '坐标转换失败', result: '' }
  19. callback(res)
  20. }
  21. }).catch(error=>{
  22. callback({ code: 10001, message: '调用坐标转换接口失败', result: '' })
  23. })
  24. }
  25. // #ifndef MP-WEIXIN
  26. if (geolocation) {
  27. var func = start ? 'getCurrentPosition' : 'watchPosition'
  28. let temp = geolocation[func](function (position) {
  29. returnPoint(position.coords.longitude,position.coords.latitude)
  30. }, function (error) {
  31. let message = ''
  32. switch (error.code) {
  33. case error.PERMISSION_DENIED:
  34. message = '定位请求拒绝'
  35. break
  36. case error.POSITION_UNAVAILABLE:
  37. message = '定位获取失败'
  38. break
  39. case error.TIMEOUT:
  40. message = '定位超时'
  41. break
  42. default:
  43. message = '未知错误'
  44. break
  45. }
  46. let res = { code: 10001, message: message, result: '' }
  47. callback(res)
  48. },{
  49. // 指示浏览器获取高精度的位置,默认为false
  50. enableHighAcuracy: true,
  51. // 指定获取地理位置的超时时间,默认不限时,单位为毫秒
  52. timeout: 5000,
  53. // 最长有效期,在重复获取地理位置时,此参数指定多久再次获取位置。
  54. maximumAge: 1000
  55. })
  56. if (!start) {
  57. navigator_id = temp
  58. }
  59. } else {
  60. let res = { code: 10001, message: '定位不支持', result: '' }
  61. callback(res)
  62. }
  63. // #endif
  64. // #ifdef MP-WEIXIN
  65. if(start){
  66. wx.getLocation({
  67. isHighAccuracy:true,
  68. highAccuracyExpireTime:5000,
  69. success:(res)=>{
  70. returnPoint(res.longitude,res.latitude)
  71. },
  72. fail:(error)=>{
  73. let res = { code: 10001, message: error.errMsg, result: '' }
  74. callback(res)
  75. }
  76. })
  77. }else{
  78. wx.startLocationUpdate()
  79. wx.onLocationChange(res=>{
  80. returnPoint(res.longitude,res.latitude)
  81. })
  82. }
  83. // #endif
  84. }
  85. export function addMap (container, callleft, callright, calltop, calldown) {
  86. let _bmap = new BMap.Map(container)
  87. var zoomCtrl = new BMap.ZoomControl({ anchor: BMAP_ANCHOR_BOTTOM_RIGHT, offset: new BMap.Size(20, 20) })
  88. _bmap.addControl(zoomCtrl)
  89. // 创建控件
  90. function PanLeftControl () {
  91. this.defaultAnchor = BMAP_ANCHOR_TOP_LEFT
  92. this.defaultOffset = new BMap.Size(10, 10)
  93. }
  94. PanLeftControl.prototype = new BMap.Control()
  95. PanLeftControl.prototype.initialize = function (map) {
  96. var div = document.createElement('div')
  97. div.className = 'bmap-pan-control pan-left iconfont icon-arrow-down'
  98. div.onclick = function (e) {
  99. map.panBy(100, 0)
  100. if (typeof (callleft) === 'function') {
  101. callleft()
  102. }
  103. }
  104. map.getContainer().appendChild(div)
  105. return div
  106. }
  107. var panLeftCtrl = new PanLeftControl()
  108. // 添加到地图当中
  109. _bmap.addControl(panLeftCtrl)
  110. // 创建控件
  111. function PanRightControl () {
  112. this.defaultAnchor = BMAP_ANCHOR_TOP_RIGHT
  113. this.defaultOffset = new BMap.Size(10, 10)
  114. }
  115. PanRightControl.prototype = new BMap.Control()
  116. PanRightControl.prototype.initialize = function (map) {
  117. var div = document.createElement('div')
  118. div.className = 'bmap-pan-control pan-right iconfont icon-arrow-down'
  119. div.onclick = function (e) {
  120. map.panBy(-100, 0)
  121. if (typeof (callright) === 'function') {
  122. callright()
  123. }
  124. }
  125. map.getContainer().appendChild(div)
  126. return div
  127. }
  128. var panRightCtrl = new PanRightControl()
  129. // 添加到地图当中
  130. _bmap.addControl(panRightCtrl)
  131. // 创建控件
  132. function PanTopControl () {
  133. this.defaultAnchor = BMAP_ANCHOR_TOP_LEFT
  134. this.defaultOffset = new BMap.Size(10, 10)
  135. }
  136. PanTopControl.prototype = new BMap.Control()
  137. PanTopControl.prototype.initialize = function (map) {
  138. var div = document.createElement('div')
  139. div.className = 'bmap-pan-control pan-top iconfont icon-arrow-down'
  140. div.onclick = function (e) {
  141. map.panBy(0, 100)
  142. if (typeof (calltop) === 'function') {
  143. calltop()
  144. }
  145. }
  146. map.getContainer().appendChild(div)
  147. return div
  148. }
  149. var panTopCtrl = new PanTopControl()
  150. // 添加到地图当中
  151. _bmap.addControl(panTopCtrl)
  152. // 创建控件
  153. function PanBottomControl () {
  154. this.defaultAnchor = BMAP_ANCHOR_BOTTOM_LEFT
  155. this.defaultOffset = new BMap.Size(10, 10)
  156. }
  157. PanBottomControl.prototype = new BMap.Control()
  158. PanBottomControl.prototype.initialize = function (map) {
  159. var div = document.createElement('div')
  160. div.className = 'bmap-pan-control pan-bottom iconfont icon-arrow-down'
  161. div.onclick = function (e) {
  162. map.panBy(0, -100)
  163. if (typeof (calldown) === 'function') {
  164. calldown()
  165. }
  166. }
  167. map.getContainer().appendChild(div)
  168. return div
  169. }
  170. var panBottomCtrl = new PanBottomControl()
  171. // 添加到地图当中
  172. _bmap.addControl(panBottomCtrl)
  173. _bmap.disableDoubleClickZoom()
  174. _bmap.disableDragging()
  175. return _bmap
  176. }
  177. export function addMarker (info, map) { // 给地图添加标记
  178. let lng = info.lng
  179. let lat = info.lat
  180. let text = info.text
  181. let color = info.color
  182. let marker
  183. let point = new BMap.Point(lng, lat)
  184. marker = new BMap.Marker(point)
  185. marker.initialize = function (map) {
  186. var div = document.createElement('div')
  187. div.style.position = 'absolute'
  188. div.style.width = '45px'
  189. div.style.height = '45px'
  190. div.style.lineHeight = '45px'
  191. div.style.fontSize = '40px'
  192. div.style.textAlign = 'center'
  193. div.style.color = color
  194. div.className = 'iconfont icon-dingwei'
  195. div.innerHTML = '<b style="font-size:18px;position:absolute;top:0;left:0px;color:#fff;line-height:1.8;width:100%">' + text + '</b>'
  196. map.getPanes().markerPane.appendChild(div)
  197. return div
  198. }
  199. marker.draw = function () {
  200. let point = this.getPosition()
  201. var position = map.pointToOverlayPixel(point)
  202. this.domElement.style.left = position.x - 22.5 + 'px'
  203. this.domElement.style.top = position.y - 45 + 'px'
  204. }
  205. map.addOverlay(marker)
  206. return marker
  207. }
  208. export function addMarker2 (info, map) { // 给地图添加标记
  209. let lng = info.lng
  210. let lat = info.lat
  211. let start_point = info.start_point
  212. let color = info.color
  213. let marker
  214. let totalDeg
  215. let point = new BMap.Point(lng, lat)
  216. marker = new BMap.Marker(point)
  217. marker.initialize = function (map) {
  218. var div = document.createElement('div')
  219. div.style.position = 'absolute'
  220. div.style.width = '20px'
  221. div.style.height = '20px'
  222. div.style.lineHeight = '20px'
  223. div.style.fontSize = '20px'
  224. div.style.textAlign = 'center'
  225. div.style.color = color
  226. let targetPos = map.pointToOverlayPixel(point)
  227. let curPos = map.pointToOverlayPixel(start_point)
  228. let deg = calRotation(curPos, targetPos)
  229. start_point = point
  230. totalDeg = deg + 13
  231. div.style.transform = 'rotate(' + totalDeg % 360 + 'deg)'
  232. div.style.transformOrigin = targetPos.x - 10 + 'px ' + targetPos.y - 7.1875 + 'px'
  233. div.className = 'iconfont icon-dingwei1'
  234. map.getPanes().markerPane.appendChild(div)
  235. return div
  236. }
  237. marker.draw = function () {
  238. let point = this.getPosition()
  239. let targetPos = map.pointToOverlayPixel(point)
  240. let curPos = map.pointToOverlayPixel(start_point)
  241. let deg = calRotation(curPos, targetPos)
  242. start_point = point
  243. totalDeg = deg + 13
  244. this.domElement.style.transform = 'rotate(' + totalDeg % 360 + 'deg)'
  245. var position = map.pointToOverlayPixel(point)
  246. this.domElement.style.left = position.x - 10 + 'px'
  247. this.domElement.style.top = position.y - 7.1875 + 'px'
  248. }
  249. map.addOverlay(marker)
  250. return marker
  251. }
  252. export function calRotation (curPos, targetPos) {
  253. var px = curPos.x
  254. var py = curPos.y
  255. var mx = targetPos.x
  256. var my = targetPos.y
  257. var x = Math.abs(px - mx)
  258. var y = Math.abs(py - my)
  259. var z = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2))
  260. var cos = y / z
  261. var radina = Math.acos(cos)// 用反三角函数求弧度
  262. var angle = Math.floor(180 / (Math.PI / radina))// 将弧度转换成角度
  263. if (mx > px && my > py) { // 鼠标在第四象限
  264. angle = 180 - angle
  265. }
  266. if (mx === px && my > py) { // 鼠标在y轴负方向上
  267. angle = 180
  268. }
  269. if (mx > px && my === py) { // 鼠标在x轴正方向上
  270. angle = 90
  271. }
  272. if (mx < px && my > py) { // 鼠标在第三象限
  273. angle = 180 + angle
  274. }
  275. if (mx < px && my === py) { // 鼠标在x轴负方向
  276. angle = 270
  277. }
  278. if (mx < px && my < py) { // 鼠标在第二象限
  279. angle = 360 - angle
  280. }
  281. return angle
  282. }
  283. export function clearWatch () {
  284. // #ifndef MP-WEIXIN
  285. if (typeof (navigator_id) === 'undefined') {
  286. return
  287. }
  288. geolocation.clearWatch(navigator_id)
  289. // #endif
  290. // #ifdef MP-WEIXIN
  291. wx.offLocationChange()
  292. wx.stopLocationUpdate()
  293. // #endif
  294. }
  295. export const getAddressByPoint =
  296. (location) =>
  297. requestRaw(
  298. env.SITE_URL + '/bmap/reverse_geocoding/v3/',
  299. 'GET',
  300. {
  301. location: location,
  302. output: 'json',
  303. ak: env.BMAP_AK,
  304. latest_admin: 1
  305. }
  306. )
  307. export const getPointByAddress =
  308. (address) =>
  309. requestRaw(
  310. env.SITE_URL + '/bmap/geocoding/v3/',
  311. 'GET',
  312. {
  313. address: address,
  314. output: 'json',
  315. ak: env.BMAP_AK,
  316. latest_admin: 1
  317. }
  318. )
  319. export const getAddressByKeyword =
  320. (query, region) =>
  321. requestRaw(
  322. env.SITE_URL + '/bmap/place/v2/suggestion',
  323. 'GET',
  324. {
  325. query: query,
  326. region: region,
  327. city_limit: true,
  328. output: 'json',
  329. ak: env.BMAP_AK
  330. }
  331. )
  332. export const getPointByIp =
  333. () =>
  334. requestRaw(
  335. env.SITE_URL + '/bmap/location/ip',
  336. 'GET',
  337. {
  338. coor: 'bd09ll',
  339. ak: env.BMAP_AK
  340. }
  341. )
  342. export const getPointNearby =
  343. (location) =>
  344. requestRaw(
  345. env.SITE_URL + '/bmap/place/v2/search',
  346. 'GET',
  347. {
  348. query: '宾馆$酒店$住宅$餐饮$生活娱乐$公司$商务$学校$大厦$公寓$写字楼',
  349. output: 'json',
  350. location: location,
  351. ak: env.BMAP_AK
  352. }
  353. )
  354. export const convertPoint =
  355. (lng,lat) =>
  356. requestRaw(
  357. env.SITE_URL + '/bmap/geoconv/v1/',
  358. 'GET',
  359. {
  360. coords: lng+','+lat,
  361. output: 'json',
  362. from:1,
  363. to:5,
  364. ak: env.BMAP_AK
  365. }
  366. )