RasterLite2 栅格数据处理函数全量参考:从 Coverage 创建到像元、金字塔与地图输出

ℹ️ 读者定位

适合你,如果: 你正在用 SQLite / SpatiaLite 做离线 GIS、桌面 GIS、单文件数据交付或栅格预览,想按函数名快速定位 RasterLite2 的处理入口。

开始前需要: 会写基础 SQL,理解 SQLite BLOB、坐标系和栅格的行列像元;如果要执行导入或导出,还需要准备带 RasterLite2 的原生构建和测试影像。

读完可以完成: 从运行库探测开始,找到 Coverage 创建、外部影像导入、像元取样、统计、Tile 预览、金字塔、地图输出和导出函数,并用 Section / Tile 记录判断数据是否真的写入。

暂时不适合: 只想找 PostGIS Raster 函数,或需要某个发行版的安装包、性能基准和已经验证的生产部署脚本;本文不把未经现场运行的结果写成成功证据。

📄 先记住这句话

RL2_Version() 只能证明当前连接看到了 RasterLite2;RL2_CreateRasterCoverage() 只能证明 Coverage 结构创建成功;只有 Section / Tile 有记录并且 Tile 能被取样或预览,才有理由说栅格数据已经进入数据库。

在工作中,我们经常会遇到一个误判:SQLite 文件能打开,raster_coverages 表也存在,于是就认为 RasterLite2 已经可以处理栅格了。实际上,这只说明我们走到了数据库结构层,离"Coverage 可读、Tile 有数据、地图能输出"还差几步。

说白了,RasterLite2 的函数不能只按字母表查,要按栅格生命周期查:先探测,再创建,再导入,再取样或渲染,最后导出。

这篇内容分为以下几个部分:

  1. 先把 SQLite、SpatiaLite、RasterLite2 和 Coverage 对象拆开。
  2. 用一组 SQL 确认当前构建支持哪些函数和 codec。
  3. 按 Pixel、Palette、Statistics、Tile、Coverage、Pyramid 等功能组查全量函数。
  4. 走一遍导入、查询、地图输出、导出和 Vector Draping 的处理链路。
  5. 用四层证据判断到底是"库可用",还是"影像真的进库了"。

一、先把 RasterLite2 放回 SQLite 体系

1.1. RasterLite2 解决什么问题

SQLite 负责数据库文件、表、事务和 BLOB;SpatiaLite 负责通用空间元数据、Geometry BLOB、空间 SQL 和空间索引;RasterLite2 则负责把大栅格组织成 Coverage、Section、Tile 和 Pyramid,保存到 SQLite 中,并提供栅格读写与地图输出能力。

bash 复制代码
SQLite 文件
  ├─ SpatiaLite:空间元数据、Geometry、空间 SQL、空间索引
  ├─ RasterLite2:Coverage / Section / Tile / Pyramid
  ├─ Raster Style:栅格样式和 Styled Layer 关联
  └─ RL2 Map Configuration:地图配置、WMS、样式和输出参数

这里有一个关键边界:SpatiaLite 能加载,并不等于当前构建一定带完整 RasterLite2。 mod_spatialitelibrasterlite2、SQLite、GEOS、PROJ、Cairo、XML 和各种 codec 的版本与依赖关系,都可能影响函数是否注册成功。

1.2. Coverage、Section、Tile、Pyramid 怎么分工

可以把一个 Coverage 理解成"同一套栅格规则下的数据容器":它约束 Sample Type、Pixel Type、波段数、压缩方式、Tile 尺寸、SRID、像元分辨率和 NoData 像元。

对象 作用 常见落点
Coverage 顶层栅格容器和配置 raster_coverages
Section 导入的一幅影像或一个覆盖片段 <coverage>_sections
Tile 被切分后的栅格瓦片 <coverage>_tiles
Tile data 压缩后的像元 BLOB <coverage>_tile_data
Pyramid 更低分辨率的层级 levelssection_levels 等表

RasterLite2 Coverage、Section、Tile、Pixel 与 Pyramid 的对象关系

所以,CreateRasterCoveragesTable() 只是创建 Coverage 目录表;RL2_CreateRasterCoverage() 才是创建一个具体 Coverage;RL2_LoadRaster() 成功并写出 Section / Tile,才说明外部影像已经进入数据库。

1.3. 函数返回值和真实证据不是一回事

RasterLite2 常见返回约定如下:

  • 1:成功或布尔真。
  • 0:失败或布尔假。
  • -1:参数无效或发生错误;部分对象函数出错时会返回 NULL
  • BLOB 返回值:可能是 Pixel、Palette、Tile、PNG、统计图或原始像元缓冲区。

不要只看返回值,还要看数据库中有没有对应对象。例如 RL2_CreateRasterCoverage() 返回 1,最多说明 Coverage 结构创建成功;它不表示任何 GeoTIFF 已经导入。

二、第一轮探测:先确认函数和依赖真的存在

2.1. 版本、CPU 和依赖库探测

官方参考页把运行环境探测单独列为一组。第一次打开连接时,建议先执行:

bash 复制代码
SELECT RL2_Version();
SELECT RL2_Target_CPU();
SELECT RL2_Cairo_Version();
SELECT RL2_Curl_Version();
SELECT RL2_Zlib_Version();
SELECT RL2_LZMA_Version();
SELECT RL2_LZ4_Version();
SELECT RL2_ZSTD_Version();
SELECT RL2_PNG_Version();
SELECT RL2_JPEG_Version();
SELECT RL2_TIFF_Version();
SELECT RL2_GeoTIFF_Version();
SELECT RL2_WEBP_Version();
SELECT RL2_OpenJPEG_Version();
SELECT RL2_Leptonica_Version();

完整函数名是:RL2_VersionRL2_Target_CPURL2_Cairo_VersionRL2_Curl_VersionRL2_Zlib_VersionRL2_LZMA_VersionRL2_LZ4_VersionRL2_ZSTD_VersionRL2_PNG_VersionRL2_JPEG_VersionRL2_TIFF_VersionRL2_GeoTIFF_VersionRL2_WEBP_VersionRL2_OpenJPEG_VersionRL2_Leptonica_Version

如果 spatialite_version() 成功而 RL2_Version()no such function,优先检查当前原生库是否真的带 RasterLite2,而不是先改 SQL。

2.2. codec 与 Leptonica 探测

RasterLite2 的压缩能力取决于编译时依赖。可以一次性检查:

