map.js 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855
  1. "use strict";
  2. const common_vendor = require("../../common/vendor.js");
  3. const pages_api_luyou = require("../api/luyou.js");
  4. const _sfc_main = {
  5. data() {
  6. return {
  7. latitude: 38.818143,
  8. // 保定理工的纬度
  9. longitude: 115.484621,
  10. // 保定理工的经度
  11. scale: 14,
  12. markers: [],
  13. polylines: [],
  14. includePoints: [],
  15. // 添加要包含在地图视野内的点
  16. showAllMarkers: false,
  17. // 是否显示所有景点
  18. searchKeyword: "",
  19. selectedLocations: [],
  20. currentIndex: -1,
  21. jingdian: [],
  22. // 存储景点数据
  23. targetSpotName: "",
  24. // 目标景点名称
  25. defaultBaodingSpots: [
  26. {
  27. id: 999,
  28. name: "保定古莲花池",
  29. pinyin: "baodinggulianhuchi",
  30. description: "始建于唐代,是保定市著名的风景名胜区,国家AAAA级旅游景区",
  31. address: "河北省保定市莲池区牌坊街67号",
  32. city: "保定",
  33. category: "景区",
  34. latitude: 38.8743,
  35. longitude: 115.4646,
  36. image: "/static/default_attraction.jpg"
  37. },
  38. {
  39. id: 998,
  40. name: "保定直隶总督署",
  41. pinyin: "baodingzhilizongedushu",
  42. description: "中国保存最完整的清代省级衙署,是河北省重点文物保护单位",
  43. address: "河北省保定市莲池区东风路1399号",
  44. city: "保定",
  45. category: "景区",
  46. latitude: 38.87346,
  47. longitude: 115.47486,
  48. image: "/static/default_attraction.jpg"
  49. },
  50. {
  51. id: 997,
  52. name: "保定野三坡景区",
  53. pinyin: "baodingyesanpo",
  54. description: "国家AAAAA级景区,以奇峰、怪石、峡谷、溶洞和清泉著称",
  55. address: "河北省保定市涞水县野三坡镇",
  56. city: "保定",
  57. category: "景区",
  58. latitude: 39.46082,
  59. longitude: 115.61501,
  60. image: "/static/default_attraction.jpg"
  61. }
  62. ]
  63. };
  64. },
  65. onLoad(options) {
  66. if (options.lat && options.lng && options.name) {
  67. this.latitude = parseFloat(options.lat);
  68. this.longitude = parseFloat(options.lng);
  69. this.targetSpotName = decodeURIComponent(options.name);
  70. this.scale = 15;
  71. common_vendor.index.__f__("log", "at pages/custom-trip/map.vue:176", `接收到景点定位参数: ${this.targetSpotName}, 坐标: ${this.latitude}, ${this.longitude}`);
  72. common_vendor.index.showToast({
  73. title: `定位到: ${this.targetSpotName}`,
  74. icon: "none",
  75. duration: 2e3
  76. });
  77. }
  78. this.initMap();
  79. common_vendor.index.showLoading({
  80. title: "加载景点数据..."
  81. });
  82. this.setDefaultBaodingSpots();
  83. this.getJingdian();
  84. },
  85. methods: {
  86. // 设置默认保定景点
  87. setDefaultBaodingSpots() {
  88. this.jingdian = [...this.defaultBaodingSpots];
  89. this.latitude = this.defaultBaodingSpots[0].latitude;
  90. this.longitude = this.defaultBaodingSpots[0].longitude;
  91. this.createMarkersFromJingdian();
  92. },
  93. // 查询景点数据
  94. getJingdian() {
  95. pages_api_luyou.findalls().then((res) => {
  96. common_vendor.index.__f__("log", "at pages/custom-trip/map.vue:218", "API返回原始数据:", JSON.stringify(res));
  97. common_vendor.index.hideLoading();
  98. if (res && res.code === 200) {
  99. this.apiResponse = res;
  100. let data = null;
  101. if (res.obj) {
  102. data = res.obj;
  103. common_vendor.index.__f__("log", "at pages/custom-trip/map.vue:233", "数据在res.obj中, 长度:", data.length);
  104. } else if (res.data && res.data.obj) {
  105. data = res.data.obj;
  106. common_vendor.index.__f__("log", "at pages/custom-trip/map.vue:236", "数据在res.data.obj中, 长度:", data.length);
  107. } else if (res.data) {
  108. data = res.data;
  109. common_vendor.index.__f__("log", "at pages/custom-trip/map.vue:239", "数据在res.data中, 长度:", data.length);
  110. } else {
  111. common_vendor.index.__f__("log", "at pages/custom-trip/map.vue:241", "尝试解析完整响应");
  112. data = res;
  113. }
  114. let apiJingdian = [];
  115. if (Array.isArray(data)) {
  116. apiJingdian = data;
  117. common_vendor.index.__f__("log", "at pages/custom-trip/map.vue:250", "直接使用数组数据, 长度:", apiJingdian.length);
  118. } else {
  119. for (const key in data) {
  120. if (Array.isArray(data[key]) && data[key].length > 0) {
  121. apiJingdian = data[key];
  122. common_vendor.index.__f__("log", "at pages/custom-trip/map.vue:256", `找到数组数据在${key}字段中, 长度:`, apiJingdian.length);
  123. break;
  124. }
  125. }
  126. }
  127. if (apiJingdian && apiJingdian.length > 0) {
  128. const processedApiData = apiJingdian.map((item) => {
  129. if (!item.latitude || !item.longitude) {
  130. common_vendor.index.__f__("log", "at pages/custom-trip/map.vue:267", `景点${item.name || "未命名"}没有坐标,尝试解析其他字段`);
  131. if (item.latitudeStr && item.longitudeStr) {
  132. item.latitude = parseFloat(item.latitudeStr);
  133. item.longitude = parseFloat(item.longitudeStr);
  134. common_vendor.index.__f__("log", "at pages/custom-trip/map.vue:273", `从latitudeStr/longitudeStr字段获取到坐标: ${item.latitude}, ${item.longitude}`);
  135. } else if (item.lat && item.lng) {
  136. item.latitude = parseFloat(item.lat);
  137. item.longitude = parseFloat(item.lng);
  138. common_vendor.index.__f__("log", "at pages/custom-trip/map.vue:277", `从lat/lng字段获取到坐标: ${item.latitude}, ${item.longitude}`);
  139. }
  140. }
  141. if (item.latitude)
  142. item.latitude = Number(item.latitude);
  143. if (item.longitude)
  144. item.longitude = Number(item.longitude);
  145. return item;
  146. }).filter((item) => {
  147. const hasValidCoords = item.latitude && item.longitude && !isNaN(Number(item.latitude)) && !isNaN(Number(item.longitude));
  148. if (!hasValidCoords) {
  149. common_vendor.index.__f__("log", "at pages/custom-trip/map.vue:291", `过滤掉无效坐标的景点: ${item.name || "未命名"}`);
  150. }
  151. return hasValidCoords;
  152. });
  153. common_vendor.index.__f__("log", "at pages/custom-trip/map.vue:296", `处理后的有效API景点数据: ${processedApiData.length}个`);
  154. this.jingdian = [...this.defaultBaodingSpots, ...processedApiData];
  155. common_vendor.index.__f__("log", "at pages/custom-trip/map.vue:301", "合并后总景点数据:", this.jingdian.length);
  156. if (this.jingdian.length > 0) {
  157. common_vendor.index.__f__("log", "at pages/custom-trip/map.vue:303", "第一条数据:", JSON.stringify(this.jingdian[0]));
  158. }
  159. common_vendor.index.showToast({
  160. title: `成功加载${this.jingdian.length}个景点`,
  161. icon: "success"
  162. });
  163. this.createMarkersFromJingdian();
  164. if (this.targetSpotName) {
  165. this.selectTargetSpot();
  166. }
  167. this.adjustMapViewToShowAllSpots();
  168. } else {
  169. common_vendor.index.__f__("log", "at pages/custom-trip/map.vue:322", "API未返回有效景点数据,继续使用默认景点");
  170. common_vendor.index.showToast({
  171. title: "使用默认景点数据",
  172. icon: "none"
  173. });
  174. if (this.targetSpotName) {
  175. this.selectTargetSpot();
  176. }
  177. }
  178. } else {
  179. common_vendor.index.__f__("error", "at pages/custom-trip/map.vue:334", "API返回错误:", res);
  180. common_vendor.index.showToast({
  181. title: res && res.message ? res.message : "查询失败,使用默认景点",
  182. icon: "none"
  183. });
  184. }
  185. }).catch((error) => {
  186. common_vendor.index.hideLoading();
  187. common_vendor.index.__f__("error", "at pages/custom-trip/map.vue:342", "查询失败:", error);
  188. common_vendor.index.showToast({
  189. title: "加载API景点失败,使用默认景点",
  190. icon: "none"
  191. });
  192. });
  193. },
  194. // 调整地图视野以包含所有景点
  195. adjustMapViewToShowAllSpots() {
  196. if (!this.jingdian || this.jingdian.length === 0)
  197. return;
  198. common_vendor.index.__f__("log", "at pages/custom-trip/map.vue:354", "调整地图视野以显示所有景点");
  199. let latSum = 0;
  200. let lngSum = 0;
  201. let validSpots = 0;
  202. this.jingdian.forEach((spot) => {
  203. if (spot.latitude && spot.longitude) {
  204. latSum += Number(spot.latitude);
  205. lngSum += Number(spot.longitude);
  206. validSpots++;
  207. }
  208. });
  209. if (validSpots > 0) {
  210. const centerLat = latSum / validSpots;
  211. const centerLng = lngSum / validSpots;
  212. common_vendor.index.__f__("log", "at pages/custom-trip/map.vue:376", `设置地图中心点为所有景点的地理中心: ${centerLat}, ${centerLng}`);
  213. this.latitude = centerLat;
  214. this.longitude = centerLng;
  215. }
  216. },
  217. // 从景点数据创建标记
  218. createMarkersFromJingdian() {
  219. if (!this.jingdian || this.jingdian.length === 0) {
  220. common_vendor.index.__f__("log", "at pages/custom-trip/map.vue:387", "景点数据为空");
  221. common_vendor.index.showToast({
  222. title: "景点数据为空",
  223. icon: "none"
  224. });
  225. return;
  226. }
  227. common_vendor.index.__f__("log", "at pages/custom-trip/map.vue:395", "开始创建标记,景点数据长度:", this.jingdian.length);
  228. [...this.markers];
  229. const poiMarkers = this.jingdian.filter((poi) => {
  230. if (!poi) {
  231. common_vendor.index.__f__("log", "at pages/custom-trip/map.vue:403", "发现无效的景点数据(null或undefined)");
  232. return false;
  233. }
  234. const hasCoords = poi.latitude && poi.longitude;
  235. if (!hasCoords) {
  236. common_vendor.index.__f__("log", "at pages/custom-trip/map.vue:409", `景点${poi.name || "未命名"}没有有效的坐标`);
  237. return false;
  238. }
  239. return true;
  240. }).map((poi, index) => {
  241. try {
  242. const lat = Number(poi.latitude);
  243. const lng = Number(poi.longitude);
  244. common_vendor.index.__f__("log", "at pages/custom-trip/map.vue:417", `处理景点 ID=${poi.id}, 名称=${poi.name}, 坐标: ${lat}, ${lng}`);
  245. if (isNaN(lat) || isNaN(lng)) {
  246. common_vendor.index.__f__("log", "at pages/custom-trip/map.vue:421", `景点${poi.name}的坐标转换为数字后不有效`);
  247. return null;
  248. }
  249. const iconType = poi.category || poi.type || "attraction";
  250. const iconPath = this.getMarkerIcon(iconType);
  251. return {
  252. id: poi.id || index + 1,
  253. latitude: lat,
  254. longitude: lng,
  255. title: poi.name || poi.title,
  256. iconPath,
  257. width: 36,
  258. // 增大标记尺寸以提高可见度
  259. height: 36,
  260. callout: {
  261. content: poi.name || poi.title,
  262. color: "#333333",
  263. fontSize: 12,
  264. borderRadius: 4,
  265. padding: 5,
  266. display: "BYCLICK"
  267. }
  268. };
  269. } catch (error) {
  270. common_vendor.index.__f__("error", "at pages/custom-trip/map.vue:447", `处理景点${poi.name || "未命名"}时出错:`, error);
  271. return null;
  272. }
  273. }).filter((marker) => marker !== null);
  274. common_vendor.index.__f__("log", "at pages/custom-trip/map.vue:452", `生成了${poiMarkers.length}个景点标记`);
  275. if (poiMarkers.length > 0) {
  276. common_vendor.index.__f__("log", "at pages/custom-trip/map.vue:454", "示例标记:", JSON.stringify(poiMarkers[0]));
  277. } else {
  278. common_vendor.index.__f__("log", "at pages/custom-trip/map.vue:456", "没有有效的景点标记生成");
  279. this.addTestMarker();
  280. return;
  281. }
  282. const selectedMarkers = this.selectedLocations.map((location, index) => {
  283. return {
  284. id: 1e3 + index,
  285. latitude: Number(location.latitude),
  286. longitude: Number(location.longitude),
  287. title: location.name,
  288. iconPath: "/static/marker_selected.png",
  289. // 使用绝对路径
  290. width: 40,
  291. height: 40,
  292. label: {
  293. content: (index + 1).toString(),
  294. color: "#FFFFFF",
  295. fontSize: 14,
  296. textAlign: "center",
  297. anchorX: 0,
  298. anchorY: -10
  299. }
  300. };
  301. });
  302. this.markers = [...poiMarkers, ...selectedMarkers];
  303. common_vendor.index.__f__("log", "at pages/custom-trip/map.vue:485", `总共有${this.markers.length}个标记点`);
  304. setTimeout(() => {
  305. this.checkMarkersVisibility();
  306. }, 1e3);
  307. },
  308. // 检查标记可见性
  309. checkMarkersVisibility() {
  310. common_vendor.index.__f__("log", "at pages/custom-trip/map.vue:495", "检查标记可见性");
  311. if (this.markers.length > 0) {
  312. common_vendor.index.__f__("log", "at pages/custom-trip/map.vue:497", "标记数量:", this.markers.length);
  313. common_vendor.index.__f__("log", "at pages/custom-trip/map.vue:498", "地图中心坐标:", this.latitude, this.longitude);
  314. const firstMarker = this.markers[0];
  315. if (firstMarker && firstMarker.latitude && firstMarker.longitude) {
  316. common_vendor.index.__f__("log", "at pages/custom-trip/map.vue:503", "移动地图到第一个标记:", firstMarker.latitude, firstMarker.longitude);
  317. this.latitude = firstMarker.latitude;
  318. this.longitude = firstMarker.longitude;
  319. this.scale = 14;
  320. }
  321. }
  322. },
  323. // 初始化地图
  324. initMap() {
  325. common_vendor.index.getLocation({
  326. type: "gcj02",
  327. success: (res) => {
  328. this.latitude = res.latitude;
  329. this.longitude = res.longitude;
  330. },
  331. fail: () => {
  332. common_vendor.index.showToast({
  333. title: "获取位置信息失败,使用默认位置",
  334. icon: "none"
  335. });
  336. }
  337. });
  338. },
  339. // 根据POI类型获取不同的图标
  340. getMarkerIcon(type) {
  341. const systemInfo = common_vendor.index.getSystemInfoSync();
  342. const platform = systemInfo.platform;
  343. common_vendor.index.__f__("log", "at pages/custom-trip/map.vue:535", "当前运行平台:", platform);
  344. const baseUrl = "/static/";
  345. let iconName;
  346. switch (type) {
  347. case "景区":
  348. case "著名景点":
  349. case "历史遗迹":
  350. case "attraction":
  351. iconName = "marker_attraction.png";
  352. break;
  353. case "酒店":
  354. case "住宿":
  355. case "hotel":
  356. iconName = "marker_hotel.png";
  357. break;
  358. case "美食":
  359. case "餐厅":
  360. case "restaurant":
  361. iconName = "marker_restaurant.png";
  362. break;
  363. case "购物":
  364. case "商场":
  365. case "shopping":
  366. iconName = "marker_shopping.png";
  367. break;
  368. default:
  369. iconName = "marker_default.png";
  370. }
  371. const iconPath = baseUrl + iconName;
  372. common_vendor.index.__f__("log", "at pages/custom-trip/map.vue:568", `选择的图标路径: ${iconPath}, 类型: ${type}`);
  373. return iconPath;
  374. },
  375. // 搜索位置
  376. searchLocation() {
  377. if (!this.searchKeyword.trim()) {
  378. return;
  379. }
  380. if (!this.jingdian || this.jingdian.length === 0) {
  381. common_vendor.index.showToast({
  382. title: "景点数据未加载",
  383. icon: "none"
  384. });
  385. return;
  386. }
  387. const result = this.jingdian.find(
  388. (poi) => (poi.name || "").includes(this.searchKeyword) || (poi.address || "").includes(this.searchKeyword) || (poi.description || "").includes(this.searchKeyword)
  389. );
  390. if (result && result.latitude && result.longitude) {
  391. this.latitude = Number(result.latitude);
  392. this.longitude = Number(result.longitude);
  393. this.scale = 15;
  394. common_vendor.index.showToast({
  395. title: `找到: ${result.name}`,
  396. icon: "none"
  397. });
  398. } else {
  399. common_vendor.index.showToast({
  400. title: "未找到相关位置",
  401. icon: "none"
  402. });
  403. }
  404. },
  405. // 点击标记
  406. onMarkerTap(e) {
  407. const markerId = e.markerId;
  408. common_vendor.index.__f__("log", "at pages/custom-trip/map.vue:613", "点击了标记:", markerId);
  409. if (markerId >= 1e3) {
  410. const index = markerId - 1e3;
  411. if (index >= 0 && index < this.selectedLocations.length) {
  412. this.currentIndex = index;
  413. return;
  414. }
  415. }
  416. const poi = this.jingdian.find((item) => item.id === markerId);
  417. if (poi) {
  418. let content = "";
  419. if (poi.description) {
  420. content += `描述: ${poi.description}
  421. `;
  422. }
  423. if (poi.address) {
  424. content += `地址: ${poi.address}
  425. `;
  426. }
  427. if (poi.category) {
  428. content += `类型: ${poi.category}
  429. `;
  430. }
  431. if (poi.city) {
  432. content += `城市: ${poi.city}
  433. `;
  434. }
  435. content += "是否添加到行程?";
  436. common_vendor.index.showModal({
  437. title: poi.name,
  438. content,
  439. confirmText: "添加",
  440. cancelText: "取消",
  441. success: (res) => {
  442. if (res.confirm) {
  443. const location = {
  444. id: poi.id,
  445. name: poi.name,
  446. latitude: Number(poi.latitude),
  447. longitude: Number(poi.longitude),
  448. address: poi.address || poi.city || "",
  449. type: poi.category || "attraction",
  450. description: poi.description || ""
  451. };
  452. this.addLocation(location);
  453. }
  454. }
  455. });
  456. }
  457. },
  458. // 添加地点到行程
  459. addLocation(location) {
  460. const exists = this.selectedLocations.some((item) => item.id === location.id);
  461. if (exists) {
  462. common_vendor.index.showToast({
  463. title: "该地点已在行程中",
  464. icon: "none"
  465. });
  466. return;
  467. }
  468. const standardizedLocation = {
  469. ...location,
  470. latitude: Number(location.latitude),
  471. longitude: Number(location.longitude)
  472. };
  473. common_vendor.index.__f__("log", "at pages/custom-trip/map.vue:687", "添加标准化后的地点:", standardizedLocation);
  474. this.selectedLocations.push(standardizedLocation);
  475. this.currentIndex = this.selectedLocations.length - 1;
  476. this.updateSelectedMarkers();
  477. common_vendor.index.showToast({
  478. title: "已添加到行程",
  479. icon: "success"
  480. });
  481. },
  482. // 移除地点
  483. removeLocation(index) {
  484. this.selectedLocations.splice(index, 1);
  485. if (this.currentIndex >= this.selectedLocations.length) {
  486. this.currentIndex = this.selectedLocations.length - 1;
  487. }
  488. this.updateSelectedMarkers();
  489. },
  490. // 选择地点
  491. selectLocation(index) {
  492. this.currentIndex = index;
  493. const location = this.selectedLocations[index];
  494. this.latitude = location.latitude;
  495. this.longitude = location.longitude;
  496. },
  497. // 清空所有地点
  498. clearAllLocations() {
  499. if (this.selectedLocations.length === 0)
  500. return;
  501. common_vendor.index.showModal({
  502. title: "确认清空",
  503. content: "确定要清空所有已添加的地点吗?",
  504. success: (res) => {
  505. if (res.confirm) {
  506. this.selectedLocations = [];
  507. this.currentIndex = -1;
  508. this.updateSelectedMarkers();
  509. }
  510. }
  511. });
  512. },
  513. // 保存行程
  514. saveTrip() {
  515. if (this.selectedLocations.length === 0) {
  516. common_vendor.index.showToast({
  517. title: "请至少添加一个地点",
  518. icon: "none"
  519. });
  520. return;
  521. }
  522. try {
  523. common_vendor.index.setStorageSync("selectedLocations", JSON.stringify(this.selectedLocations));
  524. common_vendor.index.navigateTo({
  525. url: "/pages/custom-trip/plan-detail",
  526. success: () => {
  527. common_vendor.index.__f__("log", "at pages/custom-trip/map.vue:756", "成功跳转到计划详情页");
  528. },
  529. fail: (err) => {
  530. common_vendor.index.__f__("error", "at pages/custom-trip/map.vue:759", "跳转到计划详情页失败:", err);
  531. common_vendor.index.showModal({
  532. title: "跳转失败",
  533. content: JSON.stringify(err),
  534. showCancel: false
  535. });
  536. }
  537. });
  538. } catch (e) {
  539. common_vendor.index.__f__("error", "at pages/custom-trip/map.vue:768", "保存位置数据失败:", e);
  540. common_vendor.index.showToast({
  541. title: "操作失败,请重试",
  542. icon: "none"
  543. });
  544. }
  545. },
  546. // 返回上一页
  547. goBack() {
  548. common_vendor.index.navigateBack();
  549. },
  550. // 更新选中的标记
  551. updateSelectedMarkers() {
  552. this.createMarkersFromJingdian();
  553. this.updatePolylines();
  554. },
  555. // 更新路线连线
  556. updatePolylines() {
  557. if (this.selectedLocations.length < 2) {
  558. this.polylines = [];
  559. this.markers = this.markers.filter((marker) => marker.id < 2e3 || marker.id >= 3e3);
  560. return;
  561. }
  562. const points = this.selectedLocations.map((location) => {
  563. return {
  564. latitude: Number(location.latitude),
  565. longitude: Number(location.longitude)
  566. };
  567. });
  568. this.polylines = [{
  569. points,
  570. color: "#1aad19",
  571. width: 4,
  572. dottedLine: false,
  573. arrowLine: true,
  574. borderColor: "#ffffff",
  575. borderWidth: 1
  576. }];
  577. let distanceMarkers = [];
  578. for (let i = 0; i < points.length - 1; i++) {
  579. const startPoint = points[i];
  580. const endPoint = points[i + 1];
  581. const distance = this.calculateDistance(
  582. startPoint.latitude,
  583. startPoint.longitude,
  584. endPoint.latitude,
  585. endPoint.longitude
  586. );
  587. const distanceText = distance < 1e3 ? `${Math.round(distance)}米` : `${(distance / 1e3).toFixed(1)}公里`;
  588. const midPoint = {
  589. latitude: (startPoint.latitude + endPoint.latitude) / 2,
  590. longitude: (startPoint.longitude + endPoint.longitude) / 2
  591. };
  592. distanceMarkers.push({
  593. id: 2e3 + i,
  594. // 距离标记ID从2000开始
  595. latitude: midPoint.latitude,
  596. longitude: midPoint.longitude,
  597. iconPath: "/static/marker_default.png",
  598. // 使用默认图标
  599. width: 0,
  600. // 设置为0使图标不可见
  601. height: 0,
  602. // 设置为0使图标不可见
  603. callout: {
  604. content: distanceText,
  605. color: "#333333",
  606. fontSize: 12,
  607. borderRadius: 4,
  608. borderWidth: 1,
  609. borderColor: "#1aad19",
  610. bgColor: "#ffffff",
  611. padding: 5,
  612. display: "ALWAYS"
  613. }
  614. });
  615. }
  616. const otherMarkers = this.markers.filter((marker) => marker.id < 2e3 || marker.id >= 3e3);
  617. this.markers = [...otherMarkers, ...distanceMarkers];
  618. },
  619. // 计算两点之间的距离(使用Haversine公式)
  620. calculateDistance(lat1, lon1, lat2, lon2) {
  621. const R = 6371e3;
  622. const dLat = this.deg2rad(lat2 - lat1);
  623. const dLon = this.deg2rad(lon2 - lon1);
  624. const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(this.deg2rad(lat1)) * Math.cos(this.deg2rad(lat2)) * Math.sin(dLon / 2) * Math.sin(dLon / 2);
  625. const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
  626. return R * c;
  627. },
  628. // 角度转弧度
  629. deg2rad(deg) {
  630. return deg * (Math.PI / 180);
  631. },
  632. // 选择目标景点(从热门目的地跳转来的)
  633. selectTargetSpot() {
  634. if (!this.targetSpotName || this.jingdian.length === 0) {
  635. return;
  636. }
  637. const targetSpot = this.jingdian.find(
  638. (spot) => spot.name === this.targetSpotName || spot.name.includes(this.targetSpotName) || this.targetSpotName.includes(spot.name) && spot.name.length > 2
  639. );
  640. if (targetSpot) {
  641. setTimeout(() => {
  642. const e = { markerId: targetSpot.id };
  643. this.onMarkerTap(e);
  644. }, 1e3);
  645. } else {
  646. common_vendor.index.__f__("log", "at pages/custom-trip/map.vue:908", `未找到匹配的目标景点: ${this.targetSpotName}`);
  647. }
  648. },
  649. // 地图加载完成后的处理
  650. onMapLoaded() {
  651. common_vendor.index.__f__("log", "at pages/custom-trip/map.vue:914", "地图加载完成");
  652. if (this.markers && this.markers.length > 0) {
  653. common_vendor.index.__f__("log", "at pages/custom-trip/map.vue:918", "当前地图标记数量:", this.markers.length);
  654. common_vendor.index.__f__("log", "at pages/custom-trip/map.vue:919", "第一个标记示例:", JSON.stringify(this.markers[0]));
  655. } else {
  656. common_vendor.index.__f__("log", "at pages/custom-trip/map.vue:921", "当前无地图标记");
  657. }
  658. this.refreshMarkers();
  659. },
  660. // 刷新地图标记
  661. refreshMarkers() {
  662. const validMarkers = this.markers.map((marker) => {
  663. const newMarker = { ...marker };
  664. if (typeof newMarker.latitude === "string") {
  665. newMarker.latitude = parseFloat(newMarker.latitude);
  666. }
  667. if (typeof newMarker.longitude === "string") {
  668. newMarker.longitude = parseFloat(newMarker.longitude);
  669. }
  670. if (isNaN(newMarker.latitude) || isNaN(newMarker.longitude)) {
  671. common_vendor.index.__f__("log", "at pages/custom-trip/map.vue:946", `忽略无效标记: ID=${newMarker.id}, 标题=${newMarker.title}`);
  672. return null;
  673. }
  674. newMarker.width = 36;
  675. newMarker.height = 36;
  676. return newMarker;
  677. }).filter((m) => m !== null);
  678. common_vendor.index.__f__("log", "at pages/custom-trip/map.vue:957", `刷新后有效标记数量: ${validMarkers.length}`);
  679. if (validMarkers.length > 0) {
  680. common_vendor.index.__f__("log", "at pages/custom-trip/map.vue:959", "刷新后第一个标记:", JSON.stringify(validMarkers[0]));
  681. }
  682. this.markers = validMarkers;
  683. if (validMarkers.length === 0) {
  684. common_vendor.index.__f__("log", "at pages/custom-trip/map.vue:967", "没有有效标记,添加一个默认测试标记");
  685. this.addTestMarker();
  686. }
  687. },
  688. // 添加测试标记
  689. addTestMarker() {
  690. common_vendor.index.__f__("log", "at pages/custom-trip/map.vue:974", "添加测试标记");
  691. const testMarker = {
  692. id: 9999,
  693. latitude: 38.8743,
  694. longitude: 115.4646,
  695. title: "测试标记",
  696. width: 20,
  697. height: 20,
  698. iconPath: "/static/marker_default.png",
  699. callout: {
  700. content: "测试标记",
  701. color: "#333333",
  702. fontSize: 12,
  703. borderRadius: 4,
  704. padding: 5,
  705. display: "ALWAYS"
  706. }
  707. };
  708. this.markers = [testMarker];
  709. common_vendor.index.__f__("log", "at pages/custom-trip/map.vue:996", "添加了测试标记:", JSON.stringify(testMarker));
  710. this.includePoints = [
  711. {
  712. latitude: testMarker.latitude,
  713. longitude: testMarker.longitude
  714. }
  715. ];
  716. },
  717. // 添加测试标记并显示
  718. addTestMarkerAndShow() {
  719. common_vendor.index.__f__("log", "at pages/custom-trip/map.vue:1009", "手动添加测试标记");
  720. const currentScale = this.scale;
  721. common_vendor.index.__f__("log", "at pages/custom-trip/map.vue:1013", "当前缩放级别:", currentScale);
  722. this.addTestMarker();
  723. setTimeout(() => {
  724. if (this.markers.length > 0) {
  725. const marker = this.markers[0];
  726. this.latitude = marker.latitude;
  727. this.longitude = marker.longitude;
  728. this.scale = currentScale;
  729. common_vendor.index.showToast({
  730. title: "已添加测试标记",
  731. icon: "success"
  732. });
  733. }
  734. }, 300);
  735. },
  736. // 显示标记信息
  737. showMarkersInfo() {
  738. if (this.markers.length > 0) {
  739. const info = {
  740. 总标记数: this.markers.length,
  741. 第一个标记: this.markers[0]
  742. };
  743. common_vendor.index.showModal({
  744. title: "标记信息",
  745. content: JSON.stringify(info, null, 2),
  746. showCancel: false
  747. });
  748. common_vendor.index.__f__("log", "at pages/custom-trip/map.vue:1046", "当前标记信息:", info);
  749. } else {
  750. common_vendor.index.showToast({
  751. title: "当前没有标记",
  752. icon: "none"
  753. });
  754. }
  755. },
  756. // 重新加载标记
  757. reloadMarkers() {
  758. common_vendor.index.__f__("log", "at pages/custom-trip/map.vue:1057", "重新加载标记");
  759. this.markers = [];
  760. this.createMarkersFromJingdian();
  761. common_vendor.index.showToast({
  762. title: `已重载${this.markers.length}个标记`,
  763. icon: "success"
  764. });
  765. },
  766. // 显示所有景点(手动方法)
  767. showAllSpots() {
  768. common_vendor.index.showModal({
  769. title: "显示所有景点",
  770. content: "调整地图视图以显示所有景点?这会改变地图缩放级别。",
  771. success: (res) => {
  772. if (res.confirm) {
  773. this.scale = 9;
  774. this.includePoints = this.markers.map((marker) => ({
  775. latitude: marker.latitude,
  776. longitude: marker.longitude
  777. }));
  778. this.showAllMarkers = true;
  779. if (this.markers.length > 0) {
  780. let latSum = 0, lngSum = 0;
  781. this.markers.forEach((marker) => {
  782. latSum += marker.latitude;
  783. lngSum += marker.longitude;
  784. });
  785. this.latitude = latSum / this.markers.length;
  786. this.longitude = lngSum / this.markers.length;
  787. common_vendor.index.showToast({
  788. title: "已显示所有景点",
  789. icon: "success"
  790. });
  791. }
  792. }
  793. }
  794. });
  795. },
  796. // 重置地图视图
  797. resetView() {
  798. this.showAllMarkers = false;
  799. this.scale = 14;
  800. if (this.defaultBaodingSpots.length > 0) {
  801. this.latitude = this.defaultBaodingSpots[0].latitude;
  802. this.longitude = this.defaultBaodingSpots[0].longitude;
  803. }
  804. common_vendor.index.showToast({
  805. title: "已重置地图视图",
  806. icon: "success"
  807. });
  808. }
  809. }
  810. };
  811. function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
  812. return common_vendor.e({
  813. a: common_vendor.o((...args) => $options.goBack && $options.goBack(...args)),
  814. b: $data.latitude,
  815. c: $data.longitude,
  816. d: $data.markers,
  817. e: $data.scale,
  818. f: common_vendor.o((...args) => $options.onMarkerTap && $options.onMarkerTap(...args)),
  819. g: $data.polylines,
  820. h: common_vendor.o((...args) => $options.onMapLoaded && $options.onMapLoaded(...args)),
  821. i: $data.showAllMarkers ? $data.includePoints : [],
  822. j: common_vendor.o((...args) => $options.searchLocation && $options.searchLocation(...args)),
  823. k: $data.searchKeyword,
  824. l: common_vendor.o(($event) => $data.searchKeyword = $event.detail.value),
  825. m: common_vendor.o((...args) => $options.addTestMarkerAndShow && $options.addTestMarkerAndShow(...args)),
  826. n: common_vendor.o((...args) => $options.showMarkersInfo && $options.showMarkersInfo(...args)),
  827. o: common_vendor.o((...args) => $options.reloadMarkers && $options.reloadMarkers(...args)),
  828. p: common_vendor.o((...args) => $options.showAllSpots && $options.showAllSpots(...args)),
  829. q: $data.showAllMarkers
  830. }, $data.showAllMarkers ? {
  831. r: common_vendor.o((...args) => $options.resetView && $options.resetView(...args))
  832. } : {}, {
  833. s: common_vendor.t($data.selectedLocations.length),
  834. t: $data.selectedLocations.length > 0
  835. }, $data.selectedLocations.length > 0 ? {
  836. v: common_vendor.f($data.selectedLocations, (item, index, i0) => {
  837. return {
  838. a: common_vendor.t(index + 1),
  839. b: common_vendor.t(item.name),
  840. c: common_vendor.t(item.address),
  841. d: common_vendor.o(($event) => $options.removeLocation(index), index),
  842. e: index,
  843. f: $data.currentIndex === index ? 1 : "",
  844. g: common_vendor.o(($event) => $options.selectLocation(index), index)
  845. };
  846. })
  847. } : {}, {
  848. w: common_vendor.o((...args) => $options.clearAllLocations && $options.clearAllLocations(...args)),
  849. x: common_vendor.o((...args) => $options.saveTrip && $options.saveTrip(...args)),
  850. y: $data.selectedLocations.length === 0 ? 1 : ""
  851. });
  852. }
  853. const MiniProgramPage = /* @__PURE__ */ common_vendor._export_sfc(_sfc_main, [["render", _sfc_render]]);
  854. wx.createPage(MiniProgramPage);
  855. //# sourceMappingURL=../../../.sourcemap/mp-weixin/pages/custom-trip/map.js.map