这段时间做的一个项目,需要在地图上绘制简单的图形。在学习高德地图JS API的过程中,发现高德地图提供的点、线等API并不能满足我的需求,还好它开放了自定义图层CustomLayer,官方说自定义图层支持canvassvg、甚至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. 高德地图自定义创建地图

    1.首先打开高都地图api自定义地图界面(自定义地图) 2.点进去,进行自定义地图配置 自定义样式  3.定义结束,点击发布 4.接下来点击使用自定义地图,会生成一串码 5.点击复制,在地图初始化调用 ...

  2. Android高德地图自定义Markers的例子

    下文为各位重点介绍关于Android高德地图自定义Markers的例子,希望这篇文章能够让各位理解到Android高德地图自定义Markers的方法. 之前的博客里说了地图的嵌入和定位,今天就说说在地 ...

  3. Android 高德地图自定义线路规划选择方案之后按照方案进行导航

    Android 高德地图自定义线路规划选择方案之后按照方案进行导航 因为我这边导航需求的问题,导致我这边不能使用高德地图官方的线路规划和导航.所以我这边线路规划和导航界面都是根据高德地图那边给的api ...

  4. 高德地图自定义图标的点标记Marker--初体验(二)

    点标记Marker 创建一个默认图标的点标记: 创建一个自定义图标的点标记: new AMap.Marker({}) 参数说明 本文以Marker为主,其他点标记方法大差不差 通过上两篇文章我们已经了 ...

  5. vue框架中使用高德地图自定义icon问题

    ** vue框架中使用高德地图自定义icon问题 ** vue框架中使用高德地图自定义icon,在编译时,因为图片会有封装问题等,但是在高德地图中没有转化对应的路径,在最后结果中会出现找不到图标的问题 ...

  6. 高德地图添加瓦片图层

    高德地图添加瓦片图层 1.准备图层图片 2.将图片根据使用地图切割为相应的瓦片 工具:高德切图工具 地址:高德地图切图工具: 高德地图切图工具 也可使用付费工具:MapCutter 下载zip文件,运 ...

  7. Android高德地图自定义Mark并实现聚合效果

    Android高德地图自定义Mark并实现聚合效果 起因:公司本来项目里面用到了高德地图,然后最近老板看见别人的APP里面有个聚合的这个功能,老板:"这个效果能不能实现,我也要!" ...

  8. android高德地图自定义图层,自定义图层-图层-教程-地图 JS API | 高德地图API

    自定义图层 CustomLayer 自定义图层是完全由开发者指定绘制方法的图层.该图层可以是 canvas.svg.甚至可以是 dom 组成的图层. JSAPI 能够实现自定义图层与高德地图的同步平移 ...

  9. 高德地图自定义点标记踩坑

    先看一下要做的效果 如上图所示,箭头所指示的就是我们要进行的点标记, 先说一下我做的这个步骤 1.上图所指示的坐标当时是用墨卡托坐标,要将其转成高德地图坐标表示的经纬度的形式,才能在高德地图中表示出来 ...

最新文章

  1. 牛顿棺材板快盖不住了:用深度神经网络解决三体问题,提速一亿倍
  2. 洛谷P2502:[HAOI2006]旅行
  3. 1019.单元测试工具CUnit
  4. 2021年中国低密度PET泡沫市场趋势报告、技术动态创新及2027年市场预测
  5. 【数据结构】树状数组笔记
  6. 当金蝶BOS开发网版主啦,纪念下!^_^
  7. GJB289A总线测试工装研究
  8. Coherence X for Mac 网页转换应用程序工具
  9. 抱薪者说 | 从零开始 ,社区年会诞生记
  10. 转载:CVPR 2019 论文汇总(按方向划分,0611 更新中)
  11. error: RPC failed; curl 56 GnuTLS recv error (-9): A TLS packet with unexpected length was
  12. 两万字的Redis笔记!
  13. 《U-Net: Convolutional Networks for Biomedical Image Segmentation》学习笔记
  14. 学习JBPM 工作流引擎 API方法(二)
  15. 【MySQL】MySQL知识图谱
  16. 心理学家:人生最可怕的不是失去爱,而是失去这种能力
  17. 基于流的(Flow-based)生成模型简介
  18. 【已完结】【悲报】pip search 报错
  19. 卸载软件管家蓝屏解决方案
  20. 商城类小程序源码,拼团、砍价、秒杀、优惠券,客服系统一套源码全搞定!

热门文章

  1. 在公司局域网内安装无线路由器的连接设置方法
  2. 基于SEER的区块链版赛亚麻将游戏Pre alpha版本内测啦!
  3. 报错:dev: `webpack-dev-server --inline --progress --config build/webpack.dev.conf.js`
  4. 5G专网,运营商该怎么玩?
  5. tableau无法启动程序_Tableau Public已启动
  6. STM32移位操作笔记
  7. 链接脚本文件-Linker script file
  8. 铭记影响世界的游戏之父
  9. 计算机一级PPT脚注,计算机一级考试《MS Office》知识考点
  10. freebsd环境变量设置