使用高德地图自定义创建图层(svg)
这段时间做的一个项目,需要在地图上绘制简单的图形。在学习高德地图
JS API
的过程中,发现高德地图提供的点、线等API并不能满足我的需求,还好它开放了自定义图层CustomLayer
,官方说自定义图层支持canvas
、svg
、甚至dom
,这里我用的是svg
,多说无益,上代码。
一、高德地图
以下的步骤在官方文档中都有,而且官方文档比较齐全。
首先需要去高德API官网申请自己的key,此步略过。
拿到key后在页面中引入地图所用的js
<script type="text/javascript" src="https://webapi.amap.com/maps?v=1.4.15&key=申请的key"></script>
准备一个放置地图的容器,指定特定的高度,宽度。我是将容器高度宽度全部设置为100%。
<div id="container"></div>
html, body, #container {margin: 0;padding: 0;width: 100%;height: 100%;
}
最后一步,在js中指定容器,加载地图,然后就可以在页面中看到你的地图了。
// 第一个参数是容器名称,第二个参数可以按自己需求随意配置。
var map = new AMap.Map('container', {zoom: 15, // 缩放等级center: [115.49481017, 38.88656455], // 中心点features: ['bg', 'road', 'building'] // 设置地图中显示的元素, 'bg'(地图背景)、'point'(POI点)、'road'(道路)、'building'(建筑物)
});
二、自定义图层
下面开始编写自定义图层,除过地图所用的js文件,我还用到了jquery
。
首先地图有一部分是异步加载的,所以需要在地图加载完成后,再去编写自定义图层,否则容易报错,而地图也给我们提供了complete
事件。
map.on('complete', function(){// TODO 编写自定义图层
})
然后声明svg
,创建图层
svg
和地图类似,也需要先声明一个容器,此容器和地图等宽等高
var svg = $('<svg id="drawing" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" ></svg>')[0];
#drawing {margin: 0;padding: 0;width: 100%;height: 100%;
}
创建图层
// 第一个参数传入我们创建的svg对象,第二个参数为图层配置,可以根据自己需求进行配置
var customLayer = new AMap.CustomLayer(svg, {zIndex: 100,zooms: [3, 18],alwaysRender: true
});
map.add(customLayer); // 要把图层添加到地图中
二、在图层中画自己喜欢的图形。
为了简化代码,项目中采用了svg.js
// 调用svg.js提供的SVG函数,传入我们创建的svg对象,创建所需要的draw对象。
var draw = SVG(svg);
现在我们开始在地图上画线。
我们规定在地图上单击即为线的起点,再进行单击即为线的终点。
首先为地图注册单机事件
var isDraw = false; // 用来判断是开始画线还是结束画线。
var startPix; // 用来存储起点
map.on('click', function(ev){isDraw = !isDraw;if(isDraw) {// isDraw为true就标明起点startPos = ev.pixel; }else{// isDraw为false就画线。 }
})
然后编写画线函数
function drawLine(start, end) {var lineWth = 3;var lineColor = 'blue';var x = start.x;var y = start.y;var x1 = end.x;var y1 = end.y;line = draw.line(x, y, x1, y1).stroke({ color: lineColor, width: lineWth });return line;
}
然后完善地图单击事件
map.on('click', function(ev){isDraw = !isDraw;if(isDraw){// isDraw为true就标明起点startPix = ev.pixel;}else{// isDraw为false就画线。 var endPix = ev.pixel;drawLine(startPix, endPix);}
})
至此就可以在地图上简单的画直线了。
但是当我们单击地图开始画线时,此时地图上没有任何东西,再点击地图时,线突然的出现,这样显得比较突兀。现在我们需要修改成,当开始画线时,线跟随鼠标移动而移动,再点击地图时,结束画线。
我们需要先注册地图mousemove
事件
map.on('mousemove', function (ev) {if(isDraw) {drawLine(startPix, ev.pixel)}
});
注册完鼠标移动时间后,线是可以跟随鼠标移动了,但是现在出现了一个小问题:
所有画的线都留下了来了,这时我们需要将多余的线去掉。
在鼠标移动时 去掉多余的线,这里需要用到draw
对象的group
功能。
var lineGroup; // 声明一个对象 存储line。
map.on('click', function(ev){isDraw = !isDraw;if(isDraw){// isDraw为true就标明起点startPix = ev.pixel;lineGroup = draw.group(); // 开始画线时创建一个group。}else{// isDraw为false就画线。 var endPix = ev.pixel;drawLine(startPix, endPix);}
});
map.on('mousemove', function(ev){if(isDraw) {lineGroup.clear(); // 在鼠标移动时先将group清空。var line = drawLine(startPix, ev.pixel);lineGroup.add(line);// 将新线添加到group中。}
})
至此,我们完成了让线跟随鼠标移动。
三、地图重绘时,让画的线随实际经纬度坐标重绘。
我们现在所画的线,在拖动、放大、缩小地图时,是不会跟随地图变化而变化的。
首先需要创建一个数组用来存储坐标点,一个对象用来存储起点坐标。
var positions = [];
var startPos;
然后开始画线记录起始点经纬度坐标,结束画线时将两点坐标存入数组。
map.on('click', function(ev){isDraw = !isDraw;if(isDraw){// isDraw为true就标明起点startPos = ev.lnglat; /*手动高亮*/startPix = ev.pixel;lineGroup = draw.group();}else{// isDraw为false就画线。 var endPix = ev.pixel;drawLine(startPix, endPix);positions.push({ /*手动高亮*/start: startPos,end: ev.lnglat})}
});
最后注册的是自定义层的重绘事件。
customLayer.render = onRender;
function onRender() {draw.clear(); // 先将画板清空for(var i = 0;i < positions.length;i++){// 需要将经纬度坐标转换为容器内坐标,lngLatToContainer是高德提供的转换方法var startPixCon = map.lngLatToContainer(positions[i].start);var endPixCon = map.lngLatToContainer(positions[i].end);drawLine(startPixCon, endPixCon);}
}
现在我们画的线就可以随地图变化而变化了。
最后附上个人编写全部代码:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>csdn</title>
</head>
<body><style>html,body,#container{margin: 0;padding: 0;width: 100%;height: 100%;}#drawing { margin: 0; padding: 0; width: 100%; height: 100%; }</style><div id="container"></div><div id="drawing"></div><script src="http://libs.baidu.com/jquery/1.9.0/jquery.js"></script><script src="https://cdn.jsdelivr.net/npm/@svgdotjs/svg.js@3.0/dist/svg.min.js"></script><script src="https://webapi.amap.com/maps?v=1.4.15&key=自己的key"></script><script type="text/javascript">// 第一个参数是容器名称,第二个参数可以按自己需求随意配置。var map = new AMap.Map('container',{ //加载地图zoom:15,center:[115.49481017, 38.88656455],features:['bg', 'road', 'building'],//地图中显示元素 'bg'(地图背景)、'point'(POI点)、'road'(道路)、'building'(建筑物)})map.on('complete',function(){//自定义图层//声明svg <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"width="3.5in" height="1in">var svg = $('<svg id="drawing" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" ></svg>')[0];var customLayer= new AMap.CustomLayer(svg,{ //创建图层zIndex:100,zooms:[3,18],alwaysRender:true,})map.add(customLayer);//把图层添加到地图中// 调用svg.js提供的SVG函数,传入创建的svg对象,创建所需要的draw对象。 var draw = SVG(svg);//注册单击事件var isDraw = false; //用来判断是开始还是结束var startPix; //储蓄起点var lineGroup;var positions = [];var startPos;map.on('click',function(ev){isDraw =!isDraw;if(isDraw){//isDraw为true就表明起点startPos = ev.lnglat; /*手动高亮*/startPix = ev.pixel;lineGroup = draw.group(); // 开始画线时创建一个group。}else{// isDraw为false就画线。var endPix = ev.pixel;drawLine(startPix,endPix);positions.push({ /*手动高亮*/start: startPos,end: ev.lnglat})}});function drawLine(start,end){var lineWth = 3;var lineColor = 'blue';var x = start.x;var y = start.y;var x1 = end.x;var y1 = end.y;line = draw.line(x, y, x1, y1).stroke({ color: lineColor, width: lineWth });return line; }map.on('mousemove', function (ev) {if(isDraw) {// drawLine(startPix, ev.pixel)lineGroup.clear(); // 在鼠标移动时先将group清空。var line = drawLine(startPix, ev.pixel);lineGroup.add(line);// 将新线添加到group中。}});//去掉多余的线customLayer.render = onRender;function onRender() {draw.clear(); // 先将画板清空for(var i = 0;i < positions.length;i++){// 需要将经纬度坐标转换为容器内坐标,lngLatToContainer是高德提供的转换方法var startPixCon = map.lngLatToContainer(positions[i].start);var endPixCon = map.lngLatToContainer(positions[i].end);drawLine(startPixCon, endPixCon);}}})</script>
</body>
</html>
看到评论区有需要svg网格的
添加svg网格设计源代码
<!doctype html>
<html><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width"><title>浅色地图</title><link rel="stylesheet" href="https://a.amap.com/jsapi_demos/static/demo-center/css/demo-center.css" /><style>html,body,#container {width: 1570px;height: 715px;}</style>
</head><body><div id="container"></div><script src="//webapi.amap.com/maps?v=2.0&key=d1bc8c8d59cf6d271829aff34e63d85b"></script><script type="text/javascript">var map = new AMap.Map('container', {center: [120.258387, 31.531555],zooms: [14, 20],zoom: 5,});AMap.plugin(['AMap.ToolBar', 'AMap.Driving'], function() { //异步同时加载多个插件var toolbar = new AMap.ToolBar();map.addControl(toolbar);});function getData(callback) {AMap.plugin('AMap.DistrictSearch', function() {var search = new AMap.DistrictSearch();search.search('中国', function(status, data) {if (status === 'complete') {var positions = []var provinces = data['districtList'][0]['districtList']for (var i = 0; i < provinces.length; i += 1) {positions.push({center: provinces[i].center,radius: Math.max(2, Math.floor(Math.random() * 10))})}console.log(positions)callback(positions)}});});}function addLayer(positions) {var canvas = document.createElement('canvas');var customLayer = new AMap.CustomLayer(canvas, {zooms: [0, 24],zIndex: 120});var onRender = function() {var size = map.getSize(); //resizevar width = size.width;var height = size.height;canvas.width = width;canvas.height = height; //清除画布//开始绘制var ctx = canvas.getContext("2d"); //获取元素工具// 1. 设置网格大小var girdSize = 65;// 2. 获取Canvas的width、heightvar CanvasWidth = ctx.canvas.width;var CanvasHeight = ctx.canvas.height;// 3. 采用遍历的方式,绘画x轴的线条var xLineTotals = Math.floor(CanvasHeight / girdSize); // 计算需要绘画的x轴条数for (var i = 0; i < xLineTotals; i++) {ctx.beginPath(); // 开启路径,设置不同的样式ctx.moveTo(0, girdSize * i - 0.5); // -0.5是为了解决像素模糊问题ctx.lineTo(CanvasWidth, girdSize * i - 0.5);ctx.strokeStyle = "rgba(255,255,255,0.7)"; // 设置每个线条的颜色ctx.lineWidth = 1;ctx.stroke();}// 4.采用遍历的方式,绘画y轴的线条var yLineTotals = Math.floor(CanvasWidth / girdSize); // 计算需要绘画y轴的条数for (var j = 0; j < yLineTotals; j++) {ctx.beginPath(); // 开启路径,设置不同的样式ctx.moveTo(girdSize * j, 0);ctx.lineTo(girdSize * j, CanvasHeight);ctx.strokeStyle = "rgba(255,255,255,0.7)"; // 设置每个线条的颜色ctx.lineWidth = 1;ctx.stroke();}}customLayer.render = onRender;customLayer.setMap(map);}getData(addLayer);</script>
</body></html>
使用高德地图自定义创建图层(svg)相关推荐
- 高德地图自定义创建地图
1.首先打开高都地图api自定义地图界面(自定义地图) 2.点进去,进行自定义地图配置 自定义样式 3.定义结束,点击发布 4.接下来点击使用自定义地图,会生成一串码 5.点击复制,在地图初始化调用 ...
- Android高德地图自定义Markers的例子
下文为各位重点介绍关于Android高德地图自定义Markers的例子,希望这篇文章能够让各位理解到Android高德地图自定义Markers的方法. 之前的博客里说了地图的嵌入和定位,今天就说说在地 ...
- Android 高德地图自定义线路规划选择方案之后按照方案进行导航
Android 高德地图自定义线路规划选择方案之后按照方案进行导航 因为我这边导航需求的问题,导致我这边不能使用高德地图官方的线路规划和导航.所以我这边线路规划和导航界面都是根据高德地图那边给的api ...
- 高德地图自定义图标的点标记Marker--初体验(二)
点标记Marker 创建一个默认图标的点标记: 创建一个自定义图标的点标记: new AMap.Marker({}) 参数说明 本文以Marker为主,其他点标记方法大差不差 通过上两篇文章我们已经了 ...
- vue框架中使用高德地图自定义icon问题
** vue框架中使用高德地图自定义icon问题 ** vue框架中使用高德地图自定义icon,在编译时,因为图片会有封装问题等,但是在高德地图中没有转化对应的路径,在最后结果中会出现找不到图标的问题 ...
- 高德地图添加瓦片图层
高德地图添加瓦片图层 1.准备图层图片 2.将图片根据使用地图切割为相应的瓦片 工具:高德切图工具 地址:高德地图切图工具: 高德地图切图工具 也可使用付费工具:MapCutter 下载zip文件,运 ...
- Android高德地图自定义Mark并实现聚合效果
Android高德地图自定义Mark并实现聚合效果 起因:公司本来项目里面用到了高德地图,然后最近老板看见别人的APP里面有个聚合的这个功能,老板:"这个效果能不能实现,我也要!" ...
- android高德地图自定义图层,自定义图层-图层-教程-地图 JS API | 高德地图API
自定义图层 CustomLayer 自定义图层是完全由开发者指定绘制方法的图层.该图层可以是 canvas.svg.甚至可以是 dom 组成的图层. JSAPI 能够实现自定义图层与高德地图的同步平移 ...
- 高德地图自定义点标记踩坑
先看一下要做的效果 如上图所示,箭头所指示的就是我们要进行的点标记, 先说一下我做的这个步骤 1.上图所指示的坐标当时是用墨卡托坐标,要将其转成高德地图坐标表示的经纬度的形式,才能在高德地图中表示出来 ...
最新文章
- 牛顿棺材板快盖不住了:用深度神经网络解决三体问题,提速一亿倍
- 洛谷P2502:[HAOI2006]旅行
- 1019.单元测试工具CUnit
- 2021年中国低密度PET泡沫市场趋势报告、技术动态创新及2027年市场预测
- 【数据结构】树状数组笔记
- 当金蝶BOS开发网版主啦,纪念下!^_^
- GJB289A总线测试工装研究
- Coherence X for Mac 网页转换应用程序工具
- 抱薪者说 | 从零开始 ,社区年会诞生记
- 转载:CVPR 2019 论文汇总(按方向划分,0611 更新中)
- error: RPC failed; curl 56 GnuTLS recv error (-9): A TLS packet with unexpected length was
- 两万字的Redis笔记!
- 《U-Net: Convolutional Networks for Biomedical Image Segmentation》学习笔记
- 学习JBPM 工作流引擎 API方法(二)
- 【MySQL】MySQL知识图谱
- 心理学家:人生最可怕的不是失去爱,而是失去这种能力
- 基于流的(Flow-based)生成模型简介
- 【已完结】【悲报】pip search 报错
- 卸载软件管家蓝屏解决方案
- 商城类小程序源码,拼团、砍价、秒杀、优惠券,客服系统一套源码全搞定!
热门文章
- 在公司局域网内安装无线路由器的连接设置方法
- 基于SEER的区块链版赛亚麻将游戏Pre alpha版本内测啦!
- 报错:dev: `webpack-dev-server --inline --progress --config build/webpack.dev.conf.js`
- 5G专网,运营商该怎么玩?
- tableau无法启动程序_Tableau Public已启动
- STM32移位操作笔记
- 链接脚本文件-Linker script file
- 铭记影响世界的游戏之父
- 计算机一级PPT脚注,计算机一级考试《MS Office》知识考点
- freebsd环境变量设置