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. [Android][Recovery] Recovery下找不到sdcard路径

    做升级的时候,把更新包拷贝到sd卡中,然后调用接口进行重启升级 wossoneri.github.io File update_file = new File("/sdcard/update ...

  2. (笔记)CTF入门指南

    [考项分类] Web: 网页安全 Crypto: 密码学(凯撒密码等) PWN: 对程序逻辑分析 系统漏洞利用 Misc: 杂项 图片隐写 数据还原 脑洞类 信息安全有关的 Reverse: 逆向工程 ...

  3. Python操作db2

    官方文档:https://www.ibm.com/support/knowledgecenter/en/SSEPGG_9.5.0/com.ibm.db2.luw.apdv.python.doc/doc ...

  4. SQL NULL 函数

    SQL ISNULL().NVL().IFNULL() 和 COALESCE() 函数 请看下面的 "Products" 表: P_Id ProductName UnitPrice ...

  5. 洛谷P1238 走迷宫题解

    题目描述 有一个m*n格的迷宫(表示有m行.n列),其中有可走的也有不可走的,如果用1表示可以走,0表示不可以走,文件读入这m*n个数据和起始点.结束点(起始点和结束点都是用两个数据来描述的,分别表示 ...

  6. .NET IL实现对象深拷贝

    对于深拷贝,通常的方法是将对象进行序列化,然后再反序化成为另一个对象.例如在stackoverflow上有这样的解决办法:https://stackoverflow.com/questions/785 ...

  7. tcping ,一个好用的TCP端口检测工具

    1.常用的用法(windows) tcp -w 10 -t -d -i 5 -j --color 81.156.165.66 443 2. http模式 -u,与-h命令连用,每一行输出目标的url ...

  8. 再看ExpressionTree,Emit,反射创建对象性能对比

    [前言] 前几日心血来潮想研究着做一个Spring框架,自然地就涉及到了Ioc容器对象创建的问题,研究怎么高性能地创建一个对象.第一联想到了Emit,兴致冲冲写了个Emit创建对象的工厂.在做性能测试 ...

  9. 关于JAVA中string直接初始化赋值和new的区别,是否可以联系到int[]的情况

    String str1 = "ABC"; String str2 = new String("ABC"); String str1 = “ABC”;可能创建一个 ...

  10. PS制作科幻特效的金色立体文字

    最终效果 一.Photoshop打开背景素材. 二.然后我们来制作字效,首先当然是在画布上打上字了,在这里要注意的是尽量选一些艺术字体,这样做出来的效果比较好些,我这里用到的字体为“Matura MT ...