活动介绍
file-type

KC-Track: 采用高德地图工厂模式开发的纠偏与动画技术

ZIP文件

下载需积分: 10 | 15KB | 更新于2024-11-27 | 31 浏览量 | 1 下载量 举报 收藏
download 立即下载
该工具库可以支持多种纠偏方式,包括但不限于两点纠偏、500个点纠偏、40个点纠偏以及不纠偏等。它适用于vue2.x项目,通过初始化地图来创建一个TrackFactory实例,这个实例允许开发者定义多个钩子函数来响应不同的操作事件,例如纠偏时的correctOnce钩子和marker移动结束时的movingEnd钩子。" 在深入分析kc-track的知识点之前,我们首先需要了解几个关键概念和背景知识: 1. 高德地图API:高德地图是中国领先的数字地图、导航和位置服务提供商。高德地图API是一系列接口和服务,允许开发者在应用程序中集成高德地图功能。开发者使用高德地图API可以获取地图数据、进行路径规划、搜索位置、定位用户等。 2. JavaScript:JavaScript是一种高级的、解释执行的编程语言,广泛用于网页开发中。它使得网页具有交互性,并且可以用来开发复杂的网页应用。 3. Vue.js:Vue.js是一个流行的渐进式JavaScript框架,主要用于构建用户界面。它易于上手,同时又足够灵活,能够根据项目需求扩展为复杂的单页应用。 基于以上背景,kc-track的知识点可以从以下几个方面进行详细阐述: - 高德地图工厂模式:工厂模式是一种创建型设计模式,用于创建对象而不必指定将要创建的对象的具体类。在高德地图的上下文中,工厂模式允许开发者以一种更灵活的方式来创建地图实例,而不需要关注内部实现的细节。 - 纠偏:在地图应用中,纠偏指的是校正地图上位置信息的准确性。这通常因为各种原因(如GPS误差、地图数据更新等)导致用户在地图上的实际位置与显示位置存在偏差,纠偏操作是为了保证位置显示的准确性。 - 绘制路线:在地图上绘制路线通常涉及到规划路径和在地图上绘制出所规划路径的功能。开发者可以使用高德地图API提供的路径规划服务来规划路线,并利用API提供的绘制工具来在地图上绘制出来。 - marker移动动画:Marker是在地图上用以标记特定位置的图形标识。Marker移动动画通常是为了增加用户交互体验,使***r在地图上移动时能够平滑地从一个位置移动到另一个位置。 - vue2.x项目:vue2.x是Vue.js的第二个主要版本,它提供了一种构建用户界面的系统,通过数据驱动和组件化的概念使得开发复杂的单页应用变得更加简单。 - TrackFactory:TrackFactory是一个工厂类,它负责实例化并提供地图功能相关的对象。在kc-track中,开发者可以利用TrackFactory来创建地图实例并配置相关参数。 - initMap函数:在Vue项目中,initMap函数通常用来初始化地图,设置地图相关参数并创建地图实例。该函数返回一个Promise对象,允许开发者以异步的方式处理地图初始化完成后的逻辑。 - correctOnce钩子:当进行纠偏操作时,开发者可以通过correctOnce钩子函数来响应纠偏事件。这个钩子函数会接收一些数据参数,这些参数通常包含纠偏前后的坐标信息等。 - movingEnd钩子:在marker移动动画结束时,movingEnd钩子函数会被调用。开发者可以通过这个钩子来处理移动结束后的逻辑,例如更新UI、记录日志等。 - 节点纠偏:节点纠偏是纠偏操作中的一种,它根据一组特定的节点(点)来进行校正。在kc-track中,开发者可以设置纠偏节点的数量,以适应不同情况下的需求。 通过上述知识点的详细解释,我们可以看到kc-track工具库为使用高德地图API开发的Vue.js项目提供了一整套解决方案,使得开发者可以更加方便地进行地图功能的开发和优化用户体验。

相关推荐

filetype
filetype