bash 复制代码
SELECT
  RL2_has_codec_none()       AS none_codec,
  RL2_has_codec_deflate()   AS deflate_codec,
  RL2_has_codec_deflate_no() AS deflate_no_codec,
  RL2_has_codec_lzma()      AS lzma_codec,
  RL2_has_codec_lzma_no()   AS lzma_no_codec,
  RL2_has_codec_lz4()       AS lz4_codec,
  RL2_has_codec_lz4_no()    AS lz4_no_codec,
  RL2_has_codec_zstd()      AS zstd_codec,
  RL2_has_codec_zstd_no()   AS zstd_no_codec,
  RL2_has_codec_png()       AS png_codec,
  RL2_has_codec_jpeg()      AS jpeg_codec,
  RL2_has_codec_fax4()      AS fax4_codec,
  RL2_has_codec_webp()      AS webp_codec,
  RL2_has_codec_ll_webp()   AS lossless_webp_codec,
  RL2_has_codec_jp2()       AS jp2_codec,
  RL2_has_codec_ll_jp2()    AS lossless_jp2_codec,
  RL2_has_leptonica()       AS leptonica;

全量函数包括:RL2_has_codec_noneRL2_has_codec_deflateRL2_has_codec_deflate_noRL2_has_codec_lzmaRL2_has_codec_lzma_noRL2_has_codec_lz4RL2_has_codec_lz4_noRL2_has_codec_zstdRL2_has_codec_zstd_noRL2_has_codec_pngRL2_has_codec_jpegRL2_has_codec_fax4RL2_has_codec_webpRL2_has_codec_ll_webpRL2_has_codec_jp2RL2_has_codec_ll_jp2RL2_has_leptonica

NONEPNGJPEGFAX4 等能力在官方参考页中有固定支持说明;LZMA、LZ4、ZSTD、WebP 和 JPEG2000 更应该以当前连接的返回值为准。不要因为文档里出现了某个 codec,就直接在生产库里选择它。

2.3. 线程、WMS、PDF 和标签选项

这些函数通常不是"处理一块像元"的函数,而是设置后影响后续调用的选项。

并行执行

bash 复制代码
SELECT RL2_GetMaxThreads();
SELECT RL2_SetMaxThreads(4);

函数为 RL2_GetMaxThreadsRL2_SetMaxThreads。官方说明最大线程数是连接级选项,新连接初始值为 0,是否适合打开要结合实际负载和原生库线程安全边界。

WMS 重试

函数为 RL2_GetMaxWmsRetriesRL2_SetMaxWmsRetriesRL2_GetWmsPauseRL2_SetWmsPause

bash 复制代码
SELECT RL2_GetMaxWmsRetries();
SELECT RL2_SetMaxWmsRetries(3);
SELECT RL2_GetWmsPause();
SELECT RL2_SetWmsPause(500);

它们只影响后续 WMS 请求,不会修复 URL、坐标系或远程服务本身的问题。

PDF 页面参数

函数为 RL2_GetPdfMarginUOMRL2_SetPdfMarginUOMRL2_GetPdfMarginsHorzRL2_SetPdfMarginHorzRL2_GetPdfMarginsVertRL2_SetPdfMarginVertRL2_GetPdfPaperFormatRL2_SetPdfPaperFormatRL2_GetPdfDPIRL2_SetPdfDPIRL2_GetPdfOrientationRL2_SetPdfOrientation

bash 复制代码
SELECT RL2_SetPdfPaperFormat('A4');
SELECT RL2_SetPdfOrientation('Landscape');
SELECT RL2_SetPdfDPI(300);
SELECT RL2_SetPdfMarginUOM('mm');
SELECT RL2_SetPdfMarginHorz(10);
SELECT RL2_SetPdfMarginVert(10);

官方允许的纸张包括 A0A5,方向为 PortraitLandscape,单位为 mmin。这类设置是连接级选项,应该在生成 PDF 前显式设置,不要依赖默认值。

标签渲染开关

函数为:

  • RL2_IsAntiLabelCollisionEnabledRL2_EnableAntiLabelCollisionRL2_DisableAntiLabelCollision
  • RL2_IsLabelWrapTextEnabledRL2_EnableLabelWrapTextRL2_DisableLabelWrapText
  • RL2_IsLabelAutorotateEnabledRL2_EnableLabelAutorotateRL2_DisableLabelAutorotate
  • RL2_IsLabelShifPositionEnabledRL2_EnableLabelShifPositionRL2_DisableLabelShifPosition

这些选项同样是连接级状态。拼写里的 ShifPosition 是官方函数名,调用时不要自行改成 ShiftPosition

2.4. 外部文件函数的安全边界

RL2_LoadRaster、字体加载/导出、GeoTIFF / TIFF / JPEG / ASCII Grid 导出等函数会访问文件系统。官方参考页明确提示,部分函数只有在环境变量 SPATIALITE_SECURITY=relaxed 时才可用。

🚨 不要把 relaxed 当成默认生产配置

外部文件 SQL 会把数据库连接变成可以读写本机文件的入口。生产环境应使用绝对路径、目录白名单、最小权限账户,并记录谁在什么时候执行了导入或导出;不要为了跑通示例而对不可信 SQL 开放任意文件路径。

三、像元、Palette、Statistics 和 Tile 函数

3.1. Pixel BLOB:创建、检查、读取和修改

Pixel 是 RasterLite2 用来描述一个像元或 NoData 像元的序列化 BLOB。常用函数如下:

函数 作用
RL2_CreatePixel(sampleType, pixelType, numBands) 创建初始值为 0 的 Pixel BLOB
RL2_CreatePixelNone() 创建 NONE / NoData Pixel
RL2_IsValidPixel(pixel, sampleType, numBands) 检查 Pixel BLOB 是否匹配类型和波段数
RL2_IsPixelNone(pixel) 判断是否为 NoData Pixel
RL2_GetPixelType(pixel) 读取 Pixel Type
RL2_GetPixelSampleType(pixel) 读取 Sample Type
RL2_GetPixelNumBands(pixel) 读取波段数
RL2_GetPixelValue(pixel, bandIndex) 读取指定波段值,索引从 0 开始
RL2_SetPixelValue(pixel, bandIndex, value) 返回写入新值后的 Pixel BLOB
RL2_IsTransparentPixel(pixel) / RL2_IsOpaquePixel(pixel) 检查透明或不透明状态
RL2_SetTransparentPixel(pixel) / RL2_SetOpaquePixel(pixel) 返回修改透明状态后的 BLOB
RL2_PixelEquals(pixel1, pixel2) 比较两个 Pixel 对象是否相同
RL2_GetPixelFromRasterByPoint(...) 按地图坐标从 Coverage 取像元

