NDJSON to GeoJSON
Paste newline-delimited GeoJSON — one feature per line, as a query export or a streaming dump — and get a single FeatureCollection back, ready for a map. Record separators, bare geometries and blank lines are all handled.
NDJSON to GeoJSON
What this tool does
It reads the input line by line and collects every GeoJSON object it finds into one FeatureCollection. A line may be a Feature, a bare geometry (which gets wrapped in a feature with empty properties), or even a whole FeatureCollection — whose features are appended, so a concatenation of collections works too.
The intent it closes: "my pipeline emits one feature per line and the map needs a collection." That is the output shape of a BigQuery export, a jq -c filter, a streaming API, or the GeoJSON to NDJSON tool on this site.
How this tool works
Line by line, tolerantly.
1. Clean each line
Leading ASCII record separators (0x1E, from RFC 8142 GeoJSON text sequences) are stripped and surrounding whitespace trimmed. Blank lines are skipped, so a file with a trailing newline or double-spaced records is fine.
2. Parse and classify
Each line is parsed as JSON, then classified: a Feature is taken as-is, a geometry type is wrapped in a feature, and a FeatureCollection contributes all of its features. A line that is valid JSON but not GeoJSON — a log record, say — is counted as skipped rather than becoming a broken feature.
3. Collect
Everything goes into one collection in input order. With skip unparseable lines on, a malformed line is counted and the rest still convert; with it off, the first bad line stops the run and names its line number — which is what you want when the file should be clean and you need to find the corruption.
Options
skip unparseable lines
On is forgiving: partial downloads, mixed log output and truncated final lines all still yield a usable collection, with a count of what was dropped. Off is strict: the run stops at the first bad line and tells you where it is.
Indent
Two or four spaces for reading and diffing, minified when the file is going straight into a request or an attribute.
Example
Input:
{"type":"Feature","properties":{"n":1},"geometry":{"type":"Point","coordinates":[0,0]}}
{"type":"Point","coordinates":[1,1]}
Output:
{
"type": "FeatureCollection",
"features": [
{ "type": "Feature", "properties": { "n": 1 }, "geometry": { "type": "Point", "coordinates": [0, 0] } },
{ "type": "Feature", "properties": {}, "geometry": { "type": "Point", "coordinates": [1, 1] } }
]
}
The second line was a bare geometry, so it was wrapped in a feature with empty properties — which keeps the collection uniform and renderable.
Tips & common pitfalls
- Mind the size. NDJSON is used precisely because files get large. A browser tab will handle tens of megabytes; past that, combine with a CLI (
jq -sorndjson-reduce) instead. - Check the skipped count. If the status line reports skipped lines on a file you expected to be clean, something upstream is emitting non-GeoJSON records — worth knowing before you use the result.
- No bbox is added. Compute one with the bbox tool if your consumer wants it.
- Verify before you map. The validator will catch coordinate-order and ring problems that a line-by-line combine cannot see.
FAQ
Does it handle RFC 8142 sequences?
Yes. A leading 0x1E record separator on each line is stripped before parsing, so application/geo+json-seq files work without preprocessing.
What if a line is a whole FeatureCollection?
Its features are appended to the output. That makes a concatenation of collections — a common result of merging exports — combine correctly.
Will properties be preserved?
Yes, exactly as they appear on each feature. Bare geometry lines get an empty properties object, because GeoJSON features require the member to be present.
Is my data uploaded?
No. Reading and combining both happen in your browser.