源码阅读
文章平均质量分 95
默而识之者
帮助别人,快乐自己
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
How it works(27) PostGIS源码解析(A) 项目的配置与编译
PostGIS 项目自然无需作过多介绍,但作为一种被 SQL 语言包装到 PostgreSQL 后面的工具集,它究竟是如何工作的对于普通用户来说其实是一个黑盒。有必要打开这个黑盒子看一看,以便在必要的时刻为其赋予有价值的新功能。原创 2024-08-09 17:08:38 · 1527 阅读 · 0 评论 -
How it works(26) Geotrellis是如何在Spark上计算的(G) 导出结果到GeoTiff文件
1. 引入 在过去几章,我们从NDVI计算入手,深入到Geotrellis中了解了内置的各种算子.如今我们回归最初计算NDVI的DEMO代码,看一下如何将计算后的NDVI结果以GeoTiff的格式输出: val ndviTiledRDD: TileLayerRDD[SpatialKey] = // ... 省略计算ndvi的步骤 // 1. 将TileLayerRDD[SpatialKey]对象拼接为一个Raster[Tile]对象 val raster: Raster[Tile] = ndviTiledR原创 2022-05-11 08:18:56 · 927 阅读 · 0 评论 -
How it works(25) Geotrellis是如何在Spark上计算的(F) 地图代数之其他Focal类算子
1. 引入 上一章我们研究了Focal类中最基础的游标(Cursor)类算子,游标类算子的核心思想代表了大多数Focal类算子的实现方法. 当然,通用的往往更慢,Geotrellis中还有其他三类为特定使用场景优化的Focal类算子: 核(kernel)算子:为卷积运算优化的游标类算子 像元尺度(cellwise)类算子:为简单邻域优化的游标类算子 表面点(surfacepoint)类算子:为山体运算优化的Focal类算子 我们先从核算子入手. 2. 核算子-以Convolve算子为例 核算子是为卷积运原创 2022-05-04 11:15:10 · 428 阅读 · 0 评论 -
How it works(24) Geotrellis是如何在Spark上计算的(E) 地图代数之游标类算子
1. 引入 上一章我们研究了Geotrellis中Local算子的实现.Local类算子种类较多,实现也较简单,其核心为:Tile中某个位置的值由另一个Tile中相同位置的值通过计算得到. Geotrellis中也存在更加复杂的Focal类算子,其核心为:Tile中某个像元位置的值由该像元周围若干像元(邻域)的值经过特定计算得到.可见,Focal类算子有两个关键点: 定义邻域 定义如何根据邻域内容计算结果 我们首先看邻域是如何定义的. 2. 邻域定义 在Geotrellis中,邻域描述了某个像元周围哪些原创 2022-04-29 11:14:20 · 1285 阅读 · 0 评论 -
How it works(23) Geotrellis是如何在Spark上计算的(D) 地图代数之Local类算子
1. 引入 在上一节,我们使用Tile对象的Map方法实现了计算NDVI的功能.但对于一些更复杂的功能,Map(f)的操作无法胜任或实现起来极为麻烦.好在Geotrellis实现了较为丰富的地图代数功能,能为我们节省不少时间. 官方文档对此部分着墨不多,不过我们可以知道,内置的地图代数算子主要分为三大类: 局部运算(Local):作用于单个像元 焦点运算(Focal):作用于邻域内的所有像元 分区运算(Zonal):作用于区域内的所有像元 还有不属于三大类的水文相关算法(hydrology) 地图代原创 2022-04-03 17:27:41 · 2534 阅读 · 0 评论 -
How it works(22) Geotrellis是如何在Spark上计算的(C) 计算模型初探
1.引入 在上一章结尾我们最终生成了MultibandTileLayerRDD[SpatialKey]对象,一切都是为了最重要的步骤——计算——做准备. 2. 计算NDVI 首先我们回顾一下计算代码: val ndviTiledRDD: TileLayerRDD[SpatialKey] = tiledRDD.withContext { rdd => rdd.mapValues { tile => tile.convert(DoubleConstantNoDataCellT原创 2021-12-04 23:09:09 · 2262 阅读 · 0 评论 -
How it works(21) Geotrellis是如何在Spark上计算的(B) 转换索引
1. 引言 在上一章我们已经讨论了数据读取的实现,了解了Geotrellis如何从本地将若干Geotiff文件读取为RDD[(ProjectedExtent, MultibandTile)]对象的. 为了进行下一步的计算操作,我们需要将原始的ProjectedExtent索引转换为SpatialKey索引.具体步骤如下: // 1. 提取数据集元数据 val (_, metadata) = geoTiffRDD.collectMetadata[SpatialKey](FloatingLayoutScheme原创 2021-08-11 22:50:19 · 554 阅读 · 1 评论 -
How it works(20) Geotrellis是如何在Spark上计算的(A) 数据读取
引入 我们会使用Geotrellis自然是因为它能利用spark进行高效的分布式计算,而分布式计算无论在数据读取还是计算上都与常规计算有许多不同. 我们就以计算一张影像的NDVI结果为例,看看Geotrellis是如何在spark上读取计算的: package demo import geotrellis.layer._ import geotrellis.util._ import geotrellis.spark._ import geotrellis.spark.store.hadoop.Had.原创 2021-07-18 10:26:54 · 638 阅读 · 1 评论 -
How it works(19) Geotrellis是如何读取GeoTiff的(D) 锦上添花的宏模型
1. 引入 宏在Geotrellis中更类似于一种锦上添花的存在:没有它不会动摇整体的功能,使用它则会带来许多方便. 在官方文档中,宏的使用被放置在额外的high-performance-scala一节.如同官方文档所说,宏的存在是为了提高效率: 计算的效率: 不使用传统的泛型,避免拆装箱的消耗. 增强某些算法的速度. 编程的效率: 提高某些代码的可读性. 自动生成部分重复代码. 宏编程属于元编程领域,本身具有一定的难度和不稳定性,相关的功能也在随着Scala的演进而更新,因此在此并不十分原创 2021-05-26 23:03:23 · 292 阅读 · 0 评论 -
How it works(18) Geotrellis是如何读取GeoTiff的(C) Segment模型
1. 引入 上一篇我们讨论了Geotrellis如何设计底层的数据类型模型,Geotrellis实际上如何从tiff文件中将数据读取出来呢? 我们再次回顾下方的类结构图: 绿色的为类继承 红色的为特征实现 可以发现,UInt32GeotiffTile类中引入的特质大部分与两类行为有关: 与Segment相关的特质 与宏相关的特质 我们首先讨论与Segment相关的特质.在引入对Segment模型的解析之前,需要补充Geotiff中数据排列布局的相关知识. 2. 图像数据在tiff文件中的排布方式原创 2021-05-23 21:36:07 · 682 阅读 · 0 评论 -
How it works(17) Geotrellis是如何读取GeoTiff的(B) 数据判断模型
1. 引入 上一篇我们解析了如何读取元数据,有了元数据,我们就可以创建一个GeoTiffTile对象: def readSingleband(byteReader: ByteReader, streaming: Boolean, withOverviews: Boolean, byteReaderExternal: Option[ByteReader]): SinglebandGeoTiff = { def getSingleband(geoTiffTile: GeoTiffTile, info:原创 2021-05-09 20:44:00 · 383 阅读 · 0 评论 -
How it works(16) Geotrellis是如何读取GeoTiff的(A) 读取元数据
Geotrellis是如何读取GeoTiff的(A):读取元数据 1. 引入 Geotrellis是如何读取Geotiff?先看官方文档中读取单波段GeoTiff的样例: val path: String = "path/to/geotrellis/raster/data/geotiff-test-files/lzw_int32.tif" val geoTiff: SinglebandGeoTiff = GeoTiffReader.readSingleband(path) 我们可以追踪GeoTiffRea原创 2021-03-29 23:00:27 · 1027 阅读 · 0 评论 -
How it works(15) OpenDroneMap结构简析
引入 OpenDroneMap(以下简称ODM),是一套非常完整的开源无人机影像三维重建服务,我以前写过的NodeODM源码阅读就是ODM的子项目.当时我所在的公司主营业务是无人机相关,基于ODM我们打造了一套全自动化无人机数据处理链路:无人机影像在线回传,自动构建成最终的正摄影像. ODM是一个好产品.举个例子:就算我梳理了ODM的脉络,我其实依旧不理解SLAM,毕竟这是一个门槛比较高的领域,但这并不妨碍我对ODM进行二次服务化的服务平稳好用的运行了大半年. 什么是好的产品? ODM整个项目在我完全不了解原创 2020-08-22 21:01:44 · 5039 阅读 · 5 评论 -
How it works(14) GDAL2Tiles源码阅读
引入 gdal2tiles(以下简称g2t),这个历史悠久的切图脚本依然能发挥其功用,因为它稳定的做好了它应做的东西.相比前面说过的gdal2mbtiles(以下简称g2m),我倒是更喜欢它,单文件脚本,运行只安装一个GDAL库足矣.同样因为有了g2m,我也是带着对比的心态提出几个问题: 从表现来看,g2t更慢 慢的原因是什么 可以采用g2m加速吗 与g2m对比,其算法有何差异 精简 原...原创 2020-01-21 13:31:34 · 1939 阅读 · 0 评论 -
How it works(1) winston3源码阅读(A)
winston 是我在 nodejs 下最常用的日志框架,那么他到底是如何工作的呢? winston 的运行核心 winston 中有两个关键词: 记录器(logger)和传输器(transport). 记录器负责收集/修饰分配进入的每一条日志,传输器则负责最终把日志记录到的哪, 整个 winston 其实就是多个流(stream)的链式调用.记录器继承了交换流(transform),而传输器...原创 2019-03-03 12:53:11 · 641 阅读 · 0 评论 -
How it works(13) Tileserver-GL源码阅读(B) 栅格瓦片的渲染
serve_rendered.js 是什么使tileserver如此的无可替代? 是他的栅格瓦片渲染. 当Tilestrata和Tilestache还在用需要复杂配置文件的mapnik时,tileserver却将web页面的mapbox直接搬到了服务端,达到了前后端配置文件与效果的完全统一,在maputnik的帮助下,样式的调整也变得方便异常. 这就造就了整个tileserver里最大的模块:...原创 2019-07-03 21:35:35 · 1328 阅读 · 0 评论 -
How it works(12) Tileserver-GL源码阅读(A) 服务的初始化
引入 Tileserver-GL(以下简称tileserver),klokantech公司出品的nodejs编写的地图服务,也是我们已经用于生产环境的地图服务.它是少有的开箱即用的且带有图形界面的轻量级地图服务了,这也是我们能快速的将它应用于实际的原因. Tileserver方便且美观的地图渲染且能与maputnik完美结合,这几乎是我第一次找到能完全替代geoserver的组合,而它同时也包含了...原创 2019-06-22 14:29:42 · 856 阅读 · 0 评论 -
How it works(11) NodeODM源码阅读(B) 任务控制与任务后处理
任务运行时 上一节的最后,通过"TaskManager.singleton().addNew(task);"方法,新建的任务被加入进了任务管理器,自此,任务的一切都交由任务管理器来调控了. 由上方的代码可以看出,TaskManager是一个单例实例.原因是保证当Taskmanager(下面简称任务管理器)在不同模块被引用时,都指向唯一的任务管理器实例. //在整个应用启动时,执行TaskManag...原创 2019-03-22 20:01:19 · 822 阅读 · 0 评论 -
How it works(10) NodeODM源码阅读(A) 鉴权与任务初始化
引入 OpenDroneMap(ODM)是一款非常强大的无人机成果处理软件,可以直接将无人机拍摄的照片处理成正摄影像甚至进行三维建模.ODM本身是基于python的OpenSFM编写的命令行工具,为了方便实际使用,NodeODM出现了. NodeODM是Nodejs编写的一套带有可视化界面的API,实现了通过接口上传图片,修改配置,获取进度等常用功能.因此我们一般用的都是NodeODM,很少会直接...原创 2019-03-19 22:15:13 · 816 阅读 · 0 评论 -
How it works(9) GDAL2Mbtiles源码阅读(C) 影像预处理与核心流程
gdal.py gdal.py封装了所需的与gdal相关的操作.主要用来进行切割前的处理. 主要操作有投影变换与抽取波段: def preprocess(inputfile, outputfile, band=None, spatial_ref=None, resampling=None, compress=None, **kwargs): # 所有要进行的预...原创 2019-03-03 13:00:13 · 704 阅读 · 0 评论 -
How it works(8) GDAL2Mbtiles源码阅读(B) 影像切割与处理
vips.py 最重要的切图模块,使用的是libvips这一快速轻量的c++模块的py绑定pyvips,这也是g2m里最大的一个模块. 切图主要分为两部分: 瓦片分隔 波段处理 瓦片分割 瓦片分割是g2m的核心功能.基本流程是: 获取图片(直接使用原片或重采样后的图片) 从图片中裁取固定大小 计算该部分所属行列号,进行存储. 因为实际使用中,基本不可能只取某个特定的级别,因此对于低缩放级别...原创 2019-03-03 12:59:40 · 996 阅读 · 0 评论 -
How it works(7) GDAL2Mbtiles源码阅读(A) 框架与存储
引入 gdal2Mbtiles是个小工具(以下简称g2m),其作用是将栅格地图(主要是Tiff格式)切成瓦片,存入Mbtiles格式的数据库中,以便于其他支持Mbtiles格式的地图服务器直接调用. 一开始我也是为了用它来切割Tiff底图,发布Tileserver-GL服务的,不过用了一下,发现其切图速度比较快.所以想看一下其内部结构.觉得其代码并不简单,也是一个深思熟虑的系统. 整体架构 通观...原创 2019-03-03 12:58:54 · 1223 阅读 · 0 评论 -
How it works(6) TileStache源码阅读(B) 自带功能模块
引入 TileStache的核心阅读完了,就可以看看具体的功能部分是如何运行的. 功能部分有4大类: Caches.py PixelEffects.py Pixels.py Providers.py 模块 Caches.py 缓存的使用在上一篇已经看过了: 读取缓存不需要锁 写入缓存必须先加锁,再写入,再解锁 所有的缓存都必须实现如下的方法: save read lock/unlock ...原创 2019-03-03 12:57:43 · 236 阅读 · 0 评论 -
How it works(5) TileStache源码阅读(A) 核心框架
引入 作为一个维护时间更长久的地图服务器(从2010年至今),Python编写的TileStache有着跟Nodejs编写的Tiletrata不同的设计理念: 全面专业.包含较多常用或不常用的专业地理信息功能. 配置文件.与Tilestrata的代码即配置不同,TileStache完全基于一个独立的配置文件来调配整个系统. 功能 相比Tilestrata的只编写框架,功能完全靠插件加载,Til...原创 2019-03-03 12:57:06 · 404 阅读 · 0 评论 -
How it works(4) Tilestrata源码阅读(B) 地图负载均衡
引入 阅读Tilestrata的源码是绕不开Tilestrata-Balancer(以下简称TB)这个默认的负载均衡服务的.其特性是: 支持动态增加,减少节点 定时检查节点健康状况 简单的请求过滤 大多数服务会采取专业的负载均衡或者反向代理,比如常见的nginx.理论上讲,nodejs的http-proxy性能是拍马也不及nginx的,但对于地图瓦片服务,绝大多数瓶颈在瓦片的生成,而非反向代理...原创 2019-03-03 12:56:11 · 346 阅读 · 0 评论 -
How it works(3) Tilestrata源码阅读(A)
引入 什么是Tilestrata 在地图服务领域,我们的选择其实是不多的.商业的首推arcgis server,开源的一般是mapserver和geoserver.这些专业地图服务其专业性很强,强大到可以满足几乎所有地图需求.不过正是因为有许多我们日常几乎用不到的专业功能,它们都十分的重,无论是从代码结构还是运行消耗(使用java编写的geoserver和arcgis server尤甚)上. 轻量...原创 2019-03-03 12:55:36 · 544 阅读 · 0 评论 -
How it works(2) autocannon源码阅读(A)
autocannon是纯node实现的接口压力测试工具,市面上类似的产品很多,老牌的AB,带有图形界面的soap ui等.不过autocannon可以方便的进行命令行调用,甚至在代码内调用,这对于nodejs项目的单元测试来说是相当方便的. 下面就来简单分析一下他的源码. 综述 上一篇我对winston框架做了源码分析,其核心关键词是流,通过流将模块链接起来. 而对于autocannon,关键词是...原创 2019-03-03 12:54:41 · 663 阅读 · 0 评论
分享