OpenLayers学习笔记(八)— 类似比例尺的距离环(二)
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学习笔记(八)— 类似比例尺的距离环(二)的更多相关文章
- OpenLayers学习笔记(七)— 类似比例尺的距离环(一)
openlayers 3 地图上创建一个距离环,始终以地图中心为中心,每个环之间的距离类似比例尺,随地图缩放而变化. 添加具有覆盖整个范围的特征的虚拟层,其可以被设置为围绕地图中心的环.注意,根据地图 ...
- Learning ROS forRobotics Programming Second Edition学习笔记(八)indigo rviz gazebo
中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS forRobotics Pro ...
- python3.4学习笔记(八) Python第三方库安装与使用,包管理工具解惑
python3.4学习笔记(八) Python第三方库安装与使用,包管理工具解惑 许多人在安装Python第三方库的时候, 经常会为一个问题困扰:到底应该下载什么格式的文件?当我们点开下载页时, 一般 ...
- Go语言学习笔记八: 数组
Go语言学习笔记八: 数组 数组地球人都知道.所以只说说Go语言的特殊(奇葩)写法. 我一直在想一个人参与了两种语言的设计,但是最后两种语言的语法差异这么大.这是自己否定自己么,为什么不与之前统一一下 ...
- 【opencv学习笔记八】创建TrackBar轨迹条
createTrackbar这个函数我们以后会经常用到,它创建一个可以调整数值的轨迹条,并将轨迹条附加到指定的窗口上,使用起来很方便.首先大家要记住,它往往会和一个回调函数配合起来使用.先看下他的函数 ...
- go微服务框架kratos学习笔记八 (kratos的依赖注入)
目录 go微服务框架kratos学习笔记八(kratos的依赖注入) 什么是依赖注入 google wire kratos中的wire Providers injector(注入器) Binding ...
- Redis学习笔记八:集群模式
作者:Grey 原文地址:Redis学习笔记八:集群模式 前面提到的Redis学习笔记七:主从复制和哨兵只能解决Redis的单点压力大和单点故障问题,接下来要讲的Redis Cluster模式,主要是 ...
- Java IO学习笔记八:Netty入门
作者:Grey 原文地址:Java IO学习笔记八:Netty入门 多路复用多线程方式还是有点麻烦,Netty帮我们做了封装,大大简化了编码的复杂度,接下来熟悉一下netty的基本使用. Netty+ ...
- OpenLayers学习笔记4——使用jQuery UI实现測量对话框
OpenLayers学习最好的方式就是跟着其自带的演示样例进行学习,另外对web前端的开发设计要了解,慢慢积累,这样在一般的小项目中应该是足够用了. 本篇參照量測demo实现对话框形式的量測,抛砖引玉 ...
随机推荐
- 监控 redis 执行命令
监控 redis 执行命令 Intro 最近在用 redis 的时候想看看执行了哪些命令,于是发现了 redis-cli 提供的 Monitor 命令,直接使用这个就可以监控执行的大部分 redis ...
- python爬虫实战:利用scrapy,短短50行代码下载整站短视频
近日,有朋友向我求助一件小事儿,他在一个短视频app上看到一个好玩儿的段子,想下载下来,可死活找不到下载的方法.这忙我得帮,少不得就抓包分析了一下这个app,找到了视频的下载链接,帮他解决了这个小问题 ...
- MySQL 基础知识梳理学习(一)----系统数据库
information_schema 此数据库是MySQL数据库自带的,主要存储数据库的元数据,保存了关于MySQL服务器维护的所有其他数据库的信息,如数据库名.数据库表.表列的数据类型及访问权限等. ...
- 宋宝华:关于Ftrace的一个完整案例【转】
Ftrace简介 Ftrace是Linux进行代码级实践分析最有效的工具之一,比如我们进行一个系统调用,出来的时间过长,我们想知道时间花哪里去了,利用Ftrace就可以追踪到一级级的时间分布. Ftr ...
- js 学习之路5:使用js在网页中添加水印
示例: <!DOCTYPE html> <html> <meta http-equiv="Content-Type" content="te ...
- 列表、enumerate()函数,以及查看数据类型所有的内置方法
随便看看 """ forList(): 测试list和enumerate()函数 examineFun(): 查看数据类型所有的内置方法 ""&quo ...
- Linux shell编写脚本部署pxe网络装机
Linux shell编写脚本部署pxe网络装机 人工安装配置,Linux PXE无人值守网络装机 https://www.cnblogs.com/yuzly/p/10582254.html 脚本实 ...
- wxPython树控件
1.树控件 树(tree)是一种通过层次结构展示信息的控件,如下图所示是树控件示例,左窗口中是树控件,在wxPython中树控件类是wx.TreeCtrl. wx.TreeCtrl中一个常用的方法有: ...
- Java文件下载:如何编码文件名称以及如何设置HttpServletResponse
在下载文件时,经常遇到文件名乱码等问题. 本文说明如何编码文件名,以及如何设置HttpServletResponse对象. 1,如何编码文件名 String userAgent = request.g ...
- 重装助手教你如何在Windows 10中更改您的帐户名称
当您设置新的Win10免费下载 PC时,您选择用户名的部分可能会让您措手不及.如果是这种情况,您可以选择弹出头部的第一件事或者您打算稍后更改的随机和临时事物.但令人惊讶的是,在Windows 10中更 ...