一个最小的对象检查示意如下:

bash 复制代码
WITH p AS (
  SELECT RL2_CreatePixel('UINT8', 'RGB', 3) AS pixel
)
SELECT
  RL2_IsValidPixel(pixel, 'UINT8', 3) AS is_valid,
  RL2_GetPixelType(pixel) AS pixel_type,
  RL2_GetPixelSampleType(pixel) AS sample_type,
  RL2_GetPixelNumBands(pixel) AS band_count,
  RL2_GetPixelValue(pixel, 0) AS band_0
FROM p;

注意两点:第一波段索引是 0,不是 1;第二,RL2_SetPixelValue 返回的是新 BLOB,不能假设它会原地修改 SQLite 中已有值。

按点查询时,官方提供两类重载:按 pyramid_level 取样,或按水平 / 垂直分辨率取样。

bash 复制代码
SELECT RL2_GetPixelFromRasterByPoint(
  NULL,
  'dem',
  MakePoint(120.123, 30.456, 4326),
  0
);

db_prefixNULL 时默认使用 MAIN;输入必须是单个 POINT;如果点的 SRID 和 Coverage 不同,官方说明会自动重投影到 Coverage 的 SRID。返回 NULL 可能是点不在 Coverage、参数不合法、没有对应 Tile 或发生错误,应用层应结合范围和日志进一步判断。

3.2. Palette 与 Font:从颜色表到字体资源

Palette 函数适合处理带颜色索引的栅格:

  • RL2_IsValidRasterPalette(palette, sampleType):检查 Palette BLOB。
  • RL2_GetPaletteNumEntries(palette):读取颜色项数量。
  • RL2_GetPaletteColorEntry(palette, entryIndex):读取 #rrggbb 颜色。
  • RL2_SetPaletteColorEntry(palette, entryIndex, hexRgbColor):返回修改颜色后的 BLOB。
  • RL2_PaletteEquals(palette1, palette2):比较两个 Palette。

Font 函数服务于地图标签或样式资源:

  • 外部文件进库:RL2_LoadFontFromFile
  • 数据库导出:RL2_ExportFontToFile
  • 校验和属性读取:RL2_IsValidFontRL2_CheckFontFacenameRL2_GetFontFamilyRL2_GetFontFacenameRL2_IsFontBoldRL2_IsFontItalic

Font 导入和导出涉及文件系统并受 SPATIALITE_SECURITY=relaxed 约束。不要把字体 BLOB 有效误写成地图标签已经正确渲染;还需要样式、字体名称、地图配置和输出函数共同验证。

3.3. Raster Statistics:NoData、有效像元和波段统计

统计对象本身也是 BLOB,函数可以分为三组:

方向 函数
校验 RL2_IsValidRasterStatistics
总体信息 RL2_GetRasterStatistics_NoDataPixelsCountRL2_GetRasterStatistics_ValidPixelsCountRL2_GetRasterStatistics_SampleTypeRL2_GetRasterStatistics_BandsCount
波段统计 RL2_GetBandStatistics_MinRL2_GetBandStatistics_MaxRL2_GetBandStatistics_AvgRL2_GetBandStatistics_VarRL2_GetBandStatistics_StdDev
图形化 RL2_GetBandStatistics_HistogramRL2_GetBandHistogramFromImage

波段索引同样从 0 开始。RL2_GetBandHistogramFromImage 接受 PNG 或 JPEG BLOB,并要求给出 image/pngimage/jpeg MIME 类型。

这里一定要注意:统计值是数据质量和渲染拉伸的重要输入,但它们不能代替坐标范围检查。DEM 的最小值、最大值和 NoData 处理正确,不代表地图 CRS 一定正确。

3.4. Tile:校验与 PNG 预览

Tile 相关函数只有 4 个,但它们是"数据库里确实有可读栅格"的重要验证入口:

  • RL2_IsValidRasterTile(dbPrefix, coverageName, pyramidLevel, tileOdd, tileEven):检查 Tile BLOB 是否属于指定 Coverage 和金字塔层级。
  • RL2_GetTileImage(dbPrefix, coverageName, tileID):把 Tile 生成 PNG 预览;DATAGRID 默认按灰度理解,多波段默认看第一波段。
  • RL2_GetTripleBandTileImage(...):从多个波段组合 RGB PNG,可指定背景色和透明开关。
  • RL2_GetMonoBandTileImage(...):从指定波段生成灰度 PNG,可指定背景色和透明开关。

示意 SQL:

bash 复制代码
SELECT RL2_GetMonoBandTileImage(NULL, 'dem', 1, 0);
SELECT RL2_GetTileImage(NULL, 'dem', 1);

返回的是图像 BLOB,不是文件路径。Java、C# 或 Python 应用要把 BLOB 写成 PNG,再在地图组件里显示;SQL 返回非空只证明预览函数拿到了可解码 Tile,不等于完整 Coverage 渲染完成。

四、Coverage 生命周期:创建、导入、查询和金字塔

4.1. 创建 Coverage 不是导入影像

RasterLite2 相关的基础表通常由 SpatiaLite 初始化过程或以下函数准备:

bash 复制代码
SELECT CreateRasterCoveragesTable();
SELECT ReCreateRasterCoveragesTriggers();

CreateMissingRasterlite2Columns() 用于旧数据库升级时补齐 RasterLite2 元数据列。它不是每次新建数据库都必须执行的"导入函数"。

创建具体 Coverage 的核心函数是 RL2_CreateRasterCoverage。官方参考页给出了从 10 参数到带 NoData、策略等可选参数的多个重载,核心参数包括:

bash 复制代码
-- 示意 SQL:参数必须按实际影像与目标版本调整。
SELECT RL2_CreateRasterCoverage(
  'dem',       -- coverageName
  'FLOAT',     -- sampleType
  'DATAGRID',  -- pixelType
  1,           -- numBands
  'DEFLATE',   -- compressionType
  80,          -- quality
  256, 256,    -- tileWidth, tileHeight
  4326,        -- SRID
  0.0001,      -- horizontal pixel resolution
  0.0001      -- vertical pixel resolution
);

