PoiQueryButton.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462
  1. //poi查询按钮 控件
  2. class PoiQueryButton extends mars3d.control.BaseControl {
  3. get parentContainer() {
  4. return document.getElementsByClassName("cesium-viewer-toolbar")[0];
  5. }
  6. /**
  7. * 创建_container控件容器对象的方法,
  8. * 只会调用一次
  9. * @return {void} 无
  10. * @private
  11. */
  12. _mountedHook() {
  13. // 初始化页面
  14. this.initQueryUI();
  15. //查询控制器
  16. this.queryPoi = new mars3d.query.GaodePOI();
  17. //创建矢量数据图层
  18. this.graphicLayer = new mars3d.layer.GraphicLayer();
  19. this._map.addLayer(this.graphicLayer);
  20. //鼠标单击后的信息面板弹窗
  21. this.graphicLayer.bindPopup(function (event) {
  22. let item = event.graphic.attr;
  23. if (!item) {
  24. return;
  25. }
  26. 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" >`;
  27. var phone = $.trim(item.tel);
  28. if (phone != "") {
  29. inHtml += "<div><label>电话</label>" + phone + "</div>";
  30. }
  31. var dz = $.trim(item.address);
  32. if (dz != "") {
  33. inHtml += "<div><label>地址</label>" + dz + "</div>";
  34. }
  35. if (item.type) {
  36. var fl = $.trim(item.type);
  37. if (fl != "") {
  38. inHtml += "<div><label>类别</label>" + fl + "</div>";
  39. }
  40. }
  41. inHtml += "</div>";
  42. return inHtml;
  43. });
  44. }
  45. clear() {
  46. var ulList = this.poiButtonResult.querySelector(".searchResults");
  47. var gaodesousuo = this.poiButtonResult.querySelector(".gaodesousuo");
  48. if (ulList) {
  49. ulList.remove();
  50. }
  51. if (this.resultNextPages) {
  52. this.resultNextPages.remove();
  53. }
  54. if (gaodesousuo) {
  55. gaodesousuo.remove();
  56. }
  57. if (this.graphicLayer) {
  58. this.graphicLayer.clear();
  59. }
  60. }
  61. //初始化所有相关UI
  62. initQueryUI() {
  63. //高度值获取
  64. this._container = mars3d.DomUtil.create("div", "cesium-button cesium-toolbar-button");
  65. this._container.style.display = "inline-block";
  66. this._container.setAttribute("title", this.options.title || "POI查询");
  67. mars3d.DomUtil.createSvg(
  68. 33,
  69. 33,
  70. "M29.772,26.433l-7.126-7.126c0.96-1.583,1.523-3.435,1.524-5.421C24.169,8.093,19.478,3.401,13.688,3.399C7.897,3.401,3.204,8.093,3.204,13.885c0,5.789,4.693,10.481,10.484,10.481c1.987,0,3.839-0.563,5.422-1.523l7.128,7.127L29.772,26.433zM7.203,13.885c0.006-3.582,2.903-6.478,6.484-6.486c3.579,0.008,6.478,2.904,6.484,6.486c-0.007,3.58-2.905,6.476-6.484,6.484C10.106,20.361,7.209,17.465,7.203,13.885z",
  71. this._container
  72. );
  73. //鼠标移入移出
  74. let cacheTarget;
  75. this._container.addEventListener("mouseover", (e) => {
  76. //缓存,提高效率
  77. if (cacheTarget == this.uuid) {
  78. return;
  79. }
  80. cacheTarget = this.uuid;
  81. // console.log("mouseover");
  82. if (this.toolSearch.style.display !== "block") {
  83. this.toolSearchNoShow("block");
  84. this.toolActive();
  85. mars3d.DomUtil.addClass(this._container, "queryPoiButton");
  86. this._container.style.height = this.parentContainer.offsetHeight + 40 + "px";
  87. this.poiButtonResult.style.height = this.parentContainer.offsetHeight - 10 + "px";
  88. }
  89. });
  90. this._container.addEventListener("mouseout", (e) => {
  91. cacheTarget = null;
  92. // console.log("mouseout");
  93. var queryVal = this.toolSearch.querySelector(".searchInput").value;
  94. if (queryVal.length == 0) {
  95. this.clear();
  96. this.toolSearchNoShow("none");
  97. mars3d.DomUtil.removeClass(this._container, "queryPoiButton");
  98. this._container.style.height = "";
  99. }
  100. });
  101. // input面板,在queryPoiButton下面
  102. this.toolSearch = mars3d.DomUtil.create("div", "toolSearch");
  103. this._container.appendChild(this.toolSearch);
  104. // 搜寻结果,在mars3dContainer面板下面
  105. this.poiButtonResult = mars3d.DomUtil.create("div", "poiButtonResult");
  106. this._container.appendChild(this.poiButtonResult);
  107. this.toolSearchNoShow("none");
  108. // 创建input输入框
  109. var textInput = mars3d.DomUtil.create("input", "searchInput");
  110. textInput.type = "search";
  111. textInput.setAttribute("placeholder", "请输入地址...");
  112. this.toolSearch.appendChild(textInput);
  113. // input的单击事件
  114. var deleteInput = mars3d.DomUtil.create("div", "deleteInput");
  115. this.toolSearch.appendChild(deleteInput);
  116. this.addElementP(deleteInput, "×", () => {
  117. this.toolSearch.querySelector(".searchInput").value = "";
  118. this.clear();
  119. this.toolSearchNoShow("none");
  120. mars3d.DomUtil.removeClass(this._container, "queryPoiButton");
  121. this._container.style.height = "";
  122. cacheTarget = null;
  123. });
  124. // 绑定change事件
  125. var timetik;
  126. textInput.addEventListener("input", () => {
  127. this.clear();
  128. clearTimeout(timetik);
  129. timetik = setTimeout(() => {
  130. var queryVal = this.toolSearch.querySelector(".searchInput").value;
  131. if (queryVal.length !== 0) {
  132. deleteInput.style.display = "block";
  133. this.autoTip(queryVal);
  134. }
  135. }, 250);
  136. });
  137. //绑定回车键
  138. textInput.addEventListener("keydown", (event) => {
  139. if (event.keyCode == "13") {
  140. clearTimeout(timetik);
  141. // 让change事件执行完成之后,在执行以下操作
  142. timetik = setTimeout(() => {
  143. this.clear();
  144. this.showPages = 1;
  145. this.strartQueryPOI();
  146. }, 250);
  147. }
  148. });
  149. }
  150. toolActive() {
  151. this.toolSearch.style.display = "block";
  152. let searchInput = this.toolSearch.querySelector(".searchInput");
  153. searchInput.focus();
  154. if (document.activeElement.tagName == "INPUT" && searchInput.value == "") {
  155. return;
  156. }
  157. this.clear();
  158. this.showPages = 1;
  159. this.strartQueryPOI();
  160. }
  161. // 根据输入框内容,查询显示列表
  162. strartQueryPOI() {
  163. var text = this.toolSearch.querySelector(".searchInput").value;
  164. if (text.trim().length == 0) {
  165. haoutil.msg("请输入搜索关键字!");
  166. return;
  167. }
  168. //输入经纬度数字时
  169. if (this.isLonLat(text)) {
  170. this.centerAtLonLat(text);
  171. return;
  172. }
  173. this.queryTextByServer(text);
  174. }
  175. queryTextByServer(text) {
  176. this.queryPoi.queryText({
  177. text: text,
  178. count: 10,
  179. page: this.showPages - 1,
  180. success: (result) => {
  181. // console.log("文字搜索", result);
  182. var pois = result.list;
  183. if (pois.length > 0) {
  184. result.list.forEach((item, index) => {
  185. if (!item.x || !item.y) {
  186. return;
  187. }
  188. // 在地图上将搜寻的结果展现为矢量数据
  189. var graphic = new mars3d.graphic.PointEntity({
  190. id: item.id,
  191. position: [item.x, item.y],
  192. style: {
  193. name: item.name,
  194. pixelSize: 10,
  195. color: "#3388ff",
  196. outline: true,
  197. outlineColor: "#ffffff",
  198. outlineWidth: 2,
  199. scaleByDistance: new Cesium.NearFarScalar(1000, 1, 1000000, 0.1),
  200. clampToGround: true, //贴地
  201. visibleDepth: false, //是否被遮挡
  202. highlight: {
  203. type: mars3d.EventType.click,
  204. color: "#ff0000",
  205. },
  206. label: {
  207. text: item.name,
  208. font_size: 20,
  209. color: "rgb(240,255,255)",
  210. outline: true,
  211. outlineWidth: 2,
  212. outlineColor: Cesium.Color.BLACK,
  213. horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
  214. verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
  215. pixelOffsetY: -10, //偏移量
  216. distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0.0, 200000),
  217. clampToGround: true, //贴地
  218. visibleDepth: false, //是否被遮挡
  219. },
  220. },
  221. attr: item,
  222. });
  223. this.graphicLayer.addGraphic(graphic);
  224. });
  225. this.graphicLayer.flyTo();
  226. console.log(result);
  227. this.showDifferentPagesResult(result);
  228. }
  229. },
  230. });
  231. }
  232. flyTo(item) {
  233. var graphic = this.graphicLayer.getGraphicById(item.id);
  234. if (graphic == null) {
  235. window.toastr.warning(item.name + " 无经纬度坐标信息!");
  236. return;
  237. }
  238. graphic.openHighlight();
  239. graphic.flyTo({
  240. radius: 2000,
  241. complete: () => {
  242. graphic.openPopup();
  243. },
  244. });
  245. }
  246. //构造查询结果的面板Html
  247. showDifferentPagesResult(result) {
  248. this.poiButtonResult.innerHTML = "";
  249. // 页面上显示结果li列表
  250. var resultDiv = document.createElement("div");
  251. resultDiv.className = "searchResults";
  252. var suggestionsList = document.createElement("ul");
  253. resultDiv.appendChild(suggestionsList);
  254. this.poiButtonResult.appendChild(resultDiv);
  255. result.list.forEach((item, index) => {
  256. var name = item.name;
  257. if (!item.x || !item.y) {
  258. return;
  259. }
  260. var number;
  261. if (this.showPages > 1) {
  262. number = (this.showPages - 1) * 10 + index + 1;
  263. } else {
  264. number = index + 1;
  265. }
  266. var suggestions = document.createElement("li");
  267. var resultList = document.createTextNode(number + ". " + name);
  268. suggestionsList.appendChild(suggestions);
  269. suggestions.appendChild(resultList);
  270. suggestions.addEventListener("click", () => {
  271. this.flyTo(item);
  272. });
  273. });
  274. var allPages = Math.ceil(result.allcount / 10); // 全部的页数 10 = result.count
  275. this.resultNextPages = document.createElement("div");
  276. this.resultNextPages.className = "resultNextPages";
  277. this.poiButtonResult.appendChild(this.resultNextPages);
  278. // 共加载条数
  279. this.addElementP(this.resultNextPages, "共加载了" + result.allcount + "条", null);
  280. // 展示的页数
  281. this.addElementP(this.resultNextPages, this.showPages + "/" + allPages + "页", null);
  282. // 首页
  283. this.addElementP(this.resultNextPages, "首页", () => {
  284. this.showPages = 1;
  285. this.pagesClickToPages(this.resultNextPages);
  286. });
  287. // 上一页
  288. this.addElementP(this.resultNextPages, "<", () => {
  289. if (this.showPages == 1) {
  290. haoutil.msg("当前已是第一页!");
  291. return;
  292. }
  293. this.showPages--;
  294. this.pagesClickToPages(this.resultNextPages);
  295. });
  296. // 下一页
  297. this.addElementP(this.resultNextPages, ">", () => {
  298. if (this.showPages >= allPages) {
  299. haoutil.msg("当前已是最后一页!");
  300. return;
  301. }
  302. this.showPages++;
  303. this.pagesClickToPages(this.resultNextPages); //查询结果
  304. });
  305. }
  306. // 添加p元素
  307. addElementP(parentElement, chilidWord, callback) {
  308. var allResult = document.createElement("p");
  309. var allResultWord = document.createTextNode(chilidWord);
  310. parentElement.appendChild(allResult); //添加p元素
  311. allResult.appendChild(allResultWord); // 给p元素添加内容
  312. allResult.addEventListener("click", callback);
  313. }
  314. // 点击上、下一页,清空当前页
  315. pagesClickToPages(allPages) {
  316. if (allPages) {
  317. this.addElementP(this.poiButtonResult, this.showPages + "/" + allPages + "页");
  318. }
  319. if (this.graphicLayer) {
  320. this.graphicLayer.clear();
  321. }
  322. this.strartQueryPOI();
  323. }
  324. autoTip(text) {
  325. this.queryPoi.autoTip({
  326. text: text,
  327. success: (result) => {
  328. var pois = result.list;
  329. let gaodesousuo = this.poiButtonResult.querySelector(".gaodesousuo");
  330. if (gaodesousuo) {
  331. gaodesousuo.remove();
  332. }
  333. var resultDiv = document.createElement("div");
  334. resultDiv.className = "searchResults gaodesousuo";
  335. var suggestionsList = document.createElement("ul");
  336. resultDiv.appendChild(suggestionsList);
  337. this.poiButtonResult.appendChild(resultDiv);
  338. if (pois.length > 0) {
  339. result.list.forEach((item) => {
  340. var name = item.name;
  341. var suggestions = document.createElement("li");
  342. var resultList = document.createTextNode(name);
  343. var fa_search = document.createElement("span");
  344. fa_search.className = "fa fa-search";
  345. suggestions.appendChild(fa_search);
  346. suggestionsList.appendChild(suggestions);
  347. suggestions.appendChild(resultList);
  348. suggestions.addEventListener("click", () => {
  349. this.toolSearch.querySelector(".searchInput").value = name;
  350. this.showPages = 1;
  351. this.queryTextByServer(name);
  352. });
  353. });
  354. } else {
  355. resultDiv.style.display = "none";
  356. }
  357. },
  358. });
  359. }
  360. toolSearchNoShow(val) {
  361. this.toolSearch.style.display = val;
  362. this.poiButtonResult.style.display = val;
  363. }
  364. //===================坐标定位处理========================
  365. isLonLat(text) {
  366. var reg = /^-?((0|1?[0-7]?[0-9]?)(([.][0-9]*)?)|180(([.][0]*)?)),-?((0|[1-8]?[0-9]?)(([.][0-9]*)?)|90(([.][0]*)?))$/; /*定义验证表达式*/
  367. return reg.test(text); /*进行验证*/
  368. }
  369. centerAtLonLat(text) {
  370. var arr = text.split(",");
  371. if (arr.length != 2) {
  372. return;
  373. }
  374. var jd = Number(arr[0]);
  375. var wd = Number(arr[1]);
  376. if (isNaN(jd) || isNaN(wd)) {
  377. return;
  378. }
  379. this.map.setCameraView({ x: jd, y: wd, minz: 2500 });
  380. //添加实体
  381. var graphic = new mars3d.graphic.PointEntity({
  382. position: Cesium.Cartesian3.fromDegrees(jd, wd),
  383. style: {
  384. color: "#3388ff",
  385. pixelSize: 10,
  386. outline: true,
  387. outlineColor: "#ffffff",
  388. outlineWidth: 2,
  389. scaleByDistance: new Cesium.NearFarScalar(1000, 1, 1000000, 0.1),
  390. clampToGround: true, //贴地
  391. visibleDepth: false, //是否被遮挡
  392. },
  393. });
  394. this.graphicLayer.addGraphic(graphic);
  395. graphic.bindPopup(`<div class="mars-popup-titile">坐标定位</div>
  396. <div class="mars-popup-content" >
  397. <div><label>经度</label> ${jd}</div>
  398. <div><label>纬度</label>${wd}</div>
  399. </div>`);
  400. setTimeout(() => {
  401. graphic.openPopup();
  402. }, 3000);
  403. }
  404. }