源码阅读
文章平均质量分 95
默而识之者
帮助别人,快乐自己
展开
-
How it works(27) PostGIS源码解析(A) 项目的配置与编译
PostGIS 项目自然无需作过多介绍,但作为一种被 SQL 语言包装到 PostgreSQL 后面的工具集,它究竟是如何工作的对于普通用户来说其实是一个黑盒。有必要打开这个黑盒子看一看,以便在必要的时刻为其赋予有价值的新功能。原创 2024-08-09 17:08:38 · 945 阅读 · 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 · 764 阅读 · 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 · 332 阅读 · 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 · 1185 阅读 · 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 · 2374 阅读 · 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 · 2124 阅读 · 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 · 418 阅读 · 1 评论 -
How it works(20) Geotrellis是如何在Spark上计算的(A) 数据读取
引入我们会使用Geotrellis自然是因为它能利用spark进行高效的分布式计算,而分布式计算无论在数据读取还是计算上都与常规计算有许多不同.我们就以计算一张影像的NDVI结果为例,看看Geotrellis是如何在spark上读取计算的:package demoimport geotrellis.layer._import geotrellis.util._import geotrellis.spark._import geotrellis.spark.store.hadoop.Had.原创 2021-07-18 10:26:54 · 439 阅读 · 1 评论 -
How it works(19) Geotrellis是如何读取GeoTiff的(D) 锦上添花的宏模型
1. 引入宏在Geotrellis中更类似于一种锦上添花的存在:没有它不会动摇整体的功能,使用它则会带来许多方便.在官方文档中,宏的使用被放置在额外的high-performance-scala一节.如同官方文档所说,宏的存在是为了提高效率:计算的效率:不使用传统的泛型,避免拆装箱的消耗.增强某些算法的速度.编程的效率:提高某些代码的可读性.自动生成部分重复代码.宏编程属于元编程领域,本身具有一定的难度和不稳定性,相关的功能也在随着Scala的演进而更新,因此在此并不十分原创 2021-05-26 23:03:23 · 165 阅读 · 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 · 513 阅读 · 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 · 285 阅读 · 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 · 802 阅读 · 0 评论 -
How it works(15) OpenDroneMap结构简析
引入OpenDroneMap(以下简称ODM),是一套非常完整的开源无人机影像三维重建服务,我以前写过的NodeODM源码阅读就是ODM的子项目.当时我所在的公司主营业务是无人机相关,基于ODM我们打造了一套全自动化无人机数据处理链路:无人机影像在线回传,自动构建成最终的正摄影像.ODM是一个好产品.举个例子:就算我梳理了ODM的脉络,我其实依旧不理解SLAM,毕竟这是一个门槛比较高的领域,但这并不妨碍我对ODM进行二次服务化的服务平稳好用的运行了大半年.什么是好的产品?ODM整个项目在我完全不了解原创 2020-08-22 21:01:44 · 3652 阅读 · 5 评论 -
How it works(14) GDAL2Tiles源码阅读
引入gdal2tiles(以下简称g2t),这个历史悠久的切图脚本依然能发挥其功用,因为它稳定的做好了它应做的东西.相比前面说过的gdal2mbtiles(以下简称g2m),我倒是更喜欢它,单文件脚本,运行只安装一个GDAL库足矣.同样因为有了g2m,我也是带着对比的心态提出几个问题:从表现来看,g2t更慢慢的原因是什么可以采用g2m加速吗与g2m对比,其算法有何差异精简原...原创 2020-01-21 13:31:34 · 1658 阅读 · 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 · 1094 阅读 · 0 评论 -
How it works(2) autocannon源码阅读(A)
autocannon是纯node实现的接口压力测试工具,市面上类似的产品很多,老牌的AB,带有图形界面的soap ui等.不过autocannon可以方便的进行命令行调用,甚至在代码内调用,这对于nodejs项目的单元测试来说是相当方便的.下面就来简单分析一下他的源码.综述上一篇我对winston框架做了源码分析,其核心关键词是流,通过流将模块链接起来.而对于autocannon,关键词是...原创 2019-03-03 12:54:41 · 541 阅读 · 0 评论 -
How it works(3) Tilestrata源码阅读(A)
引入什么是Tilestrata在地图服务领域,我们的选择其实是不多的.商业的首推arcgis server,开源的一般是mapserver和geoserver.这些专业地图服务其专业性很强,强大到可以满足几乎所有地图需求.不过正是因为有许多我们日常几乎用不到的专业功能,它们都十分的重,无论是从代码结构还是运行消耗(使用java编写的geoserver和arcgis server尤甚)上.轻量...原创 2019-03-03 12:55:36 · 448 阅读 · 0 评论 -
How it works(4) Tilestrata源码阅读(B) 地图负载均衡
引入阅读Tilestrata的源码是绕不开Tilestrata-Balancer(以下简称TB)这个默认的负载均衡服务的.其特性是:支持动态增加,减少节点定时检查节点健康状况简单的请求过滤大多数服务会采取专业的负载均衡或者反向代理,比如常见的nginx.理论上讲,nodejs的http-proxy性能是拍马也不及nginx的,但对于地图瓦片服务,绝大多数瓶颈在瓦片的生成,而非反向代理...原创 2019-03-03 12:56:11 · 269 阅读 · 0 评论 -
How it works(5) TileStache源码阅读(A) 核心框架
引入作为一个维护时间更长久的地图服务器(从2010年至今),Python编写的TileStache有着跟Nodejs编写的Tiletrata不同的设计理念:全面专业.包含较多常用或不常用的专业地理信息功能.配置文件.与Tilestrata的代码即配置不同,TileStache完全基于一个独立的配置文件来调配整个系统.功能相比Tilestrata的只编写框架,功能完全靠插件加载,Til...原创 2019-03-03 12:57:06 · 300 阅读 · 0 评论 -
How it works(6) TileStache源码阅读(B) 自带功能模块
引入TileStache的核心阅读完了,就可以看看具体的功能部分是如何运行的.功能部分有4大类:Caches.pyPixelEffects.pyPixels.pyProviders.py模块Caches.py缓存的使用在上一篇已经看过了:读取缓存不需要锁写入缓存必须先加锁,再写入,再解锁所有的缓存都必须实现如下的方法:savereadlock/unlock...原创 2019-03-03 12:57:43 · 172 阅读 · 0 评论 -
How it works(7) GDAL2Mbtiles源码阅读(A) 框架与存储
引入gdal2Mbtiles是个小工具(以下简称g2m),其作用是将栅格地图(主要是Tiff格式)切成瓦片,存入Mbtiles格式的数据库中,以便于其他支持Mbtiles格式的地图服务器直接调用.一开始我也是为了用它来切割Tiff底图,发布Tileserver-GL服务的,不过用了一下,发现其切图速度比较快.所以想看一下其内部结构.觉得其代码并不简单,也是一个深思熟虑的系统.整体架构通观...原创 2019-03-03 12:58:54 · 1007 阅读 · 0 评论 -
How it works(8) GDAL2Mbtiles源码阅读(B) 影像切割与处理
vips.py最重要的切图模块,使用的是libvips这一快速轻量的c++模块的py绑定pyvips,这也是g2m里最大的一个模块.切图主要分为两部分:瓦片分隔波段处理瓦片分割瓦片分割是g2m的核心功能.基本流程是:获取图片(直接使用原片或重采样后的图片)从图片中裁取固定大小计算该部分所属行列号,进行存储.因为实际使用中,基本不可能只取某个特定的级别,因此对于低缩放级别...原创 2019-03-03 12:59:40 · 855 阅读 · 0 评论 -
How it works(9) GDAL2Mbtiles源码阅读(C) 影像预处理与核心流程
gdal.pygdal.py封装了所需的与gdal相关的操作.主要用来进行切割前的处理.主要操作有投影变换与抽取波段:def preprocess(inputfile, outputfile, band=None, spatial_ref=None, resampling=None, compress=None, **kwargs): # 所有要进行的预...原创 2019-03-03 13:00:13 · 554 阅读 · 0 评论 -
How it works(10) NodeODM源码阅读(A) 鉴权与任务初始化
引入OpenDroneMap(ODM)是一款非常强大的无人机成果处理软件,可以直接将无人机拍摄的照片处理成正摄影像甚至进行三维建模.ODM本身是基于python的OpenSFM编写的命令行工具,为了方便实际使用,NodeODM出现了.NodeODM是Nodejs编写的一套带有可视化界面的API,实现了通过接口上传图片,修改配置,获取进度等常用功能.因此我们一般用的都是NodeODM,很少会直接...原创 2019-03-19 22:15:13 · 561 阅读 · 0 评论 -
How it works(11) NodeODM源码阅读(B) 任务控制与任务后处理
任务运行时上一节的最后,通过"TaskManager.singleton().addNew(task);"方法,新建的任务被加入进了任务管理器,自此,任务的一切都交由任务管理器来调控了.由上方的代码可以看出,TaskManager是一个单例实例.原因是保证当Taskmanager(下面简称任务管理器)在不同模块被引用时,都指向唯一的任务管理器实例.//在整个应用启动时,执行TaskManag...原创 2019-03-22 20:01:19 · 635 阅读 · 0 评论 -
How it works(12) Tileserver-GL源码阅读(A) 服务的初始化
引入Tileserver-GL(以下简称tileserver),klokantech公司出品的nodejs编写的地图服务,也是我们已经用于生产环境的地图服务.它是少有的开箱即用的且带有图形界面的轻量级地图服务了,这也是我们能快速的将它应用于实际的原因.Tileserver方便且美观的地图渲染且能与maputnik完美结合,这几乎是我第一次找到能完全替代geoserver的组合,而它同时也包含了...原创 2019-06-22 14:29:42 · 647 阅读 · 0 评论 -
How it works(1) winston3源码阅读(A)
winston 是我在 nodejs 下最常用的日志框架,那么他到底是如何工作的呢?winston 的运行核心winston 中有两个关键词: 记录器(logger)和传输器(transport).记录器负责收集/修饰分配进入的每一条日志,传输器则负责最终把日志记录到的哪,整个 winston 其实就是多个流(stream)的链式调用.记录器继承了交换流(transform),而传输器...原创 2019-03-03 12:53:11 · 512 阅读 · 0 评论