sampleType 描述单个样本的数据类型,pixelType 描述像元的解释方式,numBands 是波段数,压缩和 Tile 尺寸会影响存储与处理方式,SRID 和分辨率决定空间定位。NoData Pixel 如果需要声明,应按官方重载使用 RL2_CreatePixelNone() 或实际 Sample Type 对应的 Pixel BLOB。

创建后建议检查:

bash 复制代码
SELECT name
FROM sqlite_master
WHERE type IN ('table', 'view')
  AND (name = 'raster_coverages' OR name LIKE 'dem_%');
 
SELECT * FROM raster_coverages WHERE coverage_name = 'dem';

看到 raster_coveragesdem_* 表,只能证明结构创建成功;还没有证明 Section / Tile 已经有记录。

4.2. RL2_LoadRaster 与原始像元导入

外部文件导入函数是 RL2_LoadRaster。官方列出的重载支持:

bash 复制代码
RL2_LoadRaster(coverageName, sourcePath)
RL2_LoadRaster(coverageName, sourcePath, withWorldFile)
RL2_LoadRaster(coverageName, sourcePath, withWorldFile, forceSRID)
RL2_LoadRaster(coverageName, sourcePath, withWorldFile, forceSRID, pyramidize)
RL2_LoadRaster(coverageName, sourcePath, withWorldFile, forceSRID, pyramidize, transaction)

它尝试在已有 Coverage 中创建并填充新的 Section,支持 JPEG、TIFF、GeoTIFF 和 ASCII Grid。withWorldFile 表示是否读取配套 World File;JPEG、普通 TIFF 和 ASCII Grid 通常需要显式 forceSRIDpyramidize 控制是否立即构建直接支持该 Section 的金字塔;最后的 transaction 控制是否由函数内部处理事务。

bash 复制代码
-- 示意 SQL;外部路径、SRID 和选项需要由应用白名单控制。
SELECT RL2_LoadRaster(
  'dem',
  'D:/data/dem.tif',
  0,
  4326,
  1,
  1
);

如果数据已经由应用解码成原始像元 BLOB,可以使用 RL2_ImportSectionRawPixels

bash 复制代码
RL2_ImportSectionRawPixels(coverageName, sectionName, width, height, pixelBuf, boundingBox)
RL2_ImportSectionRawPixels(..., pyramidize)
RL2_ImportSectionRawPixels(..., pyramidize, transaction)
RL2_ImportSectionRawPixels(..., pyramidize, transaction, bigEndian)

这条路线不读取外部 GeoTIFF,而是由调用方提供宽、高、像元缓冲区和空间范围;因此更适合 Java、C# 或自定义传感器管线,但像元排列、字节序、Sample Type、波段数和 NoData 必须与 Coverage 完全匹配。

另外两个导入入口是:

  • RL2_LoadRastersFromDir:按目录批量导入栅格文件。
  • RL2_LoadRasterFromWMS:按 WMS URL、图层、样式、Bounding Box 和像元分辨率请求并导入。

它们都需要把远程服务、路径、坐标系、重试、超时和事务当成独立配置处理。

4.3. 点取样、默认波段和 Coverage 元数据

Coverage / Section 管理组的完整函数如下:

函数 作用
RL2_CreateRasterCoverage 创建具体 Coverage
RL2_CopyRasterCoverage 复制 Coverage
RL2_DropCoverage 删除 Coverage 及相关结构
RL2_DeleteSection 删除 Section
RL2_SetRasterCoverageInfos 设置 Coverage 信息元数据
RL2_SetRasterCoverageCopyright 设置版权信息
RL2_SetRasterCoverageDefaultBands 设置默认显示波段
RL2_SetRasterCoverageVisibilityRange 设置最小 / 最大比例尺可见范围
RL2_GetRasterCoverageMinScaleDenominator / RL2_GetRasterCoverageMaxScaleDenominator 读取可见比例尺范围
RL2_EnableRasterCoverageAutoNDVI / RL2_IsRasterCoverageAutoNdviEnabled 开启或检查自动 NDVI

这些函数通常需要已有 Coverage,并且很多函数会更新元数据而不是像元。比如设置默认波段不会改变原始数据,只会影响后续地图输出如何选择波段。

RL2_GetPixelFromRasterByPoint 是最适合做抽样验收的入口:先用一个已知范围内的 POINT 查询,再解码返回的 Pixel BLOB,检查类型、波段和值;不要只检查返回 BLOB 非空。

4.4. Pyramidize、PyramidizeMonolithic 与 DePyramidize

金字塔函数只有 3 个:

  • RL2_Pyramidize(coverageName):构建整个 Coverage 的 Section-based Pyramid。
  • RL2_Pyramidize(coverageName, sectionID, forceRebuild, transaction):按 Section 构建,可强制重建并控制事务。
  • RL2_PyramidizeMonolithic(coverageName):建立 Coverage 级的 Monolithic Pyramid。
  • RL2_DePyramidize(coverageName):删除已有 Pyramid 层级。

这里要分清两类策略:Section-based Pyramid 可以分别服务不同 Section;Monolithic Pyramid 面向整个 Coverage。forceRebuild 会销毁现有层级后重建,生产环境不要在没有备份和时间评估的情况下直接打开。

金字塔验收应该看三类证据:层级表是否出现、低分辨率查询是否命中对应层级、地图输出在缩放时是否真的使用了正确分辨率。只看到函数返回 1,还不能说明低层级图像质量正确。

五、地图输出、导出和矢量 Draping

5.1. Raster / Vector / WMS / Map Configuration 输出

地图输出函数把栅格数据、样式和空间范围组合成图像 BLOB:

函数 处理对象
RL2_GetMapImageFromRaster Raster Coverage,支持样式名、MIME、背景色和透明度等重载
RL2_GetStyledMapImageFromRaster 直接按样式生成 Raster 地图
RL2_GetMapImageFromVector Vector 图层叠加输出
RL2_GetStyledMapImageFromVector 带样式的 Vector 输出
RL2_GetMapImageFromWMS 请求远程 WMS 输出
RL2_GetImageFromMapConfiguration 按 RL2 Map Configuration 输出

Raster 地图最小形态可以理解为:数据库前缀、Coverage 名称、Bounding Box、输出宽高;可选样式名、MIME、背景色、透明开关和更多渲染选项。

bash 复制代码
RL2_GetMapImageFromRaster(
  dbPrefix, coverageName, boundingBox, width, height,
  styleName, mimeType, bgColor, transparent, ...
)

