widget.js 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567
  1. "use script"; //开发环境建议开启严格模式
  2. (function (window, mars3d) {
  3. //创建widget类,需要继承BaseWidget
  4. class MyWidget extends mars3d.widget.BaseWidget {
  5. //外部资源配置
  6. get resources() {
  7. return ["view.css"];
  8. }
  9. //弹窗配置
  10. get view() {
  11. return {
  12. type: "append",
  13. url: "view.html",
  14. parent: "body",
  15. };
  16. }
  17. //初始化[仅执行1次]
  18. create() {
  19. this.storageName = "mars3d_queryGaodePOI";
  20. this.pageSize = 6;
  21. this.allpage = 0;
  22. this.thispage = 0;
  23. //创建矢量数据图层
  24. this.graphicLayer = new mars3d.layer.GraphicLayer({
  25. name: this.config.name,
  26. pid: 99, //图层管理 中使用,父节点id
  27. });
  28. //鼠标单击后的信息面板弹窗
  29. this.graphicLayer.bindPopup(function (event) {
  30. let item = event.graphic?.attr;
  31. if (!item) {
  32. return;
  33. }
  34. var inHtml = `<div class="mars-popup-titile"><a href="https://www.amap.com/detail/${item.id}" target="_black" style="color: #ffffff; ">${item.name}</a></div><div class="mars-popup-content" >`;
  35. var phone = $.trim(item.tel);
  36. if (phone != "") {
  37. inHtml += "<div><label>电话</label>" + phone + "</div>";
  38. }
  39. var dz = $.trim(item.address);
  40. if (dz != "") {
  41. inHtml += "<div><label>地址</label>" + dz + "</div>";
  42. }
  43. if (item.type) {
  44. var fl = $.trim(item.type);
  45. if (fl != "") {
  46. inHtml += "<div><label>类别</label>" + fl + "</div>";
  47. }
  48. }
  49. inHtml += "</div>";
  50. return inHtml;
  51. });
  52. //查询控制器
  53. this._queryPoi = new mars3d.query.GaodePOI({
  54. // city: '合肥市',
  55. });
  56. }
  57. //每个窗口创建完成后调用
  58. winCreateOK(opt, result) {
  59. if (opt.type != "append") {
  60. return;
  61. }
  62. var that = this;
  63. var img = $("#map-querybar img");
  64. img.each((index, item) => {
  65. $(item).attr("src", this.path + $(item).attr("src"));
  66. });
  67. if (this.config.position) {
  68. $("#map-querybar").css(this.config.position);
  69. }
  70. if (this.config.style) {
  71. $("#map-querybar").css(this.config.style);
  72. }
  73. // 搜索框
  74. $("#txt_querypoi").click(function () {
  75. // 文本框内容为空
  76. if ($.trim($(this).val()).length === 0) {
  77. that.hideAllQueryBarView();
  78. that.showHistoryList(); // 显示历史记录
  79. }
  80. });
  81. var timetik = 0;
  82. // 搜索框绑定文本框值发生变化,隐藏默认搜索信息栏,显示匹配结果列表
  83. $("#txt_querypoi").bind("input propertychange", () => {
  84. clearTimeout(timetik);
  85. timetik = setTimeout(() => {
  86. this.hideAllQueryBarView();
  87. this.clearLayers();
  88. var queryVal = $.trim($("#txt_querypoi").val());
  89. if (queryVal.length == 0) {
  90. // 文本框内容为空,显示历史记录
  91. this.showHistoryList();
  92. } else {
  93. this.autoTipList(queryVal, true);
  94. }
  95. }, 500);
  96. });
  97. // 点击搜索查询按钮
  98. $("#btn_querypoi").click(() => {
  99. clearTimeout(timetik);
  100. this.hideAllQueryBarView();
  101. var queryVal = $.trim($("#txt_querypoi").val());
  102. this.strartQueryPOI(queryVal, true);
  103. });
  104. //绑定回车键
  105. $("#txt_querypoi").bind("keydown", (event) => {
  106. if (event.keyCode == "13") {
  107. $("#btn_querypoi").click();
  108. }
  109. });
  110. // 返回查询结果面板界面
  111. $("#querybar_detail_back").click(() => {
  112. this.hideAllQueryBarView();
  113. $("#querybar_resultlist_view").show();
  114. });
  115. }
  116. //打开激活
  117. activate() {
  118. this.map.addLayer(this.graphicLayer);
  119. $(".mars3d-locationbar").append('<div id="queryAddress" class="mars3d-locationbar-content" style="margin-right: 50px;"></div>');
  120. //单击地图事件
  121. this.map.on(mars3d.EventType.clickMap, this.onMapClick, this);
  122. this.map.on(mars3d.EventType.cameraChanged, this.onMapCameraChanged, this);
  123. }
  124. //关闭释放
  125. disable() {
  126. this.map.removeLayer(this.graphicLayer);
  127. //释放单击地图事件
  128. this.map.off(mars3d.EventType.clickMap, this.onMapClick, this);
  129. this.map.off(mars3d.EventType.cameraChanged, this.onMapCameraChanged, this);
  130. $("#queryAddress").remove();
  131. this.hideAllQueryBarView();
  132. this.clearLayers();
  133. }
  134. onMapClick(event) {
  135. // 点击地图区域,隐藏所有弹出框
  136. if ($.trim($("#txt_querypoi").val()).length == 0) {
  137. this.hideAllQueryBarView();
  138. $("#txt_querypoi").blur();
  139. }
  140. }
  141. onMapCameraChanged(event) {
  142. let radius = this.map.camera.positionCartographic.height; //单位:米
  143. if (radius > 100000) {
  144. this.address = null;
  145. $("#queryAddress").html("");
  146. return;
  147. }
  148. this._queryPoi.getAddress({
  149. location: this.map.getCenter(),
  150. success: (result) => {
  151. // console.log("地址", result);
  152. this.address = result;
  153. $("#queryAddress").html("地址:" + result.address);
  154. },
  155. });
  156. }
  157. hideAllQueryBarView() {
  158. $("#querybar_histroy_view").hide();
  159. $("#querybar_autotip_view").hide();
  160. $("#querybar_resultlist_view").hide();
  161. }
  162. // 点击面板条目,自动填充搜索框,并展示搜索结果面板
  163. autoSearch(name) {
  164. $("#txt_querypoi").val(name);
  165. $("#btn_querypoi").trigger("click");
  166. }
  167. //===================与后台交互========================
  168. //显示智能提示搜索结果
  169. autoTipList(text, queryEx) {
  170. //输入经纬度数字时
  171. if (this.isLonLat(text)) {
  172. return;
  173. }
  174. //查询外部widget
  175. if (this.hasExWidget() && queryEx) {
  176. this.autoExTipList(text);
  177. return;
  178. }
  179. //查询外部widget
  180. //搜索提示
  181. this._queryPoi.autoTip({
  182. text: text,
  183. city: this.address?.city,
  184. location: this.map.getCenter(),
  185. success: (result) => {
  186. var inhtml = "";
  187. var pois = result.list;
  188. for (var index = 0; index < pois.length; index++) {
  189. var name = pois[index].name;
  190. // var num = pois[index].num;
  191. // if (num > 0) continue;
  192. inhtml += "<li><i class='fa fa-search'></i><a href=\"javascript:queryGaodePOIWidget.autoSearch('" + name + "');\">" + name + "</a></li>";
  193. }
  194. if (inhtml.length > 0) {
  195. $("#querybar_ul_autotip").html(inhtml);
  196. $("#querybar_autotip_view").show();
  197. }
  198. },
  199. });
  200. }
  201. // 根据输入框内容,查询显示列表
  202. strartQueryPOI(text, queryEx) {
  203. if (text.length == 0) {
  204. toastr.warning("请输入搜索关键字!");
  205. return;
  206. }
  207. // TODO:根据文本框输入内容,从数据库模糊查询到所有匹配结果(分页显示)
  208. this.addHistory(text);
  209. this.hideAllQueryBarView();
  210. //输入经纬度数字时
  211. if (this.isLonLat(text)) {
  212. this.centerAtLonLat(text);
  213. return;
  214. }
  215. //查询外部widget
  216. if (this.hasExWidget() && queryEx) {
  217. var qylist = this.queryExPOI(text);
  218. return;
  219. }
  220. //查询外部widget
  221. this.thispage = 1;
  222. this.queryText = text;
  223. this.query_city = this.address?.city;
  224. // this.query_location = this.map.getCenter()
  225. // this.query_radius = this.map.camera.positionCartographic.height //单位:米
  226. this.queryTextByServer();
  227. }
  228. queryTextByServer() {
  229. //查询获取数据
  230. this._queryPoi.queryText({
  231. text: this.queryText,
  232. count: this.pageSize,
  233. page: this.thispage - 1,
  234. city: this.query_city,
  235. // location: this.query_location,
  236. // radius: this.query_radius,
  237. success: (result) => {
  238. if (!this.isActivate) {
  239. return;
  240. }
  241. this.showPOIPage(result.list, result.allcount);
  242. },
  243. });
  244. }
  245. //===================显示查询结果处理========================
  246. showPOIPage(data, counts) {
  247. // count -- 显示搜索结果的数量;data -- 结果的属性,如地址电话等
  248. if (counts < data.length) {
  249. counts = data.length;
  250. }
  251. this.allpage = Math.ceil(counts / this.pageSize);
  252. var inhtml = "";
  253. if (counts == 0) {
  254. inhtml += '<div class="querybar-page"><div class="querybar-fl">没有找到"<strong>' + this.queryText + '</strong>"相关结果</div></div>';
  255. } else {
  256. this.objResultData = this.objResultData || {};
  257. for (var index = 0; index < data.length; index++) {
  258. var item = data[index];
  259. var startIdx = (this.thispage - 1) * this.pageSize;
  260. item.index = startIdx + (index + 1);
  261. var _id = index;
  262. inhtml += `<div class="querybar-site" onclick="queryGaodePOIWidget.showDetail('${_id}')">
  263. <div class="querybar-sitejj">
  264. <h3>${item.index}、${item.name}
  265. <a id="btnShowDetail" href="https://www.amap.com/detail/${item.id}" target="_blank" class="querybar-more">更多&gt;</a> </h3>
  266. <p> ${item.address || ""}</p>
  267. </div>
  268. </div> `;
  269. this.objResultData[_id] = item;
  270. }
  271. //分页信息
  272. var _fyhtml;
  273. if (this.allpage > 1) {
  274. _fyhtml =
  275. '<div class="querybar-ye querybar-fr">' +
  276. this.thispage +
  277. "/" +
  278. this.allpage +
  279. '页 <a href="javascript:queryGaodePOIWidget.showFirstPage()">首页</a> <a href="javascript:queryGaodePOIWidget.showPretPage()">&lt;</a> <a href="javascript:queryGaodePOIWidget.showNextPage()">&gt;</a> </div>';
  280. } else {
  281. _fyhtml = "";
  282. }
  283. //底部信息
  284. inhtml += '<div class="querybar-page"><div class="querybar-fl">找到<strong>' + counts + "</strong>条结果</div>" + _fyhtml + "</div>";
  285. }
  286. $("#querybar_resultlist_view").html(inhtml);
  287. $("#querybar_resultlist_view").show();
  288. this.showPOIArr(data);
  289. if (counts == 1) {
  290. this.showDetail("0");
  291. }
  292. }
  293. showFirstPage() {
  294. this.thispage = 1;
  295. this.queryTextByServer();
  296. }
  297. showNextPage() {
  298. this.thispage = this.thispage + 1;
  299. if (this.thispage > this.allpage) {
  300. this.thispage = this.allpage;
  301. toastr.warning("当前已是最后一页了");
  302. return;
  303. }
  304. this.queryTextByServer();
  305. }
  306. showPretPage() {
  307. this.thispage = this.thispage - 1;
  308. if (this.thispage < 1) {
  309. this.thispage = 1;
  310. toastr.warning("当前已是第一页了");
  311. return;
  312. }
  313. this.queryTextByServer();
  314. }
  315. //点击单个结果,显示详细
  316. showDetail(id) {
  317. var item = this.objResultData[id];
  318. this.flyTo(item);
  319. }
  320. clearLayers() {
  321. this.graphicLayer.closePopup();
  322. this.graphicLayer.clear();
  323. }
  324. showPOIArr(arr) {
  325. this.clearLayers();
  326. arr.forEach((item) => {
  327. var jd = Number(item.lng);
  328. var wd = Number(item.lat);
  329. if (isNaN(jd) || isNaN(wd)) {
  330. return;
  331. }
  332. item.lng = jd;
  333. item.lat = wd;
  334. //添加实体
  335. var graphic = new mars3d.graphic.PointEntity({
  336. position: Cesium.Cartesian3.fromDegrees(jd, wd),
  337. style: {
  338. pixelSize: 10,
  339. color: "#3388ff",
  340. outline: true,
  341. outlineColor: "#ffffff",
  342. outlineWidth: 2,
  343. scaleByDistance: new Cesium.NearFarScalar(1000, 1, 1000000, 0.1),
  344. clampToGround: true, //贴地
  345. visibleDepth: false, //是否被遮挡
  346. label: {
  347. text: item.name,
  348. font_size: 20,
  349. color: "rgb(240,255,255)",
  350. outline: true,
  351. outlineWidth: 2,
  352. outlineColor: Cesium.Color.BLACK,
  353. horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
  354. verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
  355. pixelOffsetY: -10, //偏移量
  356. distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0.0, 200000),
  357. clampToGround: true, //贴地
  358. visibleDepth: false, //是否被遮挡
  359. },
  360. },
  361. attr: item,
  362. });
  363. this.graphicLayer.addGraphic(graphic);
  364. item._graphic = graphic;
  365. });
  366. if (arr.length > 1) {
  367. this.graphicLayer.flyTo();
  368. }
  369. }
  370. flyTo(item) {
  371. var graphic = item._graphic;
  372. if (graphic == null) {
  373. window.toastr.warning(item.name + " 无经纬度坐标信息!");
  374. return;
  375. }
  376. this.map.flyToGraphic(graphic, { radius: 2000 });
  377. setTimeout(() => {
  378. this.graphicLayer.openPopup(graphic);
  379. }, 3000);
  380. }
  381. //===================坐标定位处理========================
  382. isLonLat(text) {
  383. var reg = /^-?((0|1?[0-7]?[0-9]?)(([.][0-9]*)?)|180(([.][0]*)?)),-?((0|[1-8]?[0-9]?)(([.][0-9]*)?)|90(([.][0]*)?))$/; /*定义验证表达式*/
  384. return reg.test(text); /*进行验证*/
  385. }
  386. centerAtLonLat(text) {
  387. var arr = text.split(",");
  388. if (arr.length != 2) {
  389. return;
  390. }
  391. var jd = Number(arr[0]);
  392. var wd = Number(arr[1]);
  393. if (isNaN(jd) || isNaN(wd)) {
  394. return;
  395. }
  396. //添加实体
  397. var graphic = new mars3d.graphic.PointEntity({
  398. position: Cesium.Cartesian3.fromDegrees(jd, wd),
  399. style: {
  400. color: "#3388ff",
  401. pixelSize: 10,
  402. outline: true,
  403. outlineColor: "#ffffff",
  404. outlineWidth: 2,
  405. scaleByDistance: new Cesium.NearFarScalar(1000, 1, 1000000, 0.1),
  406. clampToGround: true, //贴地
  407. visibleDepth: false, //是否被遮挡
  408. },
  409. });
  410. this.graphicLayer.addGraphic(graphic);
  411. graphic.bindPopup(`<div class="mars-popup-titile">坐标定位</div>
  412. <div class="mars-popup-content" >
  413. <div><label>经度</label> ${jd}</div>
  414. <div><label>纬度</label>${wd}</div>
  415. </div>`);
  416. graphic.openHighlight();
  417. graphic.flyTo({
  418. radius: 1000, //点数据:radius控制视距距离
  419. scale: 1.5, //线面数据:scale控制边界的放大比例
  420. complete: () => {
  421. graphic.openPopup();
  422. },
  423. });
  424. }
  425. //===================历史记录相关========================
  426. showHistoryList() {
  427. $("#querybar_histroy_view").hide();
  428. localforage.getItem(this.storageName).then((laststorage) => {
  429. if (laststorage == null) {
  430. return;
  431. }
  432. this.arrHistory = eval(laststorage);
  433. if (this.arrHistory == null || this.arrHistory.length == 0) {
  434. return;
  435. }
  436. var inhtml = "";
  437. for (var index = this.arrHistory.length - 1; index >= 0; index--) {
  438. var item = this.arrHistory[index];
  439. inhtml += "<li><i class='fa fa-history'/><a href=\"javascript:queryGaodePOIWidget.autoSearch('" + item + "');\">" + item + "</a></li>";
  440. }
  441. $("#querybar_ul_history").html(inhtml);
  442. $("#querybar_histroy_view").show();
  443. });
  444. }
  445. clearHistory() {
  446. this.arrHistory = [];
  447. localforage.removeItem(this.storageName);
  448. $("#querybar_ul_history").html("");
  449. $("#querybar_histroy_view").hide();
  450. }
  451. //记录历史值
  452. addHistory(data) {
  453. this.arrHistory = [];
  454. localforage.getItem(this.storageName).then((laststorage) => {
  455. if (laststorage != null) {
  456. this.arrHistory = eval(laststorage);
  457. }
  458. //先删除之前相同记录
  459. haoutil.array.remove(this.arrHistory, data);
  460. this.arrHistory.push(data);
  461. if (this.arrHistory.length > 10) {
  462. this.arrHistory.splice(0, 1);
  463. }
  464. localforage.setItem(this.storageName, this.arrHistory);
  465. });
  466. }
  467. //======================查询非百度poi,联合查询处理=================
  468. //外部widget是否存在或启用
  469. hasExWidget() {
  470. if (window["queryBarWidget"] == null) {
  471. return false;
  472. } else {
  473. this.exWidget = window.queryBarWidget;
  474. return true;
  475. }
  476. }
  477. autoExTipList(text) {
  478. this.exWidget.autoTipList(text, () => {
  479. this.autoTipList(text, false);
  480. });
  481. }
  482. //调用外部widget进行查询
  483. queryExPOI(text) {
  484. var layer = this.graphicLayer;
  485. this.exWidget.strartQueryPOI(text, layer, () => {
  486. this.strartQueryPOI(text, false);
  487. });
  488. }
  489. }
  490. //注册到widget管理器中。
  491. window.queryGaodePOIWidget = mars3d.widget.bindClass(MyWidget);
  492. //每个widet之间都是直接引入到index.html中,会存在彼此命名冲突,所以闭包处理下。
  493. })(window, mars3d);