openlayers 3 地图上创建一个距离环,始终以地图中心为中心,每个环之间的距离类似比例尺,随地图缩放而变化。

添加具有覆盖整个范围的特征的虚拟层,其可以被设置为围绕地图中心的环。

这篇是上一篇距离环文章的拓展和完善

GitHub:八至

作者:狐狸家的鱼

在线预览

这是模仿openlayers插件库ol-ext新出的canvas距离环功能,简直雪中送炭。

代码:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>距离环</title>
<link rel="stylesheet" href="css/ol.css" type="text/css">
<script src="build/jquery.js"></script>
<script src="build/ol.js"></script>
<style> html,
body {
height: 100%;
width: 100%;
padding: 0px;
margin: 0px;
} .map {
height: 100%;
width: 100%;
} </style>
</head>
<body>
<div id="map"></div> <script> var map = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.OSM(),
})
],
target: 'map',
view: new ol.View()
}); ol.control.CanvasScaleLine = function(options) {
ol.control.ScaleLine.call(this, options);
this.scaleHeight_ = 6;
// Get style options
if (!options) options={};
if (!options.style) options.style = new ol.style.Style();
this.setStyle(options.style);
}
ol.inherits(ol.control.CanvasScaleLine, ol.control.ScaleLine);
ol.control.CanvasScaleLine.prototype.setMap = function (map) {
var oldmap = this.getMap();
if (this._listener) ol.Observable.unByKey(this._listener);
this._listener = null;
ol.control.ScaleLine.prototype.setMap.call(this, map);
if (oldmap) oldmap.renderSync();
// Add postcompose on the map
if (map) {
this._listener = map.on('postcompose', this.drawScale_.bind(this));
}
// Hide the default DOM element
this.element.style.visibility = 'hidden';
this.olscale = this.element.querySelector(".ol-scale-line-inner");
}
ol.control.CanvasScaleLine.prototype.setStyle = function (style) {
var stroke = style.getStroke();
this.strokeStyle_ = stroke ? ol.color.asString(stroke.getColor()) : "#000";
this.strokeWidth_ = stroke ? stroke.getWidth() : 2;
var fill = style.getFill();
this.fillStyle_ = fill ? ol.color.asString(fill.getColor()) : "#fff";
var text = style.getText();
this.font_ = text ? text.getFont() : "10px Arial";
stroke = text ? text.getStroke() : null;
fill = text ? text.getFill() : null;
this.fontStrokeStyle_ = stroke ? ol.color.asString(stroke.getColor()) : this.fillStyle_;
this.fontStrokeWidth_ = stroke ? stroke.getWidth() : 3;
this.fontFillStyle_ = fill ? ol.color.asString(fill.getColor()) : this.strokeStyle_;
// refresh
if (this.getMap()) this.getMap().render();
} ol.control.CanvasScaleLine.prototype.drawScale_ = function(e) {
if ( this.element.style.visibility!=="hidden" ) return;
var ctx = e.context;
// Get size of the scale div
var scalewidth = parseInt(this.olscale.style.width);
if (!scalewidth) return;
var text = this.olscale.textContent;
var position = {left: this.element.offsetLeft, top: this.element.offsetTop};
// Retina device
var ratio = e.frameState.pixelRatio;
ctx.save();
ctx.scale(ratio,ratio);
// Position if transform:scale()
var container = this.getMap().getTargetElement();
var scx = container.offsetWidth / container.getBoundingClientRect().width;
var scy = container.offsetHeight / container.getBoundingClientRect().height;
position.left *= scx;
position.top *= scy;
// On top
position.top += this.element.clientHeight - this.scaleHeight_;
// Draw scale text
ctx.beginPath();
ctx.strokeStyle = this.fontStrokeStyle_;
ctx.fillStyle = this.fontFillStyle_;
ctx.lineWidth = this.fontStrokeWidth_;
ctx.textAlign = "center";
ctx.textBaseline ="bottom";
ctx.font = this.font_;
ctx.strokeText(text, position.left+scalewidth/2, position.top);
ctx.fillText(text, position.left+scalewidth/2, position.top);
ctx.closePath();
// Draw scale bar
position.top += 2;
ctx.lineWidth = this.strokeWidth_;
ctx.strokeStyle = this.strokeStyle_;
var max = 4;
var n = parseInt(text);
while (n%10 === 0) n/=10;
if (n%5 === 0) max = 5;
for (var i=0; i<max; i++) {
ctx.beginPath();
ctx.fillStyle = i%2 ? this.fillStyle_ : this.strokeStyle_;
ctx.rect(position.left+i*scalewidth/max, position.top, scalewidth/max, this.scaleHeight_);
ctx.stroke();
ctx.fill();
ctx.closePath();
} // Calculate and draw rings corresponding to scale line
var map = this.getMap();
var proj = map.getView().getProjection();
var center = ol.proj.transform(map.getView().getCenter(), proj, 'EPSG:4326');
var sphere = ol.Sphere ? new ol.Sphere(6371008.8) : undefined;
var t = text.split(' ');
var multiplier = t[0]/max;
switch (t[1]) {
case 'km':
multiplier *= 1000;
break;
case 'm':
multiplier *= 1;
break;
case 'mm':
multiplier *= 0.001;
break;
default:
}
for (var i=0; i<max; i++) {
var geometry = sphere ? ol.geom.Polygon.circular(sphere, center, (i+1)*multiplier, 128).transform('EPSG:4326', proj)
: ol.geom.Polygon.circular(center, (i+1)*multiplier, 128).transform('EPSG:4326', proj);
var coordinates = geometry.getCoordinates()[0];
var pixels = [];
var top = [0, Infinity];
coordinates.forEach( function(coordinate) {
var pixel = map.getPixelFromCoordinate(coordinate);
pixels.push(pixel);
if (pixel[1] < top[1]) { top = pixel; }
});
ctx.moveTo(pixels[0][0], pixels[0][1]);
for (var j=1; j<pixels.length; j++) {
ctx.lineTo(pixels[j][0], pixels[j][1]);
}
ctx.lineWidth = this.strokeWidth_;
ctx.strokeStyle = this.strokeStyle_;
ctx.stroke();
}
// Draw scale text above the rings
ctx.beginPath();
ctx.strokeStyle = this.fontStrokeStyle_;
ctx.fillStyle = this.fontFillStyle_;
ctx.lineWidth = this.fontStrokeWidth_;
ctx.textAlign = "center";
ctx.textBaseline ="bottom";
ctx.font = this.font_;
ctx.strokeText(text, top[0], top[1]-this.strokeWidth_);
ctx.fillText(text, top[0], top[1]-this.strokeWidth_);
ctx.closePath(); ctx.restore();
} var proj = map.getView().getProjection();
map.getView().setCenter(ol.proj.transform([-38, 75.9], 'EPSG:4326', proj));
map.getView().setZoom(2);
map.addControl(new ol.control.CanvasScaleLine());
</script>
</body>
</html>

