The line:
query: "$.features[*].properties.urls.pbf"
is written in JSONPath convention. JSONPath is to JSON what XPath is to XML → a mini “query language” to navigate nested structures.
$ → root object{ "foo": 123 }
$ = the whole object$.foo = 123. → child operator{ "a": { "b": 42 } }
$.a = { "b": 42 }$.a.b = 42[*] → wildcard array{ "nums": [10, 20, 30] }
$.nums[*] = [10, 20, 30].. → recursive descent** in globbing).{ "foo": { "bar": { "baz": 99 } } }
$..baz = 99[] → array index / slice / filter[0] → first item\[1:3] → slice\[?(@.key=="value")] → filterExample:
{
"users": [
{"id": 1, "role": "admin"},
{"id": 2, "role": "user"}
]
}
$.users[0].id = 1\$.users[*].role = ["admin", "user"]\$.users[?(@.role=="admin")].id = [1]@ → current objectUsed inside filters.
query: "$.features[*].properties.urls.pbf"
Applied to your GeoJSON:
{
"features": [
{
"properties": {
"urls": {
"pbf": "https://download.geofabrik.de/asia/afghanistan-latest.osm.pbf"
}
}
},
{
"properties": {
"urls": {
"pbf": "https://download.geofabrik.de/asia/india-latest.osm.pbf"
}
}
}
]
}
Step by step:
$ → start at root object\.features → go into the features array\[*] → take every element in that array\.properties.urls.pbf → drill down into properties → urls → pbf👉 Result = list of all PBF download URLs:
[
"https://download.geofabrik.de/asia/afghanistan-latest.osm.pbf",
"https://download.geofabrik.de/asia/india-latest.osm.pbf"
]
$ = root\. = child\[*] = all items in array\[0], [1:3] = array index/slice\?() = filter with condition\@ = current object\.. = recursive descent (all levels)