GeoJSON Merger
Combine two or more GeoJSON files into a single FeatureCollection. Tag features by source, deduplicate by geometry, and download in one click.
| Source | Features in | Added | Skipped (dedup) |
|---|---|---|---|
What This Tool Does
Combine any number of GeoJSON files into a single FeatureCollection with full control over deduplication and source tracking.
_source property on every feature with the name of
the slot it came from. Name slots anything — "Roads", "POIs", "Layer A" — and filter by that in your map.
How to Use
Logic Behind the Tool
How sources are parsed, combined, and optionally deduplicated.
JSON.parse(). The tool accepts a
FeatureCollection (uses .features array), a single Feature (wrapped
in an array), or a bare geometry object (wrapped in a Feature with empty properties). All three produce a
flat array of Feature objects before merging.JSON.parse(JSON.stringify(f)) to avoid mutating the originals. They are concatenated in slot
order into a single array. The output wraps the array in a FeatureCollection. No spatial
operation is performed — this is a simple feature concatenation, not a topological union.geometry object is serialised to a string
with JSON.stringify(geometry) and added to a Set. If the same string was seen
from an earlier source, the feature is skipped. This is exact string equality — coordinate order,
precision, and nesting must match exactly. Properties are not compared.feature.properties._source = slot.label is set on every
feature after deep-cloning. Existing _source properties from the input are overwritten. This
is intentional — the tag reflects where the feature came from in this merge operation, not any prior
source history.Frequently Asked Questions
It concatenates features — this is not a spatial union or intersection. Each feature from each source is added as-is into the output FeatureCollection. If you have two polygon layers representing different areas, the output will contain both polygons. If you want to compute the geometric union of two polygons (combine them into one shape), that is a spatial operation requiring a library like Turf.js or GDAL.
Use the style or pointToLayer option of L.geoJSON:
L.geoJSON(data, { style: f => f.properties._source === 'Roads' ? {color:'blue'} : {color:'red'} }).
In Mapbox GL JS, use a filter expression: ["==", ["get", "_source"], "Roads"] on a separate
layer for each source. In QGIS, add a categorised symbol renderer on the _source field.
Only if the features have identical geometry objects (same coordinates, same type, same precision). Enable "Deduplicate by geometry" to remove exact duplicates. If your files come from different sources with slightly different coordinate precision, deduplication will not catch them — the geometries must match string-for-string. For fuzzy spatial deduplication (within N metres), use Turf.js or QGIS.
Pretty-printed output uses 2-space indentation and newlines, making it readable in a text editor but larger in file size. Minified output strips all whitespace, reducing file size significantly — a 1MB pretty GeoJSON is typically 600–700KB minified. Use minified when serving the file from a web API or loading it in a browser map; use pretty when you want to inspect or version-control the file.