Leaflet.Graticule源码分析以及经纬度汉化展示

目录

前言

一、源码分析

1、类图设计

2、时序调用 

3、调用说明

二、经纬度汉化

1、改造前

2、汉化

3、改造效果

总结


前言

        在之前的博客基于Leaflet的Webgis经纬网格生成实践中,已经深入介绍了Leaflet.Graticule的实际使用方法和进行了简单的源码分析。认真看过实例效果的朋友一定会发现,在页面上生成的网格中,其边线的经度和维度都是英文的,如下图所示:

         那如何进行汉化改造支持呢,这里需要进行显示支持。本文将重点详细分析这款经纬网生成的源码,以及其内在的调用逻辑,通过本文,可以让您知道经纬网的构造原理,做到知其然知其所以然。

一、源码分析

1、类图设计

        相对来说,这种前端的工具型框架设计得还是比较简单的,没有过多的依赖。相当于后端的一个类,这里采用OOP的方式进行源码分析。众所周知,通常一个类,包含属性和方法。Leaflet.Graticule也无外乎如此,其属性定义如下图所示。

        由于一张图的篇幅有限,我们暂且把方法给隐藏起来了。其具体的方法架构如下图:

2、时序调用 

        时序图可以用来很好的描述方法内部的流转和调用逻辑,方便对某一个方法的全生命进行跟踪和展示。这里也同样采用这种方法来进行调用流程的阐述。

3、调用说明

        第一步:初始化配置参数,在这里会调用构造方法进行对象创建。其定义参考如下:

var obj = L.latlngGraticule({
	showLabel: true,
	color: 'red',
	zoomInterval: {
		latitude: [
			{start: 2, end: 4, interval: 30},
			{start: 5, end: 20, interval: 5}
			],
			longitude: [
				{start: 2, end: 4, interval: 30},
				{start: 5, end: 20, interval: 5}
			]
		}
	});

         第二步、调用Layer.js的addTo方法进行地图添加。

addTo: function (map) {
        map.addLayer(this);
        return this;
    }

        第三步、通过addLayer将地图添加到定义的leaflet地图中,代码如下:

_layerAdd: function (e) {
		var map = e.target;

		// check in case layer gets added and then removed before the map is ready
		if (!map.hasLayer(this)) { return; }

		this._map = map;
		this._zoomAnimated = map._zoomAnimated;

		if (this.getEvents) {
			var events = this.getEvents();
			map.on(events, this);
			this.once('remove', function () {
				map.off(events, this);
			}, this);
		}

		this.onAdd(map);

		if (this.getAttribution && map.attributionControl) {
			map.attributionControl.addAttribution(this.getAttribution());
		}

		this.fire('add');
		map.fire('layeradd', {layer: this});

        第四步、通过reset触发绘制方法,进行基于Canvas的经纬度线的绘制。

 _reset: function () {
        var container = this._container,
            canvas = this._canvas,
            size = this._map.getSize(),
            lt = this._map.containerPointToLayerPoint([0, 0]);

        L.DomUtil.setPosition(container, lt);

        container.style.width = size.x + 'px';
        container.style.height = size.y + 'px';

        canvas.width  = size.x;
        canvas.height = size.y;
        canvas.style.width  = size.x + 'px';
        canvas.style.height = size.y + 'px';

        this.__calcInterval();

        this.__draw(true);
    },

        第五步、绘制经纬线

function __draw_lon_line(self, lon_tick) {
                lngstr = self.__format_lng(lon_tick);
                txtWidth = ctx.measureText(lngstr).width;
                var bb = map.latLngToContainerPoint(L.latLng(_lat_b, lon_tick));

                if (curvedLon) {
                    if (typeof(curvedLon) == 'number') {
                        _lat_delta = curvedLon;
                    }

                    ctx.beginPath();
                    ctx.moveTo(bb.x, bb.y);
                    var _prev_p = null;
                    for (var j=_lat_b; j<_lat_t; j+=_lat_delta) {
                        var tt = map.latLngToContainerPoint(L.latLng(j, lon_tick));
                        ctx.lineTo(tt.x, tt.y);

                        if (self.options.showLabel && label && _prev_p != null) {
                            if (_prev_p.y > 8 && tt.y <= 8) {
                                ctx.fillText(lngstr, tt.x - (txtWidth/2), txtHeight);
                            }
                            else if (_prev_p.y >= hh && tt.y < hh) {
                                ctx.fillText(lngstr, tt.x - (txtWidth/2), hh-2);
                            }
                        }

                        _prev_p = {x:tt.x, y:tt.y, lon:lon_tick, lat:j};
                    }
                    ctx.stroke();
                }
                else {
                    var __lat_top = _lat_t;
                    var tt = map.latLngToContainerPoint(L.latLng(__lat_top, lon_tick));
                    if (curvedLat) {
                        __lat_top = map.containerPointToLatLng(L.point(tt.x, 0));
                        __lat_top = __lat_top.lat;
                        if (__lat_top > 90) { __lat_top = 90; }
                        tt = map.latLngToContainerPoint(L.latLng(__lat_top, lon_tick));

                        var __lat_bottom = map.containerPointToLatLng(L.point(bb.x, hh));
                        __lat_bottom = __lat_bottom.lat;
                        if (__lat_bottom < -90) { __lat_bottom = -90; }
                        bb = map.latLngToContainerPoint(L.latLng(__lat_bottom, lon_tick));
                    }

                    ctx.beginPath();
                    ctx.moveTo(tt.x, tt.y+1);
                    ctx.lineTo(bb.x, bb.y-1);
                    ctx.stroke();

                    if (self.options.showLabel && label) {
                        ctx.fillText(lngstr, tt.x - (txtWidth/2), txtHeight+1);
                        ctx.fillText(lngstr, bb.x - (txtWidth/2), hh-3);
                    }
                }
            };

          第七步、将经过绘制的经纬网通过canvas渲染到html页面进行展示

        经过以上的步骤,就完成了经纬网的生成。以上代码只是对源代码进行深入讲解,实际使用的过程中,不是为了调整相关参数或者调整运行逻辑,可以不必要进行代码改造,直接使用即可。 

二、经纬度汉化

1、改造前

        在上面的源码分析中,我们会进行经纬度的格式化,详细代码在__format_lat和__format_lng这两个方法中,这里我们以__format_lng为例:

__format_lng: function(lng) {
        if (this.options.lngFormatTickLabel) {
            return this.options.lngFormatTickLabel(lng);
        }

        // todo: format type of float
        if (lng > 180) {
            return '' + (360 - lng) + 'W';
        }
        else if (lng > 0 && lng < 180) {
            return '' + lng + 'E';
        }
        else if (lng < 0 && lng > -180) {
            return '' + (lng*-1) + 'W';
        }
        else if (lng == -180) {
            return '' + (lng*-1);
        }
        else if (lng < -180) {
            return '' + (360 + lng) + 'W';
        }
        return '' + lng;
    }

        可以看到,代码中仔细规定了经度的展示单位,W为西经,E表示东经。了解了以上知识就可以进行汉化改造,直接修改相应参数即可。

2、汉化

__format_lng: function(lng) {
        if (this.options.lngFormatTickLabel) {
            return this.options.lngFormatTickLabel(lng);
        }
        if (lng > 180) {
			return '' + (360 - lng) + '西经';
        }
        else if (lng > 0 && lng < 180) {
			return '' + lng + '东经';
        }
        else if (lng < 0 && lng > -180) {
			return '' + (lng*-1) + '西经';
        }
        else if (lng == -180) {
            return '' + (lng*-1);
        }
        else if (lng < -180) {
			return '' + (360 + lng) + '西经';
        }
        return '' + lng;
    }

3、改造效果

 注意:这里只改造了经度,维度信息还没有修改,您可以尝试动手将维度值也进行合理的汉化。

总结

        以上就是本文的主要内容,本文将重点详细分析这款经纬网生成的源码,以及其内在的调用逻辑,通过本文,可以让您知道经纬网的构造原理,做到知其然知其所以然。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/248982.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python【Matplotlib】图例可拖动改变位置

代码&#xff1a; import matplotlib.pyplot as plt from matplotlib.widgets import Button# 创建一个示例图形 fig, ax plt.subplots() line, ax.plot([1, 2, 3], labelLine 1)# 添加图例 legend ax.legend(locupper right, draggableTrue)# 添加一个按钮&#xff0c;用于…

媒体直播平台有哪些,活动直播如何扩大曝光?

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 媒体直播平台包括人民视频、新华社现场云、中国网、新浪新闻直播、搜狐视频直播、凤凰新闻直播、腾讯新闻直播等。活动直播想要扩大曝光&#xff0c;可以考虑以下方式&#xff1a; 1.选择…

【深度学习】TensorFlow深度模型构建:训练一元线性回归模型

文章目录 1. 生成拟合数据集2. 构建线性回归模型数据流图3. 在Session中运行已构建的数据流图4. 输出拟合的线性回归模型5. TensorBoard神经网络数据流图可视化6. 完整代码 本文讲解&#xff1a; 以一元线性回归模型为例&#xff0c; 介绍如何使用TensorFlow 搭建模型 并通过会…

数据泄露警报:不同行业危机解析与迅软DSE的拯救之道

在如今全球信息数字化不断加速的时代里&#xff0c;数据资料的价值更为突出&#xff0c;根据IBM数据显示&#xff0c;数据泄露的平均成本接近440万美元。一旦泄露可能意味着丢失信息、声誉受损&#xff0c;并可能导致延误和生产力损失。那么不同行业一旦发生了数据泄露将会面临…

Linux部署MySQL5.7和8.0版本 | CentOS和Ubuntu系统详细步骤安装

一、MySQL数据库管理系统安装部署【简单】 简介 MySQL数据库管理系统&#xff08;后续简称MySQL&#xff09;&#xff0c;是一款知名的数据库系统&#xff0c;其特点是&#xff1a;轻量、简单、功能丰富。 MySQL数据库可谓是软件行业的明星产品&#xff0c;无论是后端开发、…

Redis——02,redis-benchmark 性能测试

redis-benchmark 性能测试 一、benchmark 性能测试。二、参数详解&#xff1a; 一、benchmark 性能测试。 在bin目录下&#xff0c;有一个redis-benchmark 工具&#xff0c;是用来测试性能的。 二、参数详解&#xff1a; http://doc.yaojieyun.com/www.runoob.com/redis/re…

VMP泄露编译的一些注意事项

VMP编译教程 鉴于VMP已经在GitHub上被大佬强制开源&#xff0c;特此出一期编译教程。各位熟悉的可以略过&#xff0c;不熟悉的可以参考一下。 环境&#xff08;软件&#xff09; Visual Studio 2015 - 2022 &#xff08;建议使用VS2019&#xff0c;Qt插件只有这个版本及以上…

Python等比例缩放图片并修改对应的Labelme标注文件(v2.0)

Python等比例缩放图片并修改对应的Labelme标注文件&#xff08;v2.0&#xff09; 前言前提条件相关介绍实验环境Python等比例缩放图片并修改对应的Labelme标注文件Json文件代码实现输出结果 前言 此版代码&#xff0c;相较于Python等比例缩放图片并修改对应的Labelme标注文件&a…

原子学习笔记1——阻塞和非阻塞IO

阻塞式 I/O 顾名思义就是对文件的 I/O 操作&#xff08;读写操作&#xff09;是阻塞式的&#xff0c;非阻塞式 I/O 同理就是对文件的I/O 操作是非阻塞的。 当对文件进行读操作时&#xff0c;如果数据未准备好、文件当前无数据可读&#xff0c;那么读操作可能会使调用者阻塞&…

编程实际应用实例:洗车店会员管理系统操作教程

一、前言 洗车店在会员管理有时候需要一卡多用&#xff0c;基本也不需要做卡&#xff0c;直接报手机号或车牌号即可完成电子会员卡录入。 下面以 佳易王洗车店会员管理系统软件为例说明&#xff0c; 软件试用版下载或技术支持可以点击下方的官网卡片 如图&#xff1a;这个卡…

[HCTF 2018]WarmUp (代码审计)

打开题目&#xff1a; 好好好。 看看源码&#xff1a; &#xff1f; source.php 让我看看&#xff01; 发现还有个文件叫hint,php 看看&#xff1a; 得到目的文件是ffffllllaaaagggg 分析代码&#xff1a; $_REQUEST 变量 $_REQUEST用于收集HTML表单提交的数据&#x…

迅为RK3568开发板使用OpenCV处理图像-ROI区域-位置提取ROI

在图像处理过程中&#xff0c;我们可能会对图像的某一个特定区域感兴趣&#xff0c;该区域被称为感兴趣区域&#xff08;Region of Interest, ROI&#xff09;。在设定感兴趣区域 ROI 后&#xff0c;就可以对该区域进行整体操作。 位置提取 ROI 本小节代码在配套资料“iTOP-3…

RocketMQ系统性学习-RocketMQ领域模型及Linux下单机安装

MQ 之间的对比 三种常用的 MQ 对比&#xff0c;ActiveMQ、Kafka、RocketMQ 性能方面&#xff1a; 三种 MQ 吞吐量级别为&#xff1a;万&#xff0c;百万&#xff0c;十万消息发送时延&#xff1a;毫秒&#xff0c;毫秒&#xff0c;微秒可用性&#xff1a;主从&#xff0c;分…

【深度学习】机器学习概述(一)机器学习三要素——模型、学习准则、优化算法

​ 文章目录 一、基本概念二、机器学习的三要素1. 模型a. 线性模型b. 非线性模型 2. 学习准则a. 损失函数1. 0-1损失函数2. 平方损失函数&#xff08;回归问题&#xff09;3. 交叉熵损失函数&#xff08;Cross-Entropy Loss&#xff09;4. Hinge 损失函数 b. 风险最小化准则1.…

MQTT 介绍与学习 —— 筑梦之路

之前写过的相关文章&#xff1a; MQTT协议&#xff08;转载&#xff09;——筑梦之路_mqtt url-CSDN博客 k8s 部署mqtt —— 筑梦之路-CSDN博客 CentOS 7 搭建mqtt服务——筑梦之路_腾讯云宝塔搭 centos 7.9.2009 x86_64 建标准mqtt服务器-CSDN博客 mqtt简介 MQTT&#xff…

tcp/ip协议2实现的插图,数据结构5 (22 - 章)

(103) 103 二二1 协议控制块 结构 file, socket , rawcb , inpcb , tcpcb 之间的联系 (104) (105)

Python:如何将MCD12Q1\MOD11A2\MOD13A2原始数据集批量输出为TIFF文件(镶嵌/重投影/)?

博客已同步微信公众号&#xff1a;GIS茄子&#xff1b;若博客出现纰漏或有更多问题交流欢迎关注GIS茄子&#xff0c;或者邮箱联系(推荐-见主页). 00 前言 之前一段时间一直使用ENVI IDL处理遥感数据&#xff0c;但是确实对于一些比较新鲜的东西IDL并没有python那么好的及时性&…

【Linux】使用官方脚本自动安装 Docker(Ubuntu 22.04)

前言 Docker是一种开源平台&#xff0c;用于开发、交付和运行应用程序。它利用了容器化技术&#xff0c;使开发人员能够将应用程序及其依赖项打包到一个称为Docker容器的可移植容器中。这些容器可以在任何运行Docker的机器上快速、一致地运行&#xff0c;无论是开发环境、测试…

微服务架构之争:Quarkus VS Spring Boot

在容器时代&#xff08;“Docker时代”&#xff09;&#xff0c;无论如何&#xff0c;Java仍然活着。Java在性能方面一直很有名&#xff0c;主要是因为代码和真实机器之间的抽象层&#xff0c;多平台的成本&#xff08;一次编写&#xff0c;随处运行——还记得吗&#xff1f;&a…

Ubuntu虚拟机怎么设置静态IP

1 首先先ifconfig看一下使用的是哪个网络接口&#xff1a; 2 编辑 sudo vi /etc/netplan/00-installer-config.yamlnetwork:ethernets:ens33: # 根据您的网络接口进行修改&#xff0c;有的是eth0&#xff0c;有的是ens33&#xff0c;具体看第一步显示的是哪个网络接口addres…