最新文章

  1. Git add 常见用法
  2. 为什么要baidu/Google问题 尽量少在群里问问题
  3. linux svn迁移备份的三种方法
  4. homework-02 &quot;最大子数组之和&quot;的问题进阶
  5. 一个空格引发的bug
  6. poj 2288 Islands and Bridges_状态压缩dp_哈密尔顿回路问题
  7. Tomcat与web程序结构与Http协议
  8. 基于Python的Flask的开发实战(第一节Flask安装)
  9. final、finally和finalize的区别
  10. 如何优化MySQL insert性能
  11. linux知识汇总
  12. Vue开发与调试工具
  13. 为什么Java的main方法必须是public static void?
  14. angular2监听页面大小变化
  15. find 查询文件,执行文件
  16. [POI2005] SKA-Piggy Banks
  17. vue入门:axios的应用及拦截封装
  18. centos 6.5 安装mysql
  19. Json转list,两种包,两种方式
  20. [置顶] VS 2017 众多重构插件

热门文章

  1. 新更新,又是一年了。这次记录下关于android版的WeiboDemo的问题
  2. Redis保证事务一致性,以及常用的数据结构
  3. Python3漏洞扫描工具 ( Python3 插件式框架 )
  4. Rsync客户端卡死的问题查询
  5. 20180831-Linux环境下Python 3.6.6 的安装说明
  6. PostgreSQL:Java使用CopyManager实现客户端文件COPY导入
  7. Docker(2):使用Dockerfile创建支持SSH服务的镜像
  8. [LeetCode] 12,13 整数和罗马数互转
  9. 18 python 初学(time、random 模块)
  10. TCP三次握手原理,你真的了解吗?