api.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541
  1. import forOwn from 'lodash/forOwn';
  2. import isEqual from 'lodash/isEqual';
  3. import isNil from 'lodash/isNil';
  4. import loadjscssfile from './loadScript';
  5. export const loadApi = async (key = '0325e3d6d69cd56de4980b4f28906fd8') => {
  6. return await loadjscssfile(
  7. 'https://webapi.amap.com/maps?v=1.4.7&key=' + key,
  8. 'js'
  9. );
  10. };
  11. // let LoadResult = false;
  12. // loadApi().then(result => {
  13. // console.log('loadApi result:', result);
  14. // LoadResult = result;
  15. // return result;
  16. // })
  17. // export default LoadResult;
  18. export const loadMap = key => {
  19. return new Promise((resolve, reject) => {
  20. if (window.AMap) {
  21. resolve(window.AMap);
  22. }
  23. loadApi(key)
  24. .then(ret => {
  25. if (window.AMap) {
  26. resolve(window.AMap);
  27. } else {
  28. reject(new Error('window.AMap不存在!'));
  29. }
  30. })
  31. .catch(error => {
  32. reject(new Error('加载地图错误!' + error.message));
  33. });
  34. });
  35. };
  36. /**
  37. * [加载插件](https://lbs.amap.com/api/javascript-api/guide/abc/plugins)
  38. * 加载完成后,可以调用:
  39. * var toolbar = new AMap.ToolBar();
  40. * map.addControl(toolbar);
  41. * @param {string} name 插件名或插件数组,如:AMap.ToolBar,['AMap.ToolBar','AMap.Driving']
  42. */
  43. export const loadPlugin = name => {
  44. return new Promise((resolve, reject) => {
  45. if (window.AMap) {
  46. resolve(true);
  47. }
  48. loadApi()
  49. .then(ret => {
  50. if (!name) {
  51. reject(new Error('未填写组件名'));
  52. }
  53. window.AMap.plugin(name, () => {
  54. resolve(true);
  55. });
  56. })
  57. .catch(error => {
  58. reject(new Error('加载地图错误!' + error.message));
  59. });
  60. });
  61. };
  62. ////////////////////////////////////////////////////////////
  63. // Map
  64. ////////////////////////////////////////////////////////////
  65. export const createMap = (AMap, dom, options, events) => {
  66. const __func__ = 'createMap';
  67. if (!AMap) {
  68. console.log(__func__, 'fail! no AMap!');
  69. return null;
  70. }
  71. if (!dom) {
  72. console.log(__func__, 'fail! no dom!');
  73. return null;
  74. }
  75. let map = new AMap.Map(dom, { ...(options || {}) });
  76. forOwn(events, (value, key) => {
  77. console.log(__func__, 'event on ' + key);
  78. map.on(key, value);
  79. });
  80. console.log(__func__, 'ok!');
  81. return map;
  82. };
  83. export const commonUpdate = (
  84. entity,
  85. newOptions,
  86. newEvents,
  87. oldOptions,
  88. oldEvents,
  89. operators,
  90. __func__ = 'commonUpdate'
  91. ) => {
  92. // const __func__ = 'commonUpdate';
  93. if (!entity) {
  94. console.log(__func__, 'fail! no entity!');
  95. return false;
  96. }
  97. // 找到改变的属性集合,包含添加,删除及修改的属性,删除的置为null
  98. let props = {};
  99. if (newOptions != oldOptions) {
  100. oldOptions &&
  101. forOwn(oldOptions, (value, key) => {
  102. // 找到改变的旧属性,用新属性取代
  103. let newValue = newOptions && newOptions[key];
  104. if (!isEqual(newValue, value)) {
  105. if (!(isNil(newValue) && isNil(value)))
  106. props[key] = newValue;
  107. }
  108. });
  109. newOptions &&
  110. forOwn(newOptions, (value, key) => {
  111. // 找到新加的属性,添加进去
  112. let oldValue = oldOptions && oldOptions[key];
  113. if (isNil(oldValue) && !isNil(value)) {
  114. props[key] = value;
  115. }
  116. });
  117. }
  118. // 找到改变的事件集合,包含添加,删除及修改的事件处理函数,删除的置为null
  119. let events = {};
  120. if (newEvents != oldEvents) {
  121. oldEvents &&
  122. forOwn(oldEvents, (value, key) => {
  123. // 找到改变的旧属性,用新属性取代
  124. let newValue = newEvents && newEvents[key];
  125. if (!isEqual(newValue, value)) {
  126. if (!(isNil(newValue) && isNil(value)))
  127. events[key] = newValue;
  128. }
  129. });
  130. newEvents &&
  131. forOwn(newEvents, (value, key) => {
  132. // 找到新加的属性,添加进去
  133. let oldValue = oldEvents && oldEvents[key];
  134. if (isNil(oldValue) && !isNil(value)) {
  135. events[key] = value;
  136. }
  137. });
  138. }
  139. // let operators = {
  140. // map: v => entity.setMap(v),
  141. // position: v => entity.setPosition(v),
  142. // offset: v => entity.setOffset(v),
  143. // icon: v => entity.setIcon(v),
  144. // content: v => entity.setContent(v),
  145. // topWhenClick: null,
  146. // bubble: null,
  147. // draggable: v => entity.setDraggable(v),
  148. // raiseOnDrag: null,
  149. // cursor: v => entity.setCursor(v),
  150. // visible: null,
  151. // zIndex: v => entity.setzIndex(v),
  152. // angle: v => entity.setAngle(v),
  153. // autoRotation: null,
  154. // animation: v => entity.setAnimation(v),
  155. // shadow: v => entity.setShadow(v),
  156. // title: v => entity.setTitle(v),
  157. // clickable: v => entity.setClickable(v),
  158. // shape: v => entity.setShape(v),
  159. // extData: v => entity.setExtData(v),
  160. // label: v => entity.setLabel(v)
  161. // };
  162. forOwn(props, (value, key) => {
  163. if (value) {
  164. let func = operators[key];
  165. if (func) {
  166. func(value);
  167. } else {
  168. // ignore properties can not set.
  169. console.log(__func__, 'warning! no setter! can not update ' + key);
  170. }
  171. } else {
  172. // key removed, not support!
  173. console.log(__func__, 'warning! remove prop not support! key=' + key);
  174. }
  175. });
  176. forOwn(events, (value, key) => {
  177. let oldFunc = oldEvents && oldEvents[key];
  178. if (oldFunc) {
  179. entity.off(key, oldFunc);
  180. }
  181. if (value) {
  182. entity.on(key, value);
  183. }
  184. });
  185. console.log(
  186. __func__, 'update:',
  187. props,
  188. events,
  189. // newOptions,
  190. // newEvents,
  191. // oldOptions,
  192. // oldEvents
  193. );
  194. return true;
  195. };
  196. export const updateMap = (
  197. map,
  198. newOptions,
  199. newEvents,
  200. oldOptions,
  201. oldEvents
  202. ) => {
  203. let operators = {
  204. view: null,
  205. layers: v => map.setLayers(v),
  206. zoom: v => map.setZoom(v),
  207. center: v => map.setCenter(v),
  208. labelzIndex: v => map.setlabelzIndex(v),
  209. zooms: null,
  210. lang: v => map.setLang(v),
  211. defaultCursor: v => map.setDefaultCursor(v),
  212. crs: null,
  213. animateEnable: null,
  214. isHotspot: v => map.setStatus({ isHotspot: v }),
  215. defaultLayer: v => map.setDefaultLayer(v),
  216. rotateEnable: null,
  217. resizeEnable: null,
  218. showIndoorMap: null,
  219. indoorMap: null,
  220. expandZoomRange: null,
  221. dragEnable: v => map.setStatus({ dragEnable: v }),
  222. zoomEnable: null,
  223. doubleClickZoom: v => map.setStatus({ doubleClickZoom: v }),
  224. keyboardEnable: v => map.setStatus({ keyboardEnable: v }),
  225. jogEnable: null,
  226. scrollWheel: null,
  227. touchZoom: null,
  228. touchZoomCenter: null,
  229. mapStyle: v => map.setMapStyle(v),
  230. features: v => map.setFeatures(v),
  231. showBuildingBlock: null,
  232. viewMode: null,
  233. pitch: v => map.setPitch(v),
  234. pitchEnable: null,
  235. buildAnimation: null,
  236. skyColor: null,
  237. preloadMode: null
  238. };
  239. return commonUpdate (
  240. map,
  241. newOptions,
  242. newEvents,
  243. oldOptions,
  244. oldEvents,
  245. operators,
  246. 'updateMap'
  247. )
  248. };
  249. ////////////////////////////////////////////////////////////
  250. // Marker
  251. ////////////////////////////////////////////////////////////
  252. /**
  253. *
  254. * @param {*} AMap
  255. * @param {*} map
  256. * @param {*} options 如果有dom用来显示,则其中的content字段即被填充为dom,不再用独立参数表示dom
  257. * @param {*} events
  258. */
  259. export const createMarker = (AMap, options, events) => {
  260. const __func__ = 'createMarker';
  261. if (!AMap) {
  262. console.log(__func__, 'fail! no AMap!');
  263. return null;
  264. }
  265. if (!options) {
  266. console.log(__func__, 'fail! no options!');
  267. return null;
  268. }
  269. if (!options.map) {
  270. console.log(__func__, 'fail! no options.map!');
  271. return null;
  272. }
  273. // let marker = new AMap.Marker({
  274. // icon: "https://webapi.amap.com/theme/v1.3/markers/n/mark_b.png",
  275. // position: [116.405467, 39.907761]
  276. // });
  277. // marker.setMap(map);
  278. let entity = new AMap.Marker(options);
  279. forOwn(events, (value, key) => {
  280. entity.on(key, value);
  281. });
  282. console.log(__func__, 'ok!');
  283. return entity;
  284. };
  285. export const updateMarker = (
  286. entity,
  287. newOptions,
  288. newEvents,
  289. oldOptions,
  290. oldEvents
  291. ) => {
  292. let operators = {
  293. map: v => entity.setMap(v),
  294. position: v => entity.setPosition(v),
  295. offset: v => entity.setOffset(v),
  296. icon: v => entity.setIcon(v),
  297. content: v => entity.setContent(v),
  298. topWhenClick: null,
  299. bubble: null,
  300. draggable: v => entity.setDraggable(v),
  301. raiseOnDrag: null,
  302. cursor: v => entity.setCursor(v),
  303. visible: null,
  304. zIndex: v => entity.setzIndex(v),
  305. angle: v => entity.setAngle(v),
  306. autoRotation: null,
  307. animation: v => entity.setAnimation(v),
  308. shadow: v => entity.setShadow(v),
  309. title: v => entity.setTitle(v),
  310. clickable: v => entity.setClickable(v),
  311. shape: v => entity.setShape(v),
  312. extData: v => entity.setExtData(v),
  313. label: v => entity.setLabel(v)
  314. };
  315. return commonUpdate (
  316. entity,
  317. newOptions,
  318. newEvents,
  319. oldOptions,
  320. oldEvents,
  321. operators,
  322. 'updateMarker'
  323. )
  324. };
  325. ////////////////////////////////////////////////////////////
  326. // MassMarks, warning! is a layer!
  327. ////////////////////////////////////////////////////////////
  328. /**
  329. *
  330. * @param {*} AMap
  331. * @param {*} map
  332. * @param {*} options 如果有dom用来显示,则其中的content字段即被填充为dom,不再用独立参数表示dom
  333. * @param {*} events
  334. */
  335. export const createMassMarks = (AMap, options, events) => {
  336. const __func__ = 'createMassMarks';
  337. if (!AMap) {
  338. console.log(__func__, 'fail! no AMap!');
  339. return null;
  340. }
  341. if (!options) {
  342. console.log(__func__, 'fail! no options!');
  343. return null;
  344. }
  345. let {map, data, ...restOpts} = options;
  346. let entity = new AMap.MassMarks(data, restOpts);
  347. forOwn(events, (value, key) => {
  348. entity.on(key, value);
  349. });
  350. if (map) {
  351. entity.setMap(map);
  352. }
  353. console.log(__func__, 'ok!');
  354. return entity;
  355. };
  356. export const updateMassMarks = (
  357. entity,
  358. newOptions,
  359. newEvents,
  360. oldOptions,
  361. oldEvents
  362. ) => {
  363. let operators = {
  364. zIndex: v => entity.setzIndex(v),
  365. opacity: null,
  366. zooms: null,
  367. cursor: v => entity.setCursor(v),
  368. alwaysRender: null,
  369. style: v => entity.setStyle(v),
  370. map: v => entity.setMap(v),
  371. data: v=> entity.setData(v)
  372. };
  373. return commonUpdate (
  374. entity,
  375. newOptions,
  376. newEvents,
  377. oldOptions,
  378. oldEvents,
  379. operators,
  380. 'updateMassMarks'
  381. )
  382. };
  383. ////////////////////////////////////////////////////////////
  384. // Polygon
  385. ////////////////////////////////////////////////////////////
  386. /**
  387. *
  388. * @param {*} AMap
  389. * @param {*} map
  390. * @param {*} options 如果有dom用来显示,则其中的content字段即被填充为dom,不再用独立参数表示dom
  391. * @param {*} events
  392. */
  393. export const createPolygon = (AMap, options, events) => {
  394. const __func__ = 'createPolygon';
  395. if (!AMap) {
  396. console.log(__func__, 'fail! no AMap!');
  397. return null;
  398. }
  399. if (!options) {
  400. console.log(__func__, 'fail! no options!');
  401. return null;
  402. }
  403. if (!options.map) {
  404. console.log(__func__, 'fail! no options.map!');
  405. return null;
  406. }
  407. let entity = new AMap.Polygon(options);
  408. forOwn(events, (value, key) => {
  409. entity.on(key, value);
  410. });
  411. console.log(__func__, 'ok!');
  412. return entity;
  413. };
  414. export const updatePolygon = (
  415. entity,
  416. newOptions,
  417. newEvents,
  418. oldOptions,
  419. oldEvents
  420. ) => {
  421. let operators = {
  422. map: v => entity.setMap(v),
  423. zIndex: v => entity.setzIndex(v),
  424. path: v => entity.setPath(v),
  425. bubble: null,
  426. cursor: null,
  427. strokeColor: null,
  428. strokeOpacity: null,
  429. strokeWeight: null,
  430. fillColor: null,
  431. fillOpacity: null,
  432. draggable: null,
  433. extData: v => entity.setExtData(v),
  434. strokeStyle: null,
  435. strokeDasharray: null,
  436. options: v => entity.setOptions(v)
  437. };
  438. return commonUpdate (
  439. entity,
  440. newOptions,
  441. newEvents,
  442. oldOptions,
  443. oldEvents,
  444. operators,
  445. 'updatePolygon'
  446. )
  447. };
  448. ////////////////////////////////////////////////////////////
  449. // Polyline
  450. ////////////////////////////////////////////////////////////
  451. /**
  452. *
  453. * @param {*} AMap
  454. * @param {*} map
  455. * @param {*} options 如果有dom用来显示,则其中的content字段即被填充为dom,不再用独立参数表示dom
  456. * @param {*} events
  457. */
  458. export const createPolyline = (AMap, options, events) => {
  459. const __func__ = 'createPolyline';
  460. if (!AMap) {
  461. console.log(__func__, 'fail! no AMap!');
  462. return null;
  463. }
  464. if (!options) {
  465. console.log(__func__, 'fail! no options!');
  466. return null;
  467. }
  468. if (!options.map) {
  469. console.log(__func__, 'fail! no options.map!');
  470. return null;
  471. }
  472. let entity = new AMap.Polyline(options);
  473. forOwn(events, (value, key) => {
  474. entity.on(key, value);
  475. });
  476. console.log(__func__, 'ok!');
  477. return entity;
  478. };
  479. export const updatePolyline = (
  480. entity,
  481. newOptions,
  482. newEvents,
  483. oldOptions,
  484. oldEvents
  485. ) => {
  486. let operators = {
  487. map: v => entity.setMap(v),
  488. zIndex: v => entity.setzIndex(v),
  489. bubble: null,
  490. cursor: null,
  491. gedodesic: null,
  492. isOutline: null,
  493. borderWeight: null,
  494. outlineColor: null,
  495. path: v => entity.setPath(v),
  496. strokeColor: null,
  497. strokeOpacity: null,
  498. strokeWeight: null,
  499. strokeStyle: null,
  500. strokeDasharray: null,
  501. lineJoin: null,
  502. lineCap: null,
  503. draggable: null,
  504. extData: v => entity.setExtData(v),
  505. showDir: null,
  506. options: v => entity.setOptions(v)
  507. };
  508. return commonUpdate (
  509. entity,
  510. newOptions,
  511. newEvents,
  512. oldOptions,
  513. oldEvents,
  514. operators,
  515. 'updatePolyline'
  516. )
  517. };