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>

OpenLayers学习笔记(八)— 类似比例尺的距离环(二)的更多相关文章

  1. OpenLayers学习笔记(七)— 类似比例尺的距离环(一)

    openlayers 3 地图上创建一个距离环,始终以地图中心为中心,每个环之间的距离类似比例尺,随地图缩放而变化. 添加具有覆盖整个范围的特征的虚拟层,其可以被设置为围绕地图中心的环.注意,根据地图 ...

  2. Learning ROS forRobotics Programming Second Edition学习笔记(八)indigo rviz gazebo

    中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS forRobotics Pro ...

  3. python3.4学习笔记(八) Python第三方库安装与使用,包管理工具解惑

    python3.4学习笔记(八) Python第三方库安装与使用,包管理工具解惑 许多人在安装Python第三方库的时候, 经常会为一个问题困扰:到底应该下载什么格式的文件?当我们点开下载页时, 一般 ...

  4. Go语言学习笔记八: 数组

    Go语言学习笔记八: 数组 数组地球人都知道.所以只说说Go语言的特殊(奇葩)写法. 我一直在想一个人参与了两种语言的设计,但是最后两种语言的语法差异这么大.这是自己否定自己么,为什么不与之前统一一下 ...

  5. 【opencv学习笔记八】创建TrackBar轨迹条

    createTrackbar这个函数我们以后会经常用到,它创建一个可以调整数值的轨迹条,并将轨迹条附加到指定的窗口上,使用起来很方便.首先大家要记住,它往往会和一个回调函数配合起来使用.先看下他的函数 ...

  6. go微服务框架kratos学习笔记八 (kratos的依赖注入)

    目录 go微服务框架kratos学习笔记八(kratos的依赖注入) 什么是依赖注入 google wire kratos中的wire Providers injector(注入器) Binding ...

  7. Redis学习笔记八:集群模式

    作者:Grey 原文地址:Redis学习笔记八:集群模式 前面提到的Redis学习笔记七:主从复制和哨兵只能解决Redis的单点压力大和单点故障问题,接下来要讲的Redis Cluster模式,主要是 ...

  8. Java IO学习笔记八:Netty入门

    作者:Grey 原文地址:Java IO学习笔记八:Netty入门 多路复用多线程方式还是有点麻烦,Netty帮我们做了封装,大大简化了编码的复杂度,接下来熟悉一下netty的基本使用. Netty+ ...

  9. OpenLayers学习笔记4——使用jQuery UI实现測量对话框

    OpenLayers学习最好的方式就是跟着其自带的演示样例进行学习,另外对web前端的开发设计要了解,慢慢积累,这样在一般的小项目中应该是足够用了. 本篇參照量測demo实现对话框形式的量測,抛砖引玉 ...

随机推荐

  1. Linux 环境 Maven 安装&仓源配置

    索引: 目录索引 参看代码 GitHub: maven.txt 一.Linux (DeepinOS) 环境 1.官网下载 https://maven.apache.org/download.cgi 2 ...

  2. Centos 7 安装 ifconfig 管理命令

    1. 安装的需求背景 我们知道ifconfig 命令可以用于查看.配置.启用或禁用指定网络接口,如配置网卡的IP地址.掩码.广播地址.网关等,功能不可谓不丰富. 此命令的功能和windows系统的ip ...

  3. Python第八天 模块 包 全局变量和内置变量__name__ Python path

    Python第八天  模块   包   全局变量和内置变量__name__    Python path 目录 Pycharm使用技巧(转载) Python第一天  安装  shell  文件 Pyt ...

  4. AngularJS学习之旅—AngularJS HTML DOM(十三)

    1.AngularJS HTML DOM AngularJS 为 HTML DOM 元素的属性提供了绑定应用数据的指令. ng-disabled 指令:ng-disabled 指令直接绑定应用程序数据 ...

  5. 面相服务的架构SOA

    SOA体系结构是基于服务组件模型,将应用程序的不同功能单元通过定义良好的接口契约联系起来,接口是采用中立方式进行定义的,独立于实现服务的硬件平台,操作系统和编程语言.使得构建在这样的系统中的服务可以以 ...

  6. 【转载】关于generate用法的总结【Verilog】

    原文链接: [原创]关于generate用法的总结[Verilog] - nanoty - 博客园http://www.cnblogs.com/nanoty/archive/2012/11/13/27 ...

  7. 为什么 npm 要为每个项目单独安装一遍 node_modules?

    nodejs中package.json中的依赖必须每个项目都有自己的node_modules文件夹,而无法在多个项目之间共用一套node_modules(像Java中的Maven那样). 依赖管理是每 ...

  8. python接口自动化-post请求1

    一.查看官方文档 1. 学习一个新的模块,直接用 help 函数就能查看相关注释或案例内容,例如 具体信息如下,可查看 python 发送 ge t和 post 请求的案例: F:\test-req- ...

  9. Kaggle教程——大神教你上分

    本文记录笔者在观看Coursera上国立经济大学HLE的课程 How to win a data science competetion中的收获,和大家分享.课程的这门课的讲授人是Kaggle的大牛, ...

  10. Java 200+ 面试题补充② Netty 模块

    让我们每天都能看到自己的进步.老王带你打造最全的 Java 面试清单,认真把一件事做到最好. 本文是前文<Java 最常见的 200+ 面试题>的第二个补充模块,第一模块为:<Jav ...