Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/azure/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用jq处理巨大的GEOJson文件_Json_Stream_Geojson_Jq_Bigdata - Fatal编程技术网

使用jq处理巨大的GEOJson文件

使用jq处理巨大的GEOJson文件,json,stream,geojson,jq,bigdata,Json,Stream,Geojson,Jq,Bigdata,给定一个GEOJson文件,如下所示:- { "type": "FeatureCollection", "features": [ { "type": "Feature", "properties": { "FEATCODE": 15014 }, "geometry": { "type": "Polygon", "coordinates": [ ..... 我想以以下内容结束:- { "type": "Featu

给定一个GEOJson文件,如下所示:-

{
  "type": "FeatureCollection",
  "features": [
   {
     "type": "Feature",
     "properties": {
     "FEATCODE": 15014
  },
  "geometry": {
    "type": "Polygon",
    "coordinates": [
     .....
我想以以下内容结束:-

{
  "type": "FeatureCollection",
  "features": [
   {
     "tippecanoe : {"minzoom" : 13},
     "type": "Feature",
     "properties": {
     "FEATCODE": 15014
  },
  "geometry": {
    "type": "Polygon",
    "coordinates": [
     .....
即,我已将TipperCanoe对象添加到数组功能中的每个功能中

我可以通过以下方式实现这一点:-

 jq '.features[].tippecanoe.minzoom = 13' <GEOJSON FILE> > <OUTPUT FILE>
jq'.features[].tippecanoe.minzoom=13'>
这对于小文件来说很好。但是处理一个414Mb的大文件似乎要花费很长时间,因为处理器已经达到最大值,并且输出文件中没有写入任何内容

进一步阅读jq,似乎--stream命令行参数可能会有所帮助,但我完全搞不清楚如何将其用于我的目的


如果能提供一个示例命令行,并解释--stream正在做什么,我将不胜感激。

另一种解决方案可以是:

jq '.features |= map_values(.tippecanoe.minzoom = 13)'
为了测试这一点,我创建了一个示例JSON作为

d = {'features': [{"type":"Feature", "properties":{"FEATCODE": 15014}} for i in range(0,N)]}
并根据
N
检查执行时间。有趣的是,虽然
map_值
方法在
N
中似乎具有线性复杂性,
.features[].tippecanoe.minzoom=13
表现出二次行为(对于N=50000,前一种方法大约在0.8秒内完成,而后一种方法大约需要47秒)

或者,您也可以使用Python手动执行此操作:

import json
import sys

data = {}
with open(sys.argv[1], 'r') as F:
    data = json.load(F)

extra_item = {"minzoom" : 13}
for feature in data['features']:
    feature["tippecanoe"] = extra_item

with open(sys.argv[2], 'w') as F:
    F.write(json.dumps(data))

在这种情况下,
map
map\u值快得多(*):

然而,使用这种方法仍然需要足够的RAM

p、 如果您想使用jq生成一个大文件进行计时,请考虑:

def N: 1000000;

def data:
   {"features": [range(0;N) | {"type":"Feature", "properties": {"FEATCODE": 15014}}] };

(*)使用
map
,100MB为20s,近似线性。

单通道jq方法可能需要比可用内存更多的RAM。如果是这种情况,那么下面将显示一种简单的全jq方法,以及一种基于jq和awk的更经济的方法

这两种方法是相同的,只是将对象流重新构造为单个JSON文档。使用awk可以非常经济地完成此步骤

在这两种情况下,假定包含所需形式对象的大型JSON输入文件名为input.JSON

仅限jq jq和awk 性能比较 为了进行比较,使用了在.features[]中包含10000000个对象的输入文件。它的大小约为1GB

u+s:


这里,基于GitHub的@nicowilliams的工作,是一个使用jq提供的流式解析器的解决方案。该解决方案在内存方面非常经济,但如果输入较大,则当前速度相当慢

该解决方案有两部分:一个用于将更新注入到使用--stream命令行选项生成的流中的函数;以及一个用于将流转换回原始格式的JSON的函数

调用: program.jq 测试数据的生成 示例输出 N=2时:

[
{"type":"Feature","properties":{"FEATCODE":15014},"tippecanoe":{"minzoom":13}}
,
{"type":"Feature","properties":{"FEATCODE":15014},"tippecanoe":{"minzoom":13}}
]

在我的600k功能文件中仍然需要很长时间。我不得不求助于一些可怕的东西,比如塞德的#“属性”#“蒂普卡诺”:{“minzoom”:13},“属性”#g'@CitizenFish在这种情况下,我倾向于更健壮的东西,例如Python——我用一个例子更新了答案(对于这个特定的情况,它似乎要快得多)…谢谢,但它并没有真正回答我的问题,而我的问题是针对--stream的。python脚本似乎一次就加载了json,我怀疑这会导致大文件的问题/分页。我的一些是>5Gbah的,事实上,那么可能会更相关。。。
jq -c  '.features[]' input.json |
    jq -c '.tippecanoe.minzoom = 13' |
    jq -c -s '{type: "FeatureCollection", features: .}'
jq -c '.features[]' input.json |
   jq -c '.tippecanoe.minzoom = 13' | awk '
     BEGIN {print "{\"type\": \"FeatureCollection\", \"features\": ["; }
     NR==1 { print; next }
           {print ","; print}
     END   {print "] }";}'
jq-only:              15m 15s
jq-awk:                7m 40s
jq one-pass using map: 6m 53s
jq -cnr --stream -f program.jq input.json
# inject the given object into the stream produced from "inputs" with the --stream option
def inject(object):
  [object|tostream] as $object
  | 2
  | truncate_stream(inputs)
  | if (.[0]|length == 1) and length == 1
    then $object[]
    else .
    end ;

# Input: the object to be added
# Output: text
def output:
  . as $object
  | ( "[",
      foreach fromstream( inject($object) ) as $o
        (0;
         if .==0 then 1 else 2 end;
         if .==1 then $o else ",", $o end),
      "]" ) ;

{}
| .tippecanoe.minzoom = 13
| output
def data(N):
 {"features":
  [range(0;2) | {"type":"Feature", "properties": {"FEATCODE": 15014}}] };
[
{"type":"Feature","properties":{"FEATCODE":15014},"tippecanoe":{"minzoom":13}}
,
{"type":"Feature","properties":{"FEATCODE":15014},"tippecanoe":{"minzoom":13}}
]