平台地址:http://lbs.amap.com/api/javascript-api/example/amap-ui-districtcluster/custom-cluster-markerjavascript
在作以前得科普一下,百度和高德,谷歌的经纬度是有误差的。php
了解经纬度误差缘由(pc测试可先不考虑,高德地图api定位在移动端显示定位失败,故采用百度地图获取经纬度,而后传给高德api转化坐标):css
适用场景html
为了使用高德服务,用户须要将非高德坐标转换为高德坐标。java
地址:http://lbs.amap.com/api/webservice/guide/api/convert/web
地址:http://www.gpsspg.com/maps.htmajax
2.示例中心:http://lbs.amap.com/api/javascript-api/example/amap-ui-simplemarker/indexapi
<!doctype html> <html lang="zh-CN"> <head> <!-- 原始地址://webapi.amap.com/ui/1.0/ui/geo/DistrictCluster/examples/plus-point-simplifier.html --> <!--<base href="//webapi.amap.com/ui/1.0/ui/geo/DistrictCluster/examples/" />--> <meta charset="utf-8"> <meta name="viewport" content="initial-scale=0.8, user-scalable=yes, width=device-width"> <title>区划聚合+海量点展现+定位+自定义标记</title> <link rel="stylesheet" href="http://cache.amap.com/lbs/static/main1119.css"/> <!--调整容器大小和一些目标地点样式大小,一级隐藏,须要使用--> <link rel="stylesheet" href="css/map_common.css"> <!--定位坐标的css样式,带一些水波效果,能够不加,在updateMarker生成标记的地方,用img的url连接便可--> <link rel="stylesheet" href="css/ico_position.css"> <!--一些样式修改和遮罩弹框样式,能够不加,默认是显示的,经过js触发显示和关闭--> <link rel="stylesheet" href="css/map_plus.css"> <!--高德自带,须要使用--> <script type="text/javascript" src='//webapi.amap.com/maps?v=1.4.3&key=d59a0ae0dd2a9b17cbbc480bea2f2033'></script> <!-- UI组件库 1.0 --> <script src="//webapi.amap.com/ui/1.0/main.js?v=1.0.11"></script> <!--如下为工具使用,好比公交,和高德自身定位,如下代码暂不使用--> <!--<script type="text/javascript"--> <!--src="http://webapi.amap.com/maps?v=1.4.3&key=你的高德地图秘钥&plugin=AMap.Transfer"></script>--> <!--<script type="text/javascript" src="http://cache.amap.com/lbs/static/addToolbar.js"></script>--> </head> <body id="body"> <div id="container"></div> <script type="text/javascript"> //建立地图 var map = new AMap.Map('container', { resizeEnable: true, expandZoomRange: true, zoom: 10, zooms: [10, 16], cursor: 'default', center: [122.947398, 34.351598]/*中心肯定暂时用不上*/ }); // 地图初始化 function initPage(DistrictCluster, PointSimplifier, $) { // 1.具体坐标点设置 var pointSimplifierIns = new PointSimplifier({ map: map, //所属的地图实例 autoSetFitView: false, //禁止自动更新地图视野 zIndex: 110, getPosition: function (item) { if (!item) { return null; } var parts = item.split(','); //返回经纬度 return [parseFloat(parts[0]), parseFloat(parts[1]), parts[2]]; }, getHoverTitle: function (dataItem) { var parts1 = dataItem.split(','); return parts1[2]; }, renderOptions: { //点的样式 pointStyle: { width: 20, height: 20, fillStyle: 'rgba(55, 175, 55, 0.8)', }, // hover层级大小 pointHoverStyle: { width: 20, height: 20, fillStyle: 'rgba(255, 175, 55, 0.8)', }, // 点击范围大小 pointHardcoreStyle: { width: 50, height: 50, lineWidth: 3, }, //鼠标hover时的title信息 hoverTitleStyle: { position: 'left', offset: [3, 0], }, } }); // 2.地区块设置 var distCluster = new DistrictCluster({ zIndex: 102, map: map, //所属的地图实例 getPosition: function (item) { if (!item) { return null; } var parts = item.split(','); //返回经纬度 return [parseFloat(parts[0]), parseFloat(parts[1]), parts[2]]; }, renderOptions: { featureStyle: { fillStyle: 'rgba(0, 0, 0, 1)', lineWidth: 1, strokeStyle: 'rgba(55, 175, 55, 0.8)', hoverOptions: { fillStyle: 'rgba(255, 0, 0, 0.2)', lineWidth: 2, strokeStyle: 'rgba(255, 0, 0, 0.8)' } }, //直接定义某写区划面的样式 getFeatureStyle: function(feature, dataItems) { if (dataItems.length > 2) { return { fillStyle: 'rgba(0, 0, 0, 0.6)' }; } else if (dataItems.length > 1) { return { fillStyle: 'rgba(0, 0, 0, 0.6)' }; } return {}; }, featureEventSupport: true, clusterMarkerEventSupport: true, clusterMarkerEventNames: ['click', 'rightclick', 'mouseover', 'mouseout'], //显示在所辖数据点的平均位置 getClusterMarkerPosition: DistrictCluster.ClusterMarkerPositionStrategy.AVERAGE_POINTS_POSITION, getClusterMarker: function (feature, dataItems, recycledMarker) { //label内容 var name3 = feature.properties.name.length < 4 ? feature.properties.name : (feature.properties.name[0] + feature.properties.name[1]) var content = name3 + '<br />' + dataItems.length + '个'; var label = { offset: new AMap.Pixel(0, 0), //修改label相对于marker的位置 //----------要改等级--------- // content: map.getZoom() > 13 ? content : null content: content }; if (dataItems.length > 0) { //存在可回收利用的marker if (recycledMarker) { //直接更新内容返回 recycledMarker.setLabel(label); return recycledMarker; } //返回一个新的Marker return new AMap.Marker({ //----------要改等级--------- // label: map.getZoom() > 13 ? label : null, label: label, }); } } } }); window.distCluster = distCluster; //根据当前zoom调整点的尺寸,大小 // 3.自定义定位 function selfPosition() { addMarker(); // 实例化点标记 function addMarker() { marker = new AMap.Marker({}); marker.setMap(map); } function updateMarker() { // 自定义点标记内容 var markerContent = document.createElement("div"); // 点标记中的图标 var ico_position = document.createElement("div"); ico_position.className = 'ico_position'; var pin = document.createElement("div"); pin.className = 'pin'; var pulse = document.createElement("div"); pulse.className = 'pulse'; markerContent.appendChild(ico_position); ico_position.appendChild(pin); ico_position.appendChild(pulse); // 点标记中的文本 var markerSpan = document.createElement("span"); markerSpan.className = 'marker'; markerSpan.innerHTML = "我在这"; markerContent.appendChild(markerSpan); ////如下为默认图片展现 //// 点标记中的图标 //var markerImg = document.createElement("img"); //markerImg.className = "markerlnglat"; //markerImg.src = "http://webapi.amap.com/theme/v1.3/markers/n/mark_r.png"; //markerContent.appendChild(markerImg); //// 点标记中的文本 //var markerSpan = document.createElement("span"); //markerSpan.className = 'marker'; //markerSpan.innerHTML = "Hi,我换新装备啦!"; //markerContent.appendChild(markerSpan); marker.setContent(markerContent); //更新点标记内容 marker.setPosition([108.992398, 34.256198]); //更新点标记位置,若是是固定的这么写下面不用转化坐标了 //百度坐标转化高德坐标,使用高德api坐标(如下为php程序调用发送{$xpoint}, {$ypoint}坐标点) // htmlobj = $.ajax({ // url: "http://restapi.amap.com/v3/assistant/coordinate/convert?key=c67d73f88613f4f574df092a93602c43&locations={$xpoint},{$ypoint}&coordsys=baidu", // async: false // }); // var obj = JSON.parse(htmlobj.responseText); // var parts1 = obj.locations.split(','); // console.log('精度:',parts1[0],'纬度:',parts1[1]) // marker.setPosition([parts1[0], parts1[1]]); //更新点标记位置 // console.log('x坐标:', {$xpoint}, 'y坐标:', {$ypoint}); } updateMarker(); } selfPosition(); // 4.刷新显示 function refresh() { var zoom = map.getZoom(); if (zoom < 13) { $('.amap-marker-label').show()//区县显示内容 pointSimplifierIns.hide();//具体坐标点显示 } else if (zoom > 16) { map.setZoom(12); } else { $('.amap-marker-label').hide();//区县显示内容 pointSimplifierIns.show();//具体坐标点显示 } } // 5.监听事件 map.on('zoomend', function () { refresh(); console.log('zoom1', map.getZoom()) }); pointSimplifierIns.on('pointClick', function (e, record) { var parts1 = record.data.split(','); $('#showMsg').html(parts1[2]); $('.mask').show(500) // $('.mask').fadeIn(500)/*注意:渐显的效果只能pc显示,移动端不反应*/ }); distCluster.on('featureClick', function (e, feature) { if (map.getZoom() == 16) { map.setZoom(16); } else { map.setZoom(map.getZoom() + 1); } // 设置点击点为视图坐标 map.setCenter([e.originalEvent.lnglat.getLng(), e.originalEvent.lnglat.getLat()]) console.log(e, feature.properties.name) }); distCluster.on('clusterMarkerClick clusterMarkerRightclick', function (e, record) { if (map.getZoom() == 16) { map.setZoom(16); } else { map.setZoom(map.getZoom() + 1); } map.setCenter([e.originalEvent.lnglat.getLng(), e.originalEvent.lnglat.getLat()]) console.log(e, record.feature.properties.name) }); $('.mask').on('click', function () { $('.mask').hide(500); // $('.mask').fadeOut(500);/*注意:渐隐的效果只能pc显示,移动端不反应*/ }); $('#showMsg').on('click', function (e) { // 阻止事件冒泡 e.stopPropagation() }); $('<div id="loadingTip">加载数据,请稍候...</div>').appendTo(document.body); $.get('http://localhost:63342/map/10w1.txt', function (csv) { // 本地同级目录的数据文件,除官方数据已有的经纬度以外,添加了第三个自定义信息 $('#loadingTip').remove(); var data = csv.split('\n'); distCluster.setData(data); pointSimplifierIns.setData(data); }); } //加载相关组件 AMapUI.load(['ui/geo/DistrictCluster', 'ui/misc/PointSimplifier', 'lib/$'], function (DistrictCluster, PointSimplifier, $) { // 建立点击具体坐标点后弹框样式 function creatMask() { var bodyin = document.getElementById('body'); var new_obj1 = document.createElement("div"); new_obj1.setAttribute("class", "mask"); var new_obj2 = document.createElement("div"); new_obj2.setAttribute("id", "showMsg"); bodyin.appendChild(new_obj1); new_obj1.appendChild(new_obj2); } creatMask(); $('.mask').hide(); //启动页面 initPage(DistrictCluster, PointSimplifier, $); }); </script> </body> </html>
108.935398,34.256598,西安市1 108.926398,34.316598,西安市2 108.947398,34.351598,西安市3 108.868398,34.253598,西安市4 108.879398,34.246598,西安市5 108.981398,34.354598,西安市6 108.992398,34.256198,西安市7
html, body, #container { width: 100%; height: 100%; margin: 0px; } #loadingTip { position: absolute; z-index: 9999; top: 50%; left: -50%; padding: 3px 3px; background: red; color: #fff; font-size: 14px; border: none; } .amap-marker-label { text-align: center; padding:1rem; width: 42px; height: 42px; background: rgba(55, 175, 55, 0.8); color: #fff; border-radius: 50%; line-height:1.5rem; border: 1px solid #fff; font-size: 1rem; } .amap-icon { width: 42px !important; top: 0; display: none; } .amap-icon img { width: 42px !important; height: 42px !important; left: 0 !important; visibility: hidden; cursor: pointer; } .amap-toolbar { display: none }
展现效果如上图浏览器
1.高德地图示例也有聚合显示个数的,可是为网格聚合,按照面积计算,不适合用其为基础模板,应当选用带有海量展现点和的行政区域聚合安全
2.因为电脑和移动端屏幕可视区域不一样,由缩放逻辑控制的显示状况可能会出现差别,能够经过meta标签里的
initial-scale=0.8
这个来修改
3.注意提供数据格式的拆分
var data = csv.split('\n');
data.split(',');
4.本示例经过隐藏样例的定位图标,将定位点的样式放大而写,你也能够经过从新书写标签样式来改变
如下为主要研究示例:
map_demo2.html
<!doctype html> <html lang="zh-CN"> <head> <!-- 原始地址://webapi.amap.com/ui/1.0/ui/geo/DistrictCluster/examples/plus-point-simplifier.html --> <!--<base href="//webapi.amap.com/ui/1.0/ui/geo/DistrictCluster/examples/" />--> <meta charset="utf-8"> <meta name="viewport" content="initial-scale=1.0, user-scalable=yes, width=device-width"> <title>区划聚合+海量点展现+定位+最近公交路线</title> <!--调整容器大小和一些目标地点样式大小,一级隐藏,须要使用--> <link rel="stylesheet" href="css/map_common.css"> <!--一些样式修改和遮罩弹框样式,能够不加,须要使用--> <link rel="stylesheet" href="css/map_plus.css"> <link rel="stylesheet" href="http://cache.amap.com/lbs/static/main1119.css"/> <script type="text/javascript" src='//webapi.amap.com/maps?v=1.4.3&key=d59a0ae0dd2a9b17cbbc480bea2f2033'></script> <!-- UI组件库 1.0 --> <script src="//webapi.amap.com/ui/1.0/main.js?v=1.0.11"></script> <script type="text/javascript" src="http://webapi.amap.com/maps?v=1.4.3&key=你的高德地图秘钥&plugin=AMap.Transfer"></script> <script type="text/javascript" src="http://cache.amap.com/lbs/static/addToolbar.js"></script> </head> <body> <div id="container"></div> <div id="panel"></div> <div id="tip"></div> <div id="btn_minRoad" class="btn_road">点击查看最近公交路线</div> <script type="text/javascript"> //建立地图 var map = new AMap.Map('container', { resizeEnable: true, expandZoomRange: true, zoom: 10, zooms: [10, 15], cursor: 'default', center:[112.947398,34.351598] }); // 地图初始化 function initPage(DistrictCluster, PointSimplifier, $) { var pointSimplifierIns = new PointSimplifier({ map: map, //所属的地图实例 autoSetFitView: false, //禁止自动更新地图视野 zIndex: 110, getPosition: function (item) { if (!item) { return null; } var parts = item.split(','); //返回经纬度 return [parseFloat(parts[0]), parseFloat(parts[1]), parts[2]]; }, getHoverTitle: function (dataItem) { var parts1 = dataItem.split(','); return parts1[2]; }, renderOptions: { //点的样式 pointStyle: { width: 20, height: 20, fillStyle: 'rgba(255, 0, 0, 1)', }, // hover层级大小 pointHoverStyle: { width: 20, height: 20, }, // 点击范围大小 pointHardcoreStyle: { width: 20, height: 20, lineWidth: 3, }, //鼠标hover时的title信息 hoverTitleStyle: { position: 'left', offset: [3, 0], }, } }); var distCluster = new DistrictCluster({ zIndex: 102, map: map, //所属的地图实例 getPosition: function (item) { if (!item) { return null; } var parts = item.split(','); //返回经纬度 return [parseFloat(parts[0]), parseFloat(parts[1]), parts[2]]; }, renderOptions: { //显示在所辖数据点的平均位置 getClusterMarkerPosition: DistrictCluster.ClusterMarkerPositionStrategy.AVERAGE_POINTS_POSITION, getClusterMarker: function (feature, dataItems, recycledMarker) { //label内容 var name3 = feature.properties.name.length < 4 ? feature.properties.name : (feature.properties.name[0] + feature.properties.name[1]) var content = name3 + '<br />' + dataItems.length+'个'; var label = { offset: new AMap.Pixel(-20, 0), //修改label相对于marker的位置 //----------要改等级--------- // content: map.getZoom() < 13 ? content : null content: content }; if (dataItems.length > 0) { //存在可回收利用的marker if (recycledMarker) { //直接更新内容返回 recycledMarker.setLabel(label); return recycledMarker; } //返回一个新的Marker return new AMap.Marker({ //----------要改等级--------- // label: map.getZoom() < 13 ? label : null, label: label, }); } } } }); window.distCluster = distCluster; //根据当前zoom调整点的尺寸,大小 var pointStyle = pointSimplifierIns.getRenderOptions().pointStyle; pointStyle.width = pointStyle.height = 8 * Math.pow(1.2, map.getZoom() - 3); function refresh() { var zoom = map.getZoom(); if (zoom == 10) { $('.amap-marker-label').show()//区县显示内容 pointSimplifierIns.hide();//具体坐标点显示 } else if (zoom == 11) { map.setZoom(12); } else if (zoom == 12) { map.setZoom(12); $('.amap-marker-label').hide();//区县显示内容 pointSimplifierIns.show();//具体坐标点显示 } else if (zoom == 13) { map.setZoom(13); $('.amap-marker-label').hide();//区县显示内容 pointSimplifierIns.show();//具体坐标点显示 }else if (zoom == 14) { map.setZoom(14); $('.amap-marker-label').hide();//区县显示内容 pointSimplifierIns.show();//具体坐标点显示 }else { map.setZoom(10); } } //监听事件 map.on('zoomend', function () { refresh(); console.log('zoom1', map.getZoom()) }); map.on('click', function (e) { map.setZoom(map.getZoom() + 1); map.setCenter([e.lnglat.getLng(), e.lnglat.getLat()]) refresh(); // alert('您在[ ' + e.lnglat.getLng() + ',' + e.lnglat.getLat() + ' ]的位置点击了地图!'); }); pointSimplifierIns.on('pointClick', function (e, record) { var parts1 = record.data.split(','); map.setZoom(10); alert(parts1[2]) }); //------------------公交路线规划---------------------- function road_planning(data_Geolocation) { btn_minRoad.onclick = function () { var transOptions = { map: map, city: '西安市', panel: 'panel', //cityd:'乌鲁木齐', policy: AMap.TransferPolicy.LEAST_TIME }; //构造公交换乘类 var transfer = new AMap.Transfer(transOptions); //根据起、终点坐标查询公交换乘路线 var min_road = Number.POSITIVE_INFINITY; var min_roads = []; var postion_now_j = data_Geolocation.position.getLng(); var postion_now_w = data_Geolocation.position.getLat(); function minRoad(data_Geolocation) { for (var i = 0; i < pointSimplifierIns._data.source.length; i++) { // console.log(pointSimplifierIns._data.source[i]) if (!pointSimplifierIns._data.source[i]) { return null; } var parts = pointSimplifierIns._data.source[i].split(','); postion_target_j = parseFloat(parts[0]); postion_target_w = parseFloat(parts[1]); Math.pow(postion_target_j - postion_now_j, 2); Math.pow(postion_now_w - postion_target_w, 2); if ((Math.pow(postion_target_j - postion_now_j, 2) + Math.pow(postion_now_w - postion_target_w, 2)) < min_road) { min_road = Math.pow(postion_target_j - postion_now_j, 2) + Math.pow(postion_now_w - postion_target_w, 2) min_roads = [postion_target_j, postion_target_w]; console.log('min_roads', min_roads[0], min_roads[1]) console.log('min_road', (Math.pow(postion_target_j - postion_now_j, 2) + Math.pow(postion_now_w - postion_target_w, 2))) } //返回经纬度 return min_roads } }; transfer.search(new AMap.LngLat(postion_now_j, postion_now_w), new AMap.LngLat(minRoad()[0], minRoad()[1])); } } //------------------定位功能---------------------- var geolocation; //加载地图,调用浏览器定位服务 map.plugin('AMap.Geolocation', function () { geolocation = new AMap.Geolocation({ enableHighAccuracy: true,//是否使用高精度定位,默认:true timeout: 10000, //超过10秒后中止定位,默认:无穷大 buttonOffset: new AMap.Pixel(10, 20),//定位按钮与设置的停靠位置的偏移量,默认:Pixel(10, 20) zoomToAccuracy: true, //定位成功后调整地图视野范围使定位位置及精度范围视野内可见,默认:false buttonPosition: 'RB', }); map.addControl(geolocation); geolocation.getCurrentPosition(); AMap.event.addListener(geolocation, 'complete', complete_zoom);//返回定位信息 AMap.event.addListener(geolocation, 'error', onError); //返回定位出错信息 }); var zoom2 = map.getZoom(); console.log('zoom2:',zoom2); //解析定位结果 function complete_zoom(data_Geolocation) { var zoom = map.getZoom(); console.log('zoom3:',zoom); map.setZoom(zoom); // var str = ['定位成功']; // str.push('经度:' + data_Geolocation.position.getLng()); // str.push('纬度:' + data_Geolocation.position.getLat()); // if (data_Geolocation.accuracy) { // str.push('精度:' + data_Geolocation.accuracy + ' 米'); // }//如为IP精肯定位结果则没有精度信息 // str.push('是否通过偏移:' + (data_Geolocation.isConverted ? '是' : '否')); // document.getElementById('tip').innerHTML = str.join('<br>'); var btn_minRoad = $('#btn_minRoad'); road_planning(data_Geolocation) } //解析定位错误信息 function onError(data_Geolocation) { document.getElementById('tip').innerHTML = '定位失败'; } //------------打开设备判断---------------- if (/Android|webOS|iPhone|iPod|BlackBerry/i.test(navigator.userAgent)) { $('#panel').css('display', 'none'); $('.amap-toolbar').hide(); } else { $('#panel').css('display', 'block') } $('<div id="loadingTip">加载数据,请稍候...</div>').appendTo(document.body); $.get('http://localhost:63342/map/10w1.txt', function (csv) { // 本地同级目录的数据文件,除官方数据已有的经纬度以外,添加了第三个自定义信息 $('#loadingTip').remove(); var data = csv.split('\n'); distCluster.setData(data); pointSimplifierIns.setData(data); }); } //加载相关组件 AMapUI.load(['ui/geo/DistrictCluster', 'ui/misc/PointSimplifier', 'lib/$'], function (DistrictCluster, PointSimplifier, $) { //启动页面 initPage(DistrictCluster, PointSimplifier, $); }); </script> </body> </html>
css,txt文件同,可本地环境打开显示
1.高德地图定位失败的缘由
在高德地图-浏览器定位的官方文档上有这样的一句注释“/***************************************
因为Chrome、IOS10等已再也不支持非安全域的浏览器定位请求,为保证定位成功率和精度,请尽快升级您的站点到HTTPS。
***************************************/”,不知道是否是和定位失败有关
另外,发现浏览器定位的时候,会有弹框提示问是否容许,只有点击肯定才能定位,但有的浏览器没有提示弹框,或者用户第一次点击取消,以后怎么刷新都没有弹框确认定位,定位也就失败了。js中如何写定位提醒的弹框呢?