草庐IT

一种激进的观点:不要再用 shp 格式了

岭南灯火 2023-03-28 原文

原文出自:switchfromshapefile.org

译者注:本文略偏激,但是我大部分赞同不要再用 shp 格式的思想,积极拥抱新的生产力。

ESRI Shapefile 简称 shp 格式,是由 ESRI 公开的一种矢量数据格式,它已经有30多年的历史了。

尽管这些年它为各行各业提供了巨大的生产力,但是它在现在这个需求越来越变态的行业中已经略显力不从心。

作为 GIS IT 行业的一员,是时候停止使用 shp 格式并引入新格式了。

shp 格式好的一面

列举了一些为什么它的占有率如此之高的原因:

  • 各种软件几乎都内置支持
  • 虽然格式是 ESRI 专有,但是其规范是公开的
  • 在大多数场景中它够用
    • 索引文件 (*.shx)为主文件(*.shp)提供良好的读取性能
    • 文件体积不大,它在未使用 zip 压缩时都要比其他格式要小一些(尤其是文本类型的格式)

shp 是一种不好的格式

原因可就多多了:

  • 无坐标系定义(憋急,待会你看下面仔细的介绍)
  • 是一种多文件格式
  • 属性名限制在10个字符
  • DBF文件限制了最多255个属性
  • 限制了数据类型,只能是 float、integer、date、text(text最多254字符)
  • 并不指明编码格式
  • 单文件最大2GB
  • 无拓扑
  • 几何类型在一个文件中是单一的
  • 复杂的数据结构是存不了的
  • 无法存储带纹理材质的三维数据;无法存储参数化对象等
  • 投影的定义
  • 必须在要素级别挨个指定几何类型,而不是在数据层面就指定
  • 无空值
  • ...

无坐标系定义

默认情况下,shp 格式是不带坐标系定义的,必须额外使用一个 *.prj 文件来定义。但是这里要说清楚,*.prj 并非 shp 格式规范里的内容,是额外加上去的。

多文件格式

你至少要三个文件才能完整使用一个 shp 格式 —— *.shx + *.shp + *.dbf

你甚至见过更多的文件,例如上面提到的 prj,还有 cfg,等等等等。通常,你需要进行 zip 打包或者挨个发送,才能保证数据完整,相信新手都有传少文件导致乌龙的情况。

属性名最多10个字符

所以,在一些古老的高校中仍然推崇使用拼音首字母来写属性,你用英文单词还随时可能爆掉。

最多255个属性

其实,255个属性放在先进的场景下也足够了,译者并不觉得是什么缺点。

属性值的类型支持得比较少

仅支持 floatintegerchardate 四种。对于 blob数组图像 就不支持了。

不指明编码格式

一定有朋友在刚接触时,发现 shp 的属性表是乱码的,这就是编码问题,原先编辑时用的是 gb 编码,换一台机器变成了 utf8,或者反过来,就会导致显示乱码,这个是历史遗留问题。

最大 2GB

.shp.dbf 文件最大 2GB,虽然 GDAL 的驱动克服了这个限制可以达到 4GB

译者觉得即使是 2GB,对于单份可编辑型数据来说也很大了。

无拓扑

它不存储复杂的几何关系。

不支持多几何类型

一个 shp 文件,只能是一种几何类型的文件。

译者觉得保持文件单一性也挺好的,并不认为一个数据文件里有多种几何类型是什么优点。

扁平的数据结构

链式数据结构,不支持层级数据的存储等。

三维的支持很有限

multipatch 虽然是三维几何形状,但是并不支持存储三维数据所需的纹理、材质信息。

投影信息互不兼容

通常,定义坐标系的 .prj 文件使用的是 ESRI WKT 来定义坐标系统投影信息,这个与 EPSG 的定义是不兼容的。

复合图形必须在要素层面定义

例如 multi-polygonmulti-polyline

无 NULL 值

无法在属性字段里写“没有数据”。不过译者觉得这是个好事。

替代品