function updateMarkerContent(markerData) { // 1. 先关闭已打开的详情(关键步骤) resetActiveMarker(); // 2. 处理当前标记 const markerKey = `${markerData.lng},${markerData.lat}`; const marker = markerInstances[markerKey]; if (!marker) { console.error('未找到标记点实例:', markerKey); return; } // 3. 存储原始数据到marker(用于后续重置时获取) marker.originalData = markerData; // 4. 生成详情样式content const content = `
${markerData.title}
${markerData.desc || '暂无描述'}
`; // 5. 更新为详情样式 marker.setContent(content); marker.setOffset(new AMap.Pixel(-110, -200)); // 6. 记录当前活跃标记 currentActiveMarkerKey = markerKey; }给这个盒子最外层的右边上面添加两个图片。竖向排列,一个是map_back一个是map_detail,点击第一个图片,返回聚合点样式,关闭当前详情,点击第二个是跳转到详情页面(pages/achievements/index),以下是map.html所有的代码 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <title>高德地图</title> <script src="https://cdn.bootcss.com/vue/2.6.11/vue.js"></script> <style> #map-container { width: 100%; height: 584px; border-radius: 22px; z-index: 4; } /* 新增:隐藏高德默认标记图标 */ #map-container .amap-marker img[src*="mark_bs.png"] { display: none !important; } </style> </head> <body>
<script type="text/javascript" src="./js/uni.webview.0.1.52.js"> </script> <script> window._AMapSecurityConfig = { securityJsCode: 'cf331d54f67e306ca5c0b17f7122d559' }; </script> <script src="https://webapi.amap.com/maps?v=2.0&key=f3323c24769b10828db07f07c0fcec0d&plugin=AMap.MarkerCluster"> </script> <script src="https://webapi.amap.com/ui/1.1/main.js"></script> <script> // 确保UniApp通信桥接准备就绪 function setupUniBridge() { return new Promise(resolve => { // H5环境直接就绪(无需等待UniApp桥接) if (isH5Environment()) { return resolve(); } // App环境逻辑不变 if (typeof uni.postMessage === 'function') { return resolve(); } document.addEventListener('UniAppJSBridgeReady', resolve); }); } // 向UniApp发送消息(兼容H5和App环境) async function sendMessageToUniApp(data) { // console.log('当前环境是否为H5--11:', this.isH5Environment()); // 应打印true(H5环境) // 1. 确保桥接就绪(仅对App环境有效,H5环境会直接resolve) await setupUniBridge(); // 2. 区分环境发送消息 if (isH5Environment()) { // H5环境:使用浏览器原生postMessage // console.log('H5环境,使用window.parent.postMessage发送消息'); window.parent.postMessage({ type: 'webviewMessage', // 自定义类型,方便UniApp识别 data: JSON.stringify(data) }, '*'); // 第三个参数为目标域名,*表示允许所有(开发环境可用,生产环境需指定具体域名) } else if (window.uni && typeof uni.postMessage === 'function') { // App环境:使用uni.postMessage // console.log('App环境,使用uni.postMessage发送消息'); uni.postMessage({ data: JSON.stringify(data) }); } else { console.error('未支持的环境,无法发送消息'); } } // 辅助函数:判断是否为H5环境(浏览器环境) function isH5Environment() { const protocol = window.location.protocol; // H5环境的协议通常是http:或https: return protocol === 'http:' || protocol === 'https:'; } // 解析URL参数 const params = new URLSearchParams(location.search); const points = JSON.parse(params.get('points') || '[]'); const markers = JSON.parse(params.get('markers') || '[]'); const center = JSON.parse(params.get('center') || '[]'); console.log(center, '解析URL参数'); // 初始化地图 const map = new AMap.Map('map-container', { zoom: 10, center: center || [106.283333, 38.466667], // [markers[0].lng, markers[0].lat] showBuildingBlock: true }); // 新增:存储所有标记点实例(key为"lng,lat",值为标记点对象) const markerInstances = {}; // 自定义单个标记内容(保持原有样式,修复图片路径) function createMarkerContent(markerData) { // 优先使用本地图片,失败则用备用图(确保是自定义图标) const imageUrl = './img/flag.png'; return `
${markerData.title}
${markerData.title}
`; } // 聚合点渲染函数 function _renderClusterMarker(context) { const count = context.count; console.log('渲染聚合点,数量:', count); // 通过JS直接设置样式(优先级更高) const div = document.createElement('div'); div.innerHTML = count; // 强制设置关键样式(覆盖默认) div.style.width = '40px'; div.style.height = '40px'; div.style.backgroundColor = '#E3383B'; div.style.borderRadius = '50%'; div.style.display = 'flex'; div.style.alignItems = 'center'; div.style.justifyContent = 'center'; div.style.color = 'white'; div.style.fontWeight = 'bold'; // 设置聚合点偏移(确保居中) context.marker.setOffset(new AMap.Pixel(-20, -20)); context.marker.setContent(div); // 通过context.marker设置内容 } // 单个标记渲染函数 function _renderMarker(context) { const markerData = context.data[0].originalData; // 生成唯一key(lng+lat) const markerKey = `${markerData.lng},${markerData.lat}`; // 1. 生成标记内容 const content = createMarkerContent(markerData); // 2. 设置标记内容 context.marker.setContent(content); // 3. 校准偏移量(根据内容尺寸计算,确保标记中心与经纬度对齐) // 内容总高度:图片30px + 标题区域20px = 50px,向上偏移50px使底部对齐定位点 context.marker.setOffset(new AMap.Pixel(-15, -50)); // 水平偏移:30px宽/2=15px // 初始化时就设置originalData context.marker.originalData = markerData; // 4. 存储标记点实例到全局对象 markerInstances[markerKey] = context.marker; // 5. 绑定点击事件 context.marker.on('click', async () => { // 若点击的是已打开的标记,则关闭它 if (currentActiveMarkerKey === markerKey) { resetActiveMarker(); return; } const message = { type: 'markerClick', data: markerData }; // console.log('H5发送消息:', message); // 优先使用uni.postMessag await sendMessageToUniApp({ type: 'markerClick', data: markerData }); }); } // 记录当前活跃的标记点key(lng,lat) let currentActiveMarkerKey = null; // 新增:重置活跃标记为默认样式 function resetActiveMarker() { if (!currentActiveMarkerKey) return; const marker = markerInstances[currentActiveMarkerKey]; if (!marker) { currentActiveMarkerKey = null; return; } // 1. 尝试获取marker.originalData let markerData = marker.originalData; // 2. 若不存在,则从原始markers数组中查找 if (!markerData) { const [lng, lat] = currentActiveMarkerKey.split(','); markerData = markers.find(m => m.lng.toString() === lng && m.lat.toString() === lat ); } // 3. 双重校验,确保markerData存在 if (!markerData) { console.warn('未找到标记点原始数据,无法重置:', currentActiveMarkerKey); currentActiveMarkerKey = null; return; } // 4. 安全恢复默认样式 marker.setContent(createMarkerContent(markerData)); marker.setOffset(new AMap.Pixel(-15, -50)); currentActiveMarkerKey = null; } // H5 接收 UniApp 指令,更新标记点内容的函数 function updateMarkerContent(markerData) { // 1. 先关闭已打开的详情(关键步骤) resetActiveMarker(); // 2. 处理当前标记 const markerKey = `${markerData.lng},${markerData.lat}`; const marker = markerInstances[markerKey]; if (!marker) { console.error('未找到标记点实例:', markerKey); return; } // 3. 存储原始数据到marker(用于后续重置时获取) marker.originalData = markerData; // 4. 生成详情样式content const content = `
${markerData.title}
${markerData.desc || '暂无描述'}
`; // 5. 更新为详情样式 marker.setContent(content); marker.setOffset(new AMap.Pixel(-110, -200)); // 6. 记录当前活跃标记 currentActiveMarkerKey = markerKey; } // 绘制路线(保持原有功能) function drawRouteAndPoints() { if (points.length === 0) return; const path = points.map(p => [p.lng, p.lat]); new AMap.Polyline({ path: path, strokeColor: "#32CD32", strokeWeight: 5, zIndex: 500, map: map }); if (points.length >= 2) { AMap.plugin('AMap.Driving', () => { const driving = new AMap.Driving({ map: map, policy: AMap.DrivingPolicy.LEAST_TIME, zIndex: 550 }); driving.search( [points[0].lng, points[0].lat], [points[points.length - 1].lng, points[points.length - 1].lat] ); }); } } // 初始化聚合标记 function initClusterMarkers() { if (!markers.length) return; // 转换数据格式为官方示例要求的结构(包含lnglat字段) const clusterPoints = markers.map(marker => ({ lnglat: new AMap.LngLat(marker.lng, marker.lat), // 官方要求的经纬度格式 originalData: marker // 保留原始数据供渲染使用 })); // 参考官方示例:插件加载后初始化聚合 AMap.plugin('AMap.MarkerCluster', function() { if (typeof AMap.MarkerCluster === 'undefined') { console.error('聚合插件加载失败'); return; } // 配置聚合参数 const cluster = new AMap.MarkerCluster(map, clusterPoints, { gridSize: 80, // 网格大小(官方示例默认60,可调整) maxZoom: 15, // 最大聚合级别 minClusterSize: 2, // 最小聚合数量(测试时可改为1) zoomOnClick: true, averageCenter: true, // zIndex: 2000, // 聚合点参数名 renderClusterMarker: _renderClusterMarker, // 单个标记参数名 renderMarker: _renderMarker }); // 调整视野 // const bounds = new AMap.Bounds(); // clusterPoints.forEach(point => bounds.extend(point.lnglat)); // map.setBounds(bounds, [50, 50, 50, 50]); }); } // 地图加载完成后初始化 map.on('complete', function() { console.log('地图加载完成,初始化组件'); initClusterMarkers(); if (points.length > 0) drawRouteAndPoints(); }); map.on('error', (err) => console.error('地图错误:', err)); // 构建带标题的HTML内容 // markers.forEach(marker => { // // 构建HTML内容(包含图片和标题) // const content = ` //
//
闽宁新貌展示中心
//
// 闽宁新貌展示中心,生动呈现闽宁协作丰硕成果,见证昔日“干沙滩”蜕变为今日“金沙滩”的壮丽历程。
// //
// `; // const markerObj = new AMap.Marker({ // position: [marker.lng, marker.lat], // content: content, // 使用HTML内容 // anchor: 'bottom-center', // 锚点在底部中心 // offset: new AMap.Pixel(0, -25) // 向上偏移 // }); // markerObj.on('click', () => { // console.log('window--uni', uni, window); // // console.log(marker, '000'); // // 将数据转为字符串 // const message = JSON.stringify({ // type: 'markerClick', // title: marker.title // }); // window.parent.postMessage(message, '*'); // // 通过uni.postMessage发送数据 // // uni.postMessage({ // // data: JSON.stringify(message) // 发送字符串 // // }); // }); // map.add(markerObj); // }); // 2. 在map加载完成后初始化聚合点 // map.on('complete', function() { // // 创建聚合实例 // const cluster = new AMap.MarkerClusterer(map, markers.map(m => { // return new AMap.Marker({ // position: [m.lng, m.lat], // content: createMarkerContent(m) // 自定义标记 // }); // }), { // gridSize: 80, // maxZoom: 18, // renderClusterMarker: renderCluster // }); // // // 转换数据格式 // // const clusterPoints = markers.map(marker => ({ // // lnglat: [marker.lng, marker.lat], // // title: marker.title, // // originalData: marker // 保留原始数据 // // })); // // console.log('在map加载完成后初始化聚合点', clusterPoints); // // // 确保有聚合点数据 // // if (clusterPoints.length === 0) return; // // 使用MarkerCluster插件 // // AMap.plugin('AMap.MarkerCluster', function() { // // console.log("聚合插件加载完成"); // // // 创建聚合点 // // const cluster = new AMap.MarkerCluster(map, clusterPoints, { // // gridSize: 80, // 聚合网格像素大小 // // maxZoom: 18, // 最大聚合级别 // // minClusterSize: 2, // 最小聚合数量 // // zoomOnClick: true, // 点击聚合点是否放大地图 // // averageCenter: true, // 聚合点是否使用平均值中心 // // // 定义聚合点样式 // // renderClusterMarker: function(context) { // // console.log('定义聚合点样式-context', context); // // // const count = context.count; // // // const div = document.createElement('div'); // // // div.innerHTML = ` // // //
// // // ${count} // // //
// // // `; // // const count = context.count; // // const div = document.createElement('div'); // // div.style.background = '#FF9A44'; // // div.style.borderRadius = '50%'; // // div.style.width = '40px'; // // div.style.height = '40px'; // // div.style.display = 'flex'; // // div.style.alignItems = 'center'; // // div.style.justifyContent = 'center'; // // div.style.color = 'white'; // // div.style.fontWeight = 'bold'; // // div.style.zIndex = '99'; // // div.innerHTML = count; // // // context.marker.setContent(div); // // return div; // // }, // // // 自定义标记点样式 // // renderMarker: function(context) { // // const markerData = context.data[0].originalData; // // // console.log('自定义标记点样式-context', context); // // // const marker = new AMap.Marker({ // // // position: [markerData.lng, markerData.lat], // // // content: ` // // //
// // // // // //
// // // ${markerData.title} // // //
// // //
// // // `, // // // offset: new AMap.Pixel(0, 0) // // // }); // // // 创建自定义内容 // // const content = ` // //
// // // //
// // ${markerData.title}
`; // // const marker = new AMap.Marker({ // // position: [markerData.lng, markerData.lat], // // content: content, // // offset: new AMap.Pixel(-2, -4) // 根据实际图片调整偏移 // // }); // // // 绑定聚合点点击事件 // // // marker.on('click', async function(e) { // // // console.log(e, 'bbbbb'); // // // sendMessageToUniApp({ // // // type: 'markerClick', // // // center: e.lnglat // // // }); // // // }); // // // // console.log('聚合点点', marker); // // // map.add(marker); // // // 绑定标记点击事件 // // marker.on('click', async function(e) { // // 发送消息给UniApp // // await sendMessageToUniApp({ // // type: 'markerClick', // // data: markerData // // }); // // }); // // return marker; // // }, // // }); // // // 绑定聚合点点击事件 // // cluster.on('click', async function(e) { // // console.log(e, 'bbbbb'); // // // 发送聚合点点击事件 // // await sendMessageToUniApp({ // // type: 'clusterClick', // // data: { // // count: e.clusterData.count, // // center: e.clusterData.center, // // markers: e.clusterData.markers // // } // // }); // // }); // // }); // }); // 2. 绘制路线 // const path = points.map(p => [p.lng, p.lat]); // new AMap.Polyline({ // path: path, // strokeColor: "#32CD32", // strokeWeight: 5, // map: map // }); // 3. 添加起点终点标记 // points.forEach((point, i) => { // new AMap.Marker({ // position: [point.lng, point.lat], // // content: `
${i === 0 ? '起' : '终'}
`, // offset: new AMap.Pixel(-10, -10), // map: map // }); // }); // 4. 绘制驾车路径(如果需要,可以注释掉直线路径,保留驾车路径) // 注意:这里同时绘制了直线和驾车路径,可能会重叠 // if (points.length >= 2) { // AMap.plugin('AMap.Driving', () => { // const driving = new AMap.Driving({ // map: map, // 这样驾车路线会直接显示在地图上 // policy: AMap.DrivingPolicy.LEAST_TIME // }); // driving.search( // [points[0].lng, points[0].lat], // [points[points.length - 1].lng, points[points.length - 1].lat], // (status, result) => { // // 可以根据结果处理 // } // ); // }); // } // 1. 绘制路线 // if (points.length > 0) { // const path = points.map(p => [p.lng, p.lat]); // new AMap.Polyline({ // path: path, // strokeColor: "#32CD32", // strokeWeight: 5, // map: map // }); // // 添加起点终点标记 // points.forEach((point, i) => { // new AMap.Marker({ // position: [point.lng, point.lat], // offset: new AMap.Pixel(-10, -10), // map: map // }); // }); // // 绘制驾车路径(如果需要) // if (points.length >= 2) { // AMap.plugin('AMap.Driving', () => { // const driving = new AMap.Driving({ // map: map, // policy: AMap.DrivingPolicy.LEAST_TIME // }); // driving.search( // [points[0].lng, points[0].lat], // [points[points.length - 1].lng, points[points.length - 1].lat] // ); // }); // } // } </script> </body> </html>

可吸不是泥
  • 粉丝: 39
上传资源 快速赚钱