map.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  1. <template>
  2. <div class="nutui-mapbox">
  3. <div class="search">
  4. <div v-if="search" class="text-msg">
  5. <input placeholder="请输入搜索内容" class="inpt-box" type="sreach" @keyup="searchKeywordlike" v-model="Keyword" />
  6. <span class="title-box">{{Keyword}}</span>
  7. <span v-if="fristCity" class="city-box">{{fristCity}}</span>
  8. </div>
  9. <ul v-show="suggestShow&&address.length>0" class="suggest-box">
  10. <li v-for="(item,index) of address" :key="index" @click="searchcomplete(item)" class="list">
  11. <div class="mark">
  12. <svg width="18" height="18">
  13. <use xlink:href="#location"/>
  14. </svg>
  15. </div>
  16. <div class="msg">
  17. <div class="tit" v-html="item.title"></div>
  18. <div class="adr">{{item.address}}</div>
  19. </div>
  20. </li>
  21. </ul>
  22. </div>
  23. <!-- 定位 -->
  24. <svg v-if="location" class="map-ca" width="30" height="30" @click="getlocationApp">
  25. <use xlink:href="#getlocation"/>
  26. </svg>
  27. <!-- 地图 -->
  28. <div @click="closeSuggest" class="nut-map" :id="option.id"></div>
  29. </div>
  30. <!--
  31. 1、当前位置的定位,获取当前经纬度
  32. 2、可以安装传入的经纬度显示位置。
  33. 3、搜索功能,搜到然后标记出来。(多标记功能)
  34. 4、获取不到经纬度给一个友情提示
  35. -->
  36. </template>
  37. <script>
  38. import './map.scss';
  39. import jsonp from "./jsonp.js";
  40. import getMap from './tcMap.js';
  41. import latSvg from '../../../asset/img/map/location.svg';
  42. import getlocation from '../../../asset/img/map/getlocation.svg';
  43. import getolocation from './location.js';
  44. export default {
  45. name:'nut-map',
  46. props: {
  47. //地图的秘钥
  48. key:{
  49. type:String,
  50. default:"K3HBZ-ZSA3U-BMUVL-BUEEN-FL6JT-XUFLM"
  51. },
  52. keySky:{
  53. type:String,
  54. default:""
  55. },
  56. sn:{
  57. type:String,
  58. default:"136884f65834d7996cb7f3e0e4d4caca"
  59. },
  60. option:{
  61. type:Object,
  62. default:{}
  63. },
  64. search:{
  65. type:Boolean,
  66. default:true
  67. },
  68. location:{
  69. type:Boolean,
  70. default:true
  71. }
  72. },
  73. data() {
  74. return {
  75. Keyword:'',
  76. map:null,
  77. tc:null,
  78. searchService:null,
  79. markerArrays:[],
  80. searchMarkers:[],
  81. searchreslut:[],
  82. fristCity:'',
  83. fristAddress:'',
  84. firstTitle:"",
  85. suggestShow:true,
  86. timeSet:null,
  87. delay:500,
  88. address:[],
  89. svgLc:latSvg
  90. };
  91. },
  92. methods: {
  93. //模糊查询
  94. searchKeywordlike(e){
  95. //正常输入则显示查询列表
  96. let keyword = this.Keyword;//搜索关键字
  97. let that = this;
  98. //按回车 选取列表第一个
  99. if(keyword&&e.keyCode == 13&&this.address[0]){
  100. this.fristAddress =this.address[0].address;
  101. that.searchKeyword();
  102. return;
  103. }
  104. //查询
  105. if(keyword){
  106. this.requestAnimationFrame(()=>{
  107. jsonp({
  108. url:'http://apis.map.qq.com/ws/place/v1/suggestion',
  109. type:"JSONP",
  110. data:{
  111. keyword:keyword,
  112. key:that.key,
  113. sn:that.sn
  114. }
  115. }).then(res=>{
  116. that.suggestShow = true;
  117. ////console.log(res.data)
  118. if(res.data){
  119. that.address = res.data;
  120. that.fristCity = res.data[0]&&res.data[0].city;
  121. }
  122. })
  123. })
  124. } else {
  125. this.address = [];
  126. }
  127. },
  128. // 有城市搜索
  129. searchKeyword(){
  130. //以知城市进行搜索
  131. let markers = this.searchMarkers;
  132. let markerArrays = this.markerArrays;
  133. let keyword = this.Keyword;//搜索关键字
  134. let region = this.fristCity;//城市
  135. if(region){
  136. let pageIndex = 1;
  137. let pageCapacity = 20;// 设置每页搜索结果数
  138. this.clearOverlays(markers);
  139. this.clearOverlays(markerArrays);
  140. //根据输入的城市设置搜索范围
  141. this.searchService.setLocation(region);
  142. //设置搜索页码
  143. this.searchService.setPageIndex(pageIndex);
  144. //设置每页的结果数
  145. this.searchService.setPageCapacity(pageCapacity);
  146. //根据输入的关键字在搜索范围内检索
  147. this.searchService.search(keyword);
  148. this.closeSuggest();
  149. }
  150. },
  151. closeSuggest(){
  152. this.suggestShow = false;
  153. },
  154. searchcomplete(res){
  155. let map = this.map;
  156. let tc = this.tc;
  157. let searchMarkers = this.searchMarkers;
  158. let markerArrays = this.markerArrays;
  159. // 清除之前的点
  160. this.clearOverlays(searchMarkers);
  161. this.clearOverlays(markerArrays);
  162. this.marker(res.location);
  163. this.searchMarkers = searchMarkers;
  164. //更新地图
  165. let location = new tc.maps.LatLng(res.location.lat,res.location.lng);
  166. let latlngBounds = new tc.maps.LatLngBounds();
  167. latlngBounds.extend(location);
  168. map.fitBounds(latlngBounds);
  169. this.Keyword = res.title;
  170. this.fristCity = res.city;
  171. this.closeSuggest();
  172. },
  173. marker(lc){
  174. ////console.log(lc)
  175. let tc = this.tc;
  176. //当前的地图
  177. let map = this.map;
  178. let searchMarkers = this.searchMarkers;
  179. ////console.log(searchMarkers)
  180. //设置坐标点
  181. let marker = new tc.maps.Marker({
  182. map: map,
  183. position: new tc.maps.LatLng(lc.lat,lc.lng)
  184. });
  185. searchMarkers.push(marker);
  186. this.searchMarkers = searchMarkers;
  187. let markerOption = this.option.marker;
  188. if(markerOption){
  189. //是否可见 默认可见
  190. if(!markerOption.visible){
  191. marker.setVisible(markerOption.visible);
  192. }
  193. //设置动画
  194. if(markerOption.animation){
  195. marker.setAnimation(tc.maps.MarkerAnimation[markerOption.animation]);
  196. }
  197. //设置是否可以拖拽 默认不可以拖拽
  198. if(markerOption.draggable){
  199. marker.setDraggable(true);
  200. }
  201. //设置自定义图片
  202. if(markerOption.icon){
  203. let icon = new tc.maps.MarkerImage(markerOption.icon);
  204. marker.setIcon(icon);
  205. }
  206. if(markerOption.title) {
  207. marker.setTitle(markerOption.title);
  208. }
  209. // //添加信息窗口
  210. if(markerOption.info){
  211. var info = new tc.maps.InfoWindow({
  212. map: map
  213. });
  214. }
  215. //标记Marker点击事件
  216. if(markerOption.click){
  217. tc.maps.event.addListener(marker, 'click', function() {
  218. //console.log(marker.getPosition())
  219. if(markerOption.click){
  220. markerOption.click(marker)
  221. }
  222. if(markerOption.info){
  223. info.open();
  224. info.setContent(markerOption.info(marker));
  225. info.setPosition(marker.getPosition());
  226. }
  227. });
  228. }
  229. //设置Marker停止拖动事件
  230. if(markerOption.dragend){
  231. tc.maps.event.addListener(marker, 'dragend', function() {
  232. //console.log(marker.getPosition())
  233. if(markerOption.marker){
  234. markerOption.click(marker)
  235. }
  236. if(markerOption.info){
  237. info.open();
  238. info.setContent(markerOption.info(marker));
  239. info.setPosition(marker.getPosition());
  240. }
  241. });
  242. }
  243. }
  244. },
  245. clearOverlays(overlays) {
  246. let overlay;
  247. while (overlay = overlays.pop()) {
  248. overlay.setMap(null);
  249. }
  250. },
  251. newSearchService(){
  252. let that = this;
  253. let tc = this.tc;
  254. let map = this.map;
  255. let searchMarkers = this.searchMarkers;
  256. //设置Poi检索服务,用于本地检索、周边检索
  257. this.searchService = new tc.maps.SearchService({
  258. //检索成功的回调函数
  259. complete: function(results) {
  260. //设置回调函数参数
  261. let pois = results.detail.pois;
  262. if(pois){
  263. let infoWin = new tc.maps.InfoWindow({
  264. map: map
  265. });
  266. let latlngBounds = new tc.maps.LatLngBounds();
  267. for (let i = 0, l = pois.length; i < l; i++) {
  268. let poi = pois[i];
  269. //扩展边界范围,用来包含搜索到的Poi点
  270. latlngBounds.extend(poi.latLng);
  271. (function(n) {
  272. let marker = new tc.maps.Marker({
  273. map: map
  274. });
  275. marker.setPosition(pois[n].latLng);
  276. marker.setTitle(i + 1);
  277. searchMarkers.push(marker);
  278. tc.maps.event.addListener(marker, 'click', function() {
  279. infoWin.open();
  280. //console.log(pois);
  281. infoWin.setContent('<div style="width:280px;height:100px;">' + 'POI的ID为:' +
  282. pois[n].id + ',POI的名称为:' + pois[n].name + ',POI的地址为:' + pois[n].address + ',POI的类型为:' + pois[n].type + '</div>');
  283. infoWin.setPosition(pois[n].latLng);
  284. });
  285. })(i);
  286. }
  287. that.searchMarkers = searchMarkers;
  288. //调整地图视野
  289. map.fitBounds(latlngBounds);
  290. }
  291. },
  292. //若服务请求失败,则运行以下函数
  293. error: function(val) {
  294. //console.log("出错了。",val);
  295. }
  296. });
  297. },
  298. init(){
  299. ////console.log(tt);
  300. let tt = this.tc;
  301. let propsOptions = this.option.options;
  302. let langs = {
  303. lat:propsOptions.center[0],
  304. lng:propsOptions.center[1]
  305. }
  306. //
  307. let center = null;
  308. let id = this.option.id;
  309. //地图显示的中心点(标记点)
  310. if(propsOptions.center[0]&&propsOptions.center[1]){
  311. let center =new tt.maps.LatLng(propsOptions.center[0],propsOptions.center[1]);
  312. propsOptions = Object.assign(propsOptions,{
  313. center:center
  314. });
  315. }
  316. //缩放类型,可设置以地图中心点或双指中心点为焦点(移动端)。 //不填默认缩放手指中心位置
  317. if(propsOptions.MapZoomType){
  318. let mapZoomType = tt.maps.MapZoomType[propsOptions.MapZoomType];
  319. propsOptions = Object.assign(propsOptions,{
  320. mapZoomType:mapZoomType
  321. });
  322. }
  323. //地图显示类型 默认显示2d平面地图
  324. if(propsOptions.MapTypeId){
  325. let MapTypeId = tt.maps.MapTypeId[propsOptions.MapTypeId];
  326. propsOptions = Object.assign(propsOptions,{
  327. MapTypeId:MapTypeId
  328. });
  329. }
  330. //地图初始化
  331. let elm = document.querySelector('#'+id);
  332. this.map = new tt.maps.Map(elm,propsOptions);
  333. //是否创建一个marker 检索
  334. this.$nextTick(()=>{
  335. this.marker(langs);
  336. this.newSearchService();
  337. })
  338. //是否有检索功能
  339. },
  340. requestAnimationFrame (callback) {
  341. let delay = this.delay;
  342. let timeSet = this.timeSet;
  343. if(timeSet){
  344. clearTimeout(timeSet);
  345. }
  346. this.timeSet = setTimeout(() => {
  347. callback()
  348. }, delay)
  349. },
  350. getlocationApp(){
  351. let that = this;
  352. let tc = this.tc;
  353. getolocation().then(()=>{
  354. let geolocation = new tc.maps.Geolocation();
  355. geolocation.getLocation(ops=>{
  356. // res.location.lat,res.location.lng
  357. if(ops){
  358. let res = {
  359. location:{
  360. lat:ops.lat,
  361. lng:ops.lng
  362. }
  363. }
  364. that.searchcomplete(res);
  365. }
  366. })
  367. })
  368. }
  369. },
  370. mounted(){
  371. let that = this;
  372. let key = that.key;
  373. getMap(key).then(
  374. qq=>{
  375. that.tc = qq;
  376. that.init();
  377. if(that.location){
  378. that.getlocationApp();
  379. }
  380. }
  381. );
  382. // 定位当前
  383. }
  384. }
  385. </script>
  386. <style lang="scss">
  387. </style>