目前有完全能替代 shp 文件格式的格式吗?似乎没有,毕竟瘦死的骆驼比马大,在 shp 格式还没有完全阻碍到生产之前,新格式并没有那么重要。

列举几个:

  • GeoPackage
  • FlatGeobuf
  • GeoJSON
  • GML
  • SpatialLite
  • CSV
  • KML

OGC GeoPackage

译者注:早些年我就写过 gpkg 格式的博客,百度搜即可,很容易找到。

主要特点:

  • 以 SQLite 为基础
  • 单文件
  • 支持矢量和栅格
  • 有官方拓展
  • 多软件支持

FlatGeobuf

译者注:我也写过这个格式,好好找找,能找到的~

主要特点:

  • 使用 FlatBuffers 二进制编码
  • 单文件
  • 支持矢量数据
  • 序列化和流式传输相当高效率
  • 性能优秀
  • 多编程语言、多软件支持

GeoJSON

这个不必多说,用过都知道,短小精悍,但是缺点也很明显。

OGC GML

这可能不太算一种 shp 格式的替代品,因为 GML 格式相对来说复杂得多,软件支持率也不算很广泛。

SpatialLite

SpatialLite 与 GeoPackage 一样是基于 SQLite 拓展而来,但是它只支持矢量数据。不过能用 SpatialLite 的场景,一般也支持 GeoPackage,SpatialLite 只是特定场合的 shp 格式替代品。

CSV

就是一文本表格,它不一定是地理数据,但是它存储地理数据的时候,最大的特点就是简单,对非 GIS 行业的人来说特别友好。

OGC KML

kml 是因谷歌地球的欢迎而起家的一种矢量数据格式,最大的特点就是能把样式也带进数据里。其本质是一种 XML 文本文件。仅支持 WGS84 坐标系。

ESRI GeoDatabase

作为一种 shp 替代品,GeoDatabase 格式完全称职。但是它并不开源,且数据格式为 ArcGIS 专有。

特点:

  • 面向对象的数据存储格式
  • 存储介质是多个散列文件
  • 支持极为复杂的数据模型
  • 专有格式且是闭源格式