地图配置相关函数不在 RasterLite2 的单独 SQL reference list 中完整展开时,也要注意它和 Raster Style 的区别:注册样式只是保存样式定义;注册 Map Configuration 只是保存 XML BLOB;只有 RL2_GetImageFromMapConfiguration 返回有效图像,才说明至少跑通了一次地图输出。

5.2. Coverage 级导出与 Section 级导出

导出函数数量较多,最好的记法是先看"覆盖范围",再看"输出格式"。

Coverage 级导出

函数包括:

bash 复制代码
RL2_ExportRawPixels
RL2_WriteGeoTiff
RL2_WriteTiff
RL2_WriteTiffTFW
RL2_WriteJpeg
RL2_WriteJpegJGW
RL2_WriteAsciiGrid
RL2_WriteMonoBandGeoTiff
RL2_WriteMonoBandTiff
RL2_WriteMonoBandTiffTFW
RL2_WriteTripleBandGeoTiff
RL2_WriteTripleBandTiff
RL2_WriteTripleBandTiffTFW
RL2_WriteNdviAsciiGrid
RL2_WriteNdwiAsciiGrid

这些函数通常要求给出输出文件、宽高、Bounding Box 和像元分辨率;GeoTIFF / TIFF 还可以指定 World File、压缩方式和 Tile 尺寸;Mono Band 需要指定灰度波段;Triple Band 需要指定 R、G、B 波段索引;NDVI / NDWI 则依赖 Coverage 的波段语义。

Section 级导出

对应的 Section 级函数包括:

bash 复制代码
RL2_ExportSectionRawPixels
RL2_WriteSectionGeoTiff
RL2_WriteSectionTiff
RL2_WriteSectionTiffTFW
RL2_WriteSectionJpeg
RL2_WriteSectionJpegJGW
RL2_WriteSectionAsciiGrid
RL2_WriteSectionMonoBandGeoTiff
RL2_WriteSectionMonoBandTiff
RL2_WriteSectionMonoBandTiffTFW
RL2_WriteSectionTripleBandGeoTiff
RL2_WriteSectionTripleBandTiff
RL2_WriteSectionTripleBandTiffTFW
RL2_WriteSectionNdviAsciiGrid
RL2_WriteSectionNdwiAsciiGrid

Section 级函数多了 sectionID,只考虑选中 Section 的 Tile;Coverage 级函数则从整个 Coverage 组织输出。输出的 Bounding Box、宽高和水平 / 垂直分辨率必须一致,否则函数可能返回失败或生成空间位置错误的文件。

⚠️ World File 不是 CRS 元数据的替代品

JGWTFW 等 World File 主要提供像元变换参数,不能自动补齐完整的投影定义。导出后还要用 GDAL、GIS 客户端或应用代码检查 CRS、范围、行列方向和像元中心约定。

5.3. NDVI / NDWI 与 Mono / Triple Band 导出

RL2_WriteNdviAsciiGridRL2_WriteNdwiAsciiGrid 及其 Section 版本,适合把特定波段组合导出为分析结果。它们不是"任意两个波段都能直接得到有意义的指数"的魔法函数,必须先确认 Coverage 的默认波段和输入影像的光谱含义。

RL2_WriteMonoBandGeoTiffRL2_WriteMonoBandTiffRL2_WriteMonoBandTiffTFW 适合灰度或单波段产品;RL2_WriteTripleBandGeoTiffRL2_WriteTripleBandTiffRL2_WriteTripleBandTiffTFW 适合把任意指定波段组合成 RGB。波段索引从 0 开始,输出质量还会受到 NoData、范围拉伸、压缩方式和目标分辨率影响。

5.4. Vector Draping:把栅格值附加到几何

RL2_DrapeGeometries 用 DEM / DTM 栅格给已有 2D 几何生成 3D 几何,也可以把值写入 M 坐标。核心参数包括数据库前缀、Raster Coverage、Coverage 列表、空间表、2D 几何列和 3D 几何列;可选 NoData、densify 距离、Z 简化距离和 updateM

bash 复制代码
RL2_DrapeGeometries(
  dbPrefix,
  rasterCoverage,
  coverageList,
  spatialTable,
  geom2D,
  geom3D,
  noDataValue,
  densifyDist,
  ZsimplifyDist,
  updateM
)

RL2_GetDrapingLastError() 用于读取 Draping 模块最近的警告或错误信息。Draping 成功后仍要检查几何类型、Z / M 坐标、NoData 处理和顶点加密结果,不能只依赖返回 1。

六、按任务查函数:最小验收链路与踩坑总结

6.1. "库可用"到"Tile 可读"的四层证据

推荐用下面四层证据排查:

层级 最小证据 可以证明 不能证明
SQLite 连接打开、sqlite_version() 文件和 SQLite 可用 RasterLite2 已加载
Runtime RL2_Version()、codec 探测 当前连接有 RasterLite2 SQL 和依赖信息 某个 Coverage 存在
Coverage raster_coverages 有记录、RL2_CreateRasterCoverage() 成功 Coverage 结构存在 外部影像已导入
Data Section / Tile 有记录,Tile BLOB 可校验或预览 栅格像元已经写入并可读取 地图样式和 CRS 一定正确
Map RL2_GetMapImageFromRaster() 或 GDAL 输出有效图像 至少一次地图输出链路跑通 生产环境所有缩放级别都正确

最小 SQL 检查骨架:

bash 复制代码
SELECT sqlite_version();
SELECT RL2_Version();
SELECT RL2_has_codec_deflate();
SELECT RL2_has_codec_png();
 
SELECT name
FROM sqlite_master
WHERE type = 'table'
  AND name IN ('raster_coverages', 'dem_sections', 'dem_tiles', 'dem_tile_data');
 
SELECT COUNT(*) FROM raster_coverages WHERE coverage_name = 'dem';
SELECT COUNT(*) FROM dem_sections;
SELECT COUNT(*) FROM dem_tiles;
SELECT COUNT(*) FROM dem_tile_data;

6.2. 常见报错怎么定位

