widget.js 17 KB

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