有关一种激进的观点:不要再用 shp 格式了的更多相关文章

  1. ruby - 使用 ruby​​ 将 HTML 转换为纯文本并维护结构/格式 - 2

    我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h

  2. ruby-on-rails - 将 Ruby 中的日期/时间格式化为 YYYY-MM-DD HH :MM:SS - 2

    这个问题在这里已经有了答案:Railsformattingdate(4个答案)关闭4年前。我想格式化Time.Now函数以显示YYYY-MM-DDHH:MM:SS而不是:“2018-03-0909:47:19+0000”该函数需要放在时间中.现在功能。require‘roo’require‘roo-xls’require‘byebug’file_name=ARGV.first||“Template.xlsx”excel_file=Roo::Spreadsheet.open(“./#{file_name}“,extension::xlsx)xml=Nokogiri::XML::Build

  3. ruby - 我可以将我的 README.textile 以正确的格式放入我的 RDoc 中吗? - 2

    我喜欢使用Textile或Markdown为我的项目编写自述文件,但是当我生成RDoc时,自述文件被解释为RDoc并且看起来非常糟糕。有没有办法让RDoc通过RedCloth或BlueCloth而不是它自己的格式化程序运行文件?它可以配置为自动检测文件后缀的格式吗?(例如README.textile通过RedCloth运行,但README.mdown通过BlueCloth运行) 最佳答案 使用YARD直接代替RDoc将允许您包含Textile或Markdown文件,只要它们的文件后缀是合理的。我经常使用类似于以下Rake任务的东西:

  4. ruby - 是否有用于序列化和反序列化各种格式的对象层次结构的模式? - 2

    给定一个复杂的对象层次结构,幸运的是它不包含循环引用,我如何实现支持各种格式的序列化?我不是来讨论实际实现的。相反,我正在寻找可能会派上用场的设计模式提示。更准确地说:我正在使用Ruby,我想解析XML和JSON数据以构建复杂的对象层次结构。此外,应该可以将该层次结构序列化为JSON、XML和可能的HTML。我可以为此使用Builder模式吗?在任何提到的情况下,我都有某种结构化数据-无论是在内存中还是文本中-我想用它来构建其他东西。我认为将序列化逻辑与实际业务逻辑分开会很好,这样我以后就可以轻松支持多种XML格式。 最佳答案 我最

  5. ruby-on-rails - 事件管理员日期过滤器日期格式自定义 - 2

    是否有简单的方法来更改默认ISO格式(yyyy-mm-dd)的ActiveAdmin日期过滤器显示格式? 最佳答案 您可以像这样为日期选择器提供额外的选项,而不是覆盖js:=f.input:my_date,as::datepicker,datepicker_options:{dateFormat:"mm/dd/yy"} 关于ruby-on-rails-事件管理员日期过滤器日期格式自定义,我们在StackOverflow上找到一个类似的问题: https://s

  6. ruby-on-rails - 如何在 Rails 中设置路由的默认格式? - 2

    路由有如下代码:resources:orders,only:[:create],defaults:{format:'json'}resources:users,only:[:create,:update],defaults:{format:'json'}resources:delivery_types,only:[:index],defaults:{format:'json'}resources:time_corrections,only:[:index],defaults:{format:'json'}是否可以使用1个字符串为所有资源设置默认格式,每行不带“默认值”散列?谢谢。

  7. ruby-on-rails - Rails 4 WYSIWYG Bootsy 不显示格式 - 2

    我刚刚按照thebootsygempage上的安装说明进行操作在我保存并查看帖子内容之前,一切看起来都不错。这是输出在View中的样子:HeaderSubhead:似乎没有呈现任何html格式,因为它被引号或类似的东西转义了-其他人有这个问题吗?我没有在github页面或SO上看到任何问题来指出我正确的方向。除了遵循gem安装说明之外,我还没有做任何事情,但也许我错过了什么或者只是犯了一个愚蠢的错误。如果你还有什么想知道的,请尽管问。干杯 最佳答案 你需要有这样的东西,转义html: 关

  8. ruby - 在 Ruby 中将整数格式化为固定长度的字符串 - 2

    有没有一种简单的方法可以将给定的整数格式化为具有固定长度和前导零的字符串?#convertnumberstostringsoffixedlength3[1,12,123,1234].map{|e|???}=>["001","012","123","234"]我找到了解决方案,但也许还有更聪明的方法。format('%03d',e)[-3..-1] 最佳答案 如何使用%1000而不是进行字符串操作来获取最后三位数字?[1,12,123,1234].map{|e|format('%03d',e%1000)}更新:根据theTinMan的

  9. ruby-on-rails - 如何正确格式化字符串,如 'mccdougal' 到 'McDougal' - 2

    什么Ruby或RailsDSL会将字符串"mccdougal"格式化为"McDougal",同时留下字符串"McDougal"原样?将titleize传递给"McDougal"结果如下:"McDougal".titleize#=>"McDougal" 最佳答案 据我所知,没有可以处理这种情况的Rails助手。这是一个非标准的边缘案例,需要特殊处理。但是,您可以创建自定义字符串变形。您可以将这段代码放入初始化程序中:ActiveSupport::Inflector.inflections(:en)do|inflect|inflect.

  10. ruby-on-rails - 有没有一种工具可以在编码时自动保存对文件的增量更改? - 2

    我最喜欢的Google文档功能之一是它会在我工作时不断自动保存我的文档版本。这意味着即使我在进行关键更改之前忘记在某个点进行保存,也很有可能会自动创建一个保存点。至少,我可以将文档恢复到错误更改之前的状态,并从该点继续工作。对于在MacOS(或UNIX)上运行的Ruby编码器,是否有具有等效功能的工具?例如,一个工具会每隔几分钟自动将Gitcheckin我的本地存储库以获取我正在处理的文件。也许我有点偏执,但这点小保险可以让我在日常工作中安心。 最佳答案 虚拟机有些人可能讨厌我对此的回应,但我在编码时经常使用VIM,它具有自动保存功

随机推荐