现象 优先检查
no such function: RL2_Version 原生扩展是否包含 RasterLite2,位数和依赖是否匹配
RL2_CreateRasterCoverage 返回 0 Sample / Pixel Type、波段数、压缩、SRID、分辨率和 Coverage 名称
RL2_LoadRaster 失败 路径、文件格式、World File、forceSRID、Security 环境变量和读权限
Coverage 有记录但 Section 为 0 只创建了 Coverage,尚未成功导入影像
Tile 为 0 Section 导入失败、范围不覆盖、事务未提交或查询了错误的 Pyramid 层级
Pixel 返回 NULL 点不在 Coverage、SRID 不一致、分辨率 / 层级不匹配或 Tile 无法解码
地图有图但位置错 CRS、Bounding Box、像元分辨率、World File 和轴方向
WMS 不稳定 URL、版本、图层、样式、坐标系、重试次数和暂停时间

6.3. Java / C# / GDAL 如何接入

RasterLite2 函数属于当前 SQLite 连接的原生能力。Java 的 JDBC、C# 的 Microsoft.Data.Sqlite 或 GDAL 驱动,解决的是"怎么打开 SQLite / 调用数据",并不会自动补齐 RasterLite2。

  • Java / JDBC:先确认 native SQLite、扩展加载和 JNA / JNI 路径,再执行 RL2_Version() 和 Coverage SQL。
  • C#:确认 x64 / x86 位数一致,设置 native DLL 搜索路径,再决定是调用 RasterLite2 SQL,还是只读 Tile 表并用 librasterlite2 C API 解码。
  • GDAL:用 RASTERLITE2:database.sqlite:coverage 打开已有 Coverage,适合验证完整 Coverage 可读和导出链路。

本地资料已经验证过 Java / C# 的 SQLite 和 SpatiaLite 矢量接入,但这些结果不能直接替代 RasterLite2 栅格导入证据。应用接入完成后,仍要按本文的 Coverage → Section → Tile → Map 顺序验收。

6.4. 最后记住:先探测,再创建,再导入,最后渲染

如果只记一条流程,就记下面这条:

bash 复制代码
连接与 DLL
  → RL2_Version / codec 探测
  → raster_coverages 元数据准备
  → RL2_CreateRasterCoverage
  → RL2_LoadRaster 或 RL2_ImportSectionRawPixels
  → Section / Tile / Pixel 验收
  → Pyramidize
  → Tile 预览或 RL2_GetMapImageFromRaster
  → WriteGeoTiff / WriteAsciiGrid / 应用地图显示

RasterLite2 的价值,不只是"把栅格塞进 SQLite",而是把栅格存储、像元访问、压缩、金字塔、样式、地图配置和导出放进一条可复制的数据库工作流。它适合离线、单机、嵌入式和单文件交付场景;如果你需要高并发服务端分析、复杂权限和成熟的多用户栅格生态,就应该把 RasterLite2 与 PostGIS Raster、云原生栅格或专用栅格服务做任务级比较。

附录:官方函数全量索引

官方参考页中的函数按功能组整理如下。序号按本文索引连续编号;同名函数的不同参数重载合并为一行。函数是否可用、具体重载数量和依赖支持情况,仍需以目标构建的运行时为准。

Version / Architecture

序号 函数名 中文描述
1 RL2_Version 返回当前使用的 RasterLite2 版本。
2 RL2_Target_CPU 返回当前 RasterLite2 使用的 CPU 架构。
3 RL2_Cairo_Version 返回当前使用的 Cairo 版本。
4 RL2_Curl_Version 返回当前使用的 libcurl 版本。
5 RL2_Zlib_Version 返回 DEFLATE 使用的 zlib 版本。
6 RL2_LZMA_Version 返回 LZMA 使用的 liblzma 版本。
7 RL2_LZ4_Version 返回 LZ4 使用的 liblz4 版本。
8 RL2_ZSTD_Version 返回 ZSTD 使用的 libzstd 版本。
9 RL2_PNG_Version 返回 PNG 使用的 libpng 版本。
10 RL2_JPEG_Version 返回 JPEG 使用的 libjpeg 或 libjpeg-turbo 版本。
11 RL2_TIFF_Version 返回 TIFF 使用的 libtiff 版本。
12 RL2_GeoTIFF_Version 返回 GeoTIFF 使用的 libgeotiff 版本。
13 RL2_WEBP_Version 返回 WebP 使用的 libwebp 版本。
14 RL2_OpenJPEG_Version 返回 JPEG2000 使用的 libopenjp2 版本。
15 RL2_Leptonica_Version 返回当前使用的 Leptonica 版本。

Codecs

序号 函数名 中文描述
16 RL2_has_codec_none 检查 NONE 编解码器是否支持。
17 RL2_has_codec_deflate 检查带 Delta Filter 的 DEFLATE 是否支持。
18 RL2_has_codec_deflate_no 检查不带 Delta Filter 的 DEFLATE 是否支持。
19 RL2_has_codec_lzma 检查带 Delta Filter 的 LZMA 是否支持。
20 RL2_has_codec_lzma_no 检查不带 Delta Filter 的 LZMA 是否支持。
21 RL2_has_codec_lz4 检查带 Delta Filter 的 LZ4 是否支持。
22 RL2_has_codec_lz4_no 检查不带 Delta Filter 的 LZ4 是否支持。
23 RL2_has_codec_zstd 检查带 Delta Filter 的 ZSTD 是否支持。
24 RL2_has_codec_zstd_no 检查不带 Delta Filter 的 ZSTD 是否支持。
25 RL2_has_codec_png 检查 PNG 编解码器是否支持。
26 RL2_has_codec_jpeg 检查 JPEG 编解码器是否支持。
27 RL2_has_codec_fax4 检查 FAX4 编解码器是否支持。
28 RL2_has_codec_webp 检查有损 WebP 是否支持。
29 RL2_has_codec_ll_webp 检查无损 WebP 是否支持。
30 RL2_has_codec_jp2 检查有损 JPEG2000 是否支持。
31 RL2_has_codec_ll_jp2 检查无损 JPEG2000 是否支持。
32 RL2_has_leptonica 检查 Leptonica 支持是否可用。

Connection / WMS / PDF / Label Options

序号 函数名 中文描述
33 RL2_GetMaxThreads 读取当前连接允许的最大并行线程数。
34 RL2_SetMaxThreads 设置当前连接允许的最大并行线程数。
35 RL2_GetMaxWmsRetries 读取 WMS 请求失败后的最大重试次数。
36 RL2_SetMaxWmsRetries 设置 WMS 请求失败后的最大重试次数。
37 RL2_GetWmsPause 读取 WMS 重试之间的暂停时间。
38 RL2_SetWmsPause 设置 WMS 重试之间的暂停时间。
39 RL2_GetPdfMarginUOM 读取 PDF 页边距的度量单位。
40 RL2_SetPdfMarginUOM 设置 PDF 页边距的度量单位。
41 RL2_GetPdfMarginsHorz 读取 PDF 左右水平边距。
42 RL2_SetPdfMarginHorz 设置 PDF 左右水平边距。
43 RL2_GetPdfMarginsVert 读取 PDF 上下垂直边距。
44 RL2_SetPdfMarginVert 设置 PDF 上下垂直边距。
45 RL2_GetPdfPaperFormat 读取 PDF 纸张规格。
46 RL2_SetPdfPaperFormat 设置 PDF 纸张规格。
47 RL2_GetPdfDPI 读取 PDF 输出 DPI。
48 RL2_SetPdfDPI 设置 PDF 输出 DPI。
49 RL2_GetPdfOrientation 读取 PDF 页面方向。
50 RL2_SetPdfOrientation 设置 PDF 页面方向。
51 RL2_IsAntiLabelCollisionEnabled 检查标签防碰撞是否启用。
52 RL2_EnableAntiLabelCollision 启用标签防碰撞。
53 RL2_DisableAntiLabelCollision 禁用标签防碰撞。
54 RL2_IsLabelWrapTextEnabled 检查标签自动换行是否启用。
55 RL2_EnableLabelWrapText 启用标签自动换行。
56 RL2_DisableLabelWrapText 禁用标签自动换行。
57 RL2_IsLabelAutorotateEnabled 检查标签自动旋转是否启用。
58 RL2_EnableLabelAutorotate 启用标签自动旋转。
59 RL2_DisableLabelAutorotate 禁用标签自动旋转。
60 RL2_IsLabelShifPositionEnabled 检查标签自动移位是否启用。
61 RL2_EnableLabelShifPosition 启用标签自动移位。
62 RL2_DisableLabelShifPosition 禁用标签自动移位。

Pixel / Palette / Font / Statistics / Tile

序号 函数名 中文描述
63 RL2_IsValidPixel 检查 Pixel BLOB 是否匹配 Sample Type 和波段数。
64 RL2_IsPixelNone 检查 Pixel 是否为 NONE / NoData。
65 RL2_CreatePixel 创建初始值为 0 的 Pixel BLOB。
66 RL2_CreatePixelNone 创建 NONE / NoData Pixel BLOB。
67 RL2_GetPixelType 读取 Pixel Type。
68 RL2_GetPixelSampleType 读取 Pixel 的 Sample Type。
69 RL2_GetPixelNumBands 读取 Pixel 的波段数。
70 RL2_GetPixelValue 读取指定波段的像元值,波段索引从 0 开始。
71 RL2_SetPixelValue 返回写入指定波段值后的新 Pixel BLOB。
72 RL2_IsTransparentPixel 检查 Pixel 是否透明。
73 RL2_IsOpaquePixel 检查 Pixel 是否不透明。
74 RL2_SetTransparentPixel 返回设置为透明后的 Pixel BLOB。
75 RL2_SetOpaquePixel 返回设置为不透明后的 Pixel BLOB。
76 RL2_PixelEquals 比较两个 Pixel BLOB 是否相同。
77 RL2_GetPixelFromRasterByPoint 按地图点和层级或分辨率从 Coverage 取像元。
78 RL2_IsValidRasterPalette 检查 Palette BLOB 是否有效。
79 RL2_GetPaletteNumEntries 读取 Palette 的颜色项数量。
80 RL2_GetPaletteColorEntry 读取 Palette 指定索引的 HEX-RGB 颜色。
81 RL2_SetPaletteColorEntry 返回修改指定 Palette 颜色后的新 BLOB。
82 RL2_PaletteEquals 比较两个 Palette BLOB 是否相同。
83 RL2_LoadFontFromFile 从外部字体文件向数据库加载字体。
84 RL2_ExportFontToFile 将数据库中的字体导出为外部文件。
85 RL2_IsValidFont 检查 Font BLOB 是否有效。
86 RL2_CheckFontFacename 检查 Font BLOB 是否匹配指定字体名称。
87 RL2_GetFontFamily 读取字体族名称。
88 RL2_GetFontFacename 读取字体完整名称。
89 RL2_IsFontBold 检查字体是否为粗体。
90 RL2_IsFontItalic 检查字体是否为斜体。
91 RL2_IsValidRasterStatistics 检查 Raster Statistics BLOB 是否有效。
92 RL2_GetRasterStatistics_NoDataPixelsCount 读取 NoData 像元数量。
93 RL2_GetRasterStatistics_ValidPixelsCount 读取有效像元数量。
94 RL2_GetRasterStatistics_SampleType 读取统计对象的 Sample Type。
95 RL2_GetRasterStatistics_BandsCount 读取统计对象的波段数量。
96 RL2_GetBandStatistics_Min 读取指定波段最小值。
97 RL2_GetBandStatistics_Max 读取指定波段最大值。
98 RL2_GetBandStatistics_Avg 读取指定波段平均值。
99 RL2_GetBandStatistics_Var 读取指定波段方差。
100 RL2_GetBandStatistics_StdDev 读取指定波段标准差。
101 RL2_GetBandStatistics_Histogram 读取指定波段的直方图 PNG BLOB。
102 RL2_GetBandHistogramFromImage 从 PNG 或 JPEG 图像 BLOB 生成波段直方图。
103 RL2_IsValidRasterTile 检查 Tile BLOB 是否匹配 Coverage 和金字塔层级。
104 RL2_GetTileImage 将 Tile 生成 PNG 预览图像。
105 RL2_GetTripleBandTileImage 从指定三个波段生成 RGB PNG。
106 RL2_GetMonoBandTileImage 从指定波段生成灰度 PNG。

Coverage / Section / Pyramid

序号 函数名 中文描述
107 RL2_CopyRasterCoverage 复制一个 Raster Coverage。
108 RL2_CreateRasterCoverage 创建具体 Raster Coverage 及其栅格结构。
109 RL2_DeleteSection 删除指定 Section。
110 RL2_DropCoverage 删除 Coverage 及相关对象。
111 RL2_EnableRasterCoverageAutoNDVI 启用 Coverage 的自动 NDVI 能力。
112 RL2_GetRasterCoverageMaxScaleDenominator 读取 Coverage 最大比例尺分母。
113 RL2_GetRasterCoverageMinScaleDenominator 读取 Coverage 最小比例尺分母。
114 RL2_IsRasterCoverageAutoNdviEnabled 检查 Coverage 自动 NDVI 是否启用。
115 RL2_SetRasterCoverageCopyright 设置 Coverage 版权信息。
116 RL2_SetRasterCoverageDefaultBands 设置 Coverage 默认显示波段。
117 RL2_SetRasterCoverageInfos 设置 Coverage 的描述性元数据。
118 RL2_SetRasterCoverageVisibilityRange 设置 Coverage 的可见比例尺范围。
119 RL2_DePyramidize 删除 Coverage 已有金字塔层级。
120 RL2_Pyramidize 创建或重建 Section-based Pyramid。
121 RL2_PyramidizeMonolithic 创建 Coverage 级 Monolithic Pyramid。

Map / Import / Export / Draping

序号 函数名 中文描述
122 RL2_GetImageFromMapConfiguration 按 Map Configuration 生成地图图像 BLOB。
123 RL2_GetMapImageFromRaster 按范围和尺寸生成 Raster 地图图像。
124 RL2_GetMapImageFromVector 生成 Vector 图层地图图像。
125 RL2_GetMapImageFromWMS 请求 WMS 并返回地图图像。
126 RL2_GetStyledMapImageFromRaster 按样式生成 Raster 地图图像。
127 RL2_GetStyledMapImageFromVector 按样式生成 Vector 地图图像。
128 RL2_ImportSectionRawPixels 从原始像元 BLOB 缓冲区导入 Section。
129 RL2_LoadRaster 从 JPEG、TIFF、GeoTIFF 或 ASCII Grid 导入 Section。
130 RL2_LoadRasterFromWMS 从 WMS 请求并导入栅格 Section。
131 RL2_LoadRastersFromDir 从目录批量导入栅格文件。
132 RL2_ExportRawPixels 按 Coverage 导出原始像元 BLOB。
133 RL2_WriteAsciiGrid 将 Coverage 导出为 ASCII Grid。
134 RL2_WriteGeoTiff 将 Coverage 导出为 GeoTIFF。
135 RL2_WriteJpeg 将 Coverage 导出为 JPEG。
136 RL2_WriteJpegJGW 将 Coverage 导出为 JPEG 并写入 JGW。
137 RL2_WriteMonoBandGeoTiff 将指定单波段导出为灰度 GeoTIFF。
138 RL2_WriteMonoBandTiff 将指定单波段导出为灰度 TIFF。
139 RL2_WriteMonoBandTiffTFW 将指定单波段导出为 TIFF 并写入 TFW。
140 RL2_WriteNdviAsciiGrid 将 Coverage 的 NDVI 结果导出为 ASCII Grid。
141 RL2_WriteNdwiAsciiGrid 将 Coverage 的 NDWI 结果导出为 ASCII Grid。
142 RL2_WriteTiff 将 Coverage 导出为普通 TIFF。
143 RL2_WriteTiffTFW 将 Coverage 导出为 TIFF 并写入 TFW。
144 RL2_WriteTripleBandGeoTiff 将指定三个波段导出为 RGB GeoTIFF。
145 RL2_WriteTripleBandTiff 将指定三个波段导出为 RGB TIFF。
146 RL2_WriteTripleBandTiffTFW 将指定三个波段导出为 TIFF 并写入 TFW。
147 RL2_ExportSectionRawPixels 按 Section 导出原始像元 BLOB。
148 RL2_WriteSectionAsciiGrid 将指定 Section 导出为 ASCII Grid。
149 RL2_WriteSectionGeoTiff 将指定 Section 导出为 GeoTIFF。
150 RL2_WriteSectionJpeg 将指定 Section 导出为 JPEG。
151 RL2_WriteSectionJpegJGW 将指定 Section 导出为 JPEG 并写入 JGW。
152 RL2_WriteSectionMonoBandGeoTiff 将 Section 的指定单波段导出为灰度 GeoTIFF。
153 RL2_WriteSectionMonoBandTiff 将 Section 的指定单波段导出为灰度 TIFF。
154 RL2_WriteSectionMonoBandTiffTFW 将 Section 的指定单波段导出为 TIFF 并写入 TFW。
155 RL2_WriteSectionNdviAsciiGrid 将 Section 的 NDVI 结果导出为 ASCII Grid。
156 RL2_WriteSectionNdwiAsciiGrid 将 Section 的 NDWI 结果导出为 ASCII Grid。
157 RL2_WriteSectionTiff 将指定 Section 导出为普通 TIFF。
158 RL2_WriteSectionTiffTFW 将指定 Section 导出为 TIFF 并写入 TFW。
159 RL2_WriteSectionTripleBandGeoTiff 将 Section 的三个波段导出为 RGB GeoTIFF。
160 RL2_WriteSectionTripleBandTiff 将 Section 的三个波段导出为 RGB TIFF。
161 RL2_WriteSectionTripleBandTiffTFW 将 Section 的三个波段导出为 TIFF 并写入 TFW。
162 RL2_DrapeGeometries 使用 DEM / DTM 栅格为 2D 几何生成 3D 或 M 坐标。
163 RL2_GetDrapingLastError 读取 Vector Draping 最近一次警告或错误。

参考资料

相关推荐
Quincy_Freak1 小时前
银河麒麟终端数据处理标准化实践:SQLiteGo 效能评估与落地路径
sqlite·数据库管理·大数据分析·银河麒麟·aarch64·sqlitego
ggabb2 天前
汉语与英语启蒙读物:两种文明基因的深层对话
sqlite
张人玉2 天前
基于 Python 的桌面端智能识别与可视化系统——生活垃圾分类可视化大屏
python·分类·sqlite·echarts·生活
皮卡丘不断更3 天前
手机优先的 Personal Ledger:把账目、学习和复盘放到同一个入口
数据库·sqlite·fastapi·开源项目·个人效率
winfredzhang3 天前
从零构建家庭照片管理系统:Django 模块化单体实战,以及我踩到的 4 个真实坑
python·postgresql·django·sqlite·bootsrap
衿心.3 天前
Django TemplateDoesNotExist
数据库·django·sqlite
张人玉4 天前
基于 Vue 3 + ECharts + Three.js + Express + SQLite——智慧城市数字孪生可视化平台
javascript·vue.js·信息可视化·sqlite·echarts
En^_^Joy6 天前
Django模板与静态文件使用指南
python·django·sqlite
En^_^Joy6 天前
Django中间件:请求拦截和响应(类似装饰器)
中间件·django·sqlite