Sean Gillies (Posts about diff)
https://sgillies.net/tags/diff.atom
2023-12-31T01:26:23Z
Sean Gillies
Nikola
Some consequences of GeoJSON features as arrays
https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html
2013-12-06T00:00:00-07:00
2013-12-06T00:00:00-07:00
Sean Gillies
<p>Don't mind me, I'm just thinking out loud about the GeoJSON format.</p>
<p>A GeoJSON Feature Collection is an object with a "features" key and the value
for the key is specified to be an array of Feature objects. Is the order of
Features significant? In the context of my <a class="reference external" href="http://sgillies.net/blog/2013/12/04/json-diff-and-patch-for-geojson.html">previous post</a>,
should a zero or empty RFC 6902 diff between this</p>
<div class="code"><pre class="code javascript"><a id="rest_code_23f90d7361a5468995d9a90765d69528-1" name="rest_code_23f90d7361a5468995d9a90765d69528-1" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_23f90d7361a5468995d9a90765d69528-1"></a><span class="p">{</span><span class="w"> </span><span class="s2">"type"</span><span class="o">:</span><span class="w"> </span><span class="s2">"FeatureCollection"</span><span class="p">,</span><span class="w"></span>
<a id="rest_code_23f90d7361a5468995d9a90765d69528-2" name="rest_code_23f90d7361a5468995d9a90765d69528-2" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_23f90d7361a5468995d9a90765d69528-2"></a><span class="w"> </span><span class="s2">"features"</span><span class="o">:</span><span class="w"> </span><span class="p">[</span><span class="w"></span>
<a id="rest_code_23f90d7361a5468995d9a90765d69528-3" name="rest_code_23f90d7361a5468995d9a90765d69528-3" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_23f90d7361a5468995d9a90765d69528-3"></a><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"type"</span><span class="o">:</span><span class="w"> </span><span class="s2">"Feature"</span><span class="p">,</span><span class="w"></span>
<a id="rest_code_23f90d7361a5468995d9a90765d69528-4" name="rest_code_23f90d7361a5468995d9a90765d69528-4" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_23f90d7361a5468995d9a90765d69528-4"></a><span class="w"> </span><span class="s2">"id"</span><span class="o">:</span><span class="w"> </span><span class="s2">"foo"</span><span class="p">,</span><span class="w"></span>
<a id="rest_code_23f90d7361a5468995d9a90765d69528-5" name="rest_code_23f90d7361a5468995d9a90765d69528-5" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_23f90d7361a5468995d9a90765d69528-5"></a><span class="w"> </span><span class="p">...</span><span class="w"> </span><span class="p">},</span><span class="w"></span>
<a id="rest_code_23f90d7361a5468995d9a90765d69528-6" name="rest_code_23f90d7361a5468995d9a90765d69528-6" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_23f90d7361a5468995d9a90765d69528-6"></a><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"type"</span><span class="o">:</span><span class="w"> </span><span class="s2">"Feature"</span><span class="p">,</span><span class="w"></span>
<a id="rest_code_23f90d7361a5468995d9a90765d69528-7" name="rest_code_23f90d7361a5468995d9a90765d69528-7" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_23f90d7361a5468995d9a90765d69528-7"></a><span class="w"> </span><span class="s2">"id"</span><span class="o">:</span><span class="w"> </span><span class="s2">"bar"</span><span class="p">,</span><span class="w"></span>
<a id="rest_code_23f90d7361a5468995d9a90765d69528-8" name="rest_code_23f90d7361a5468995d9a90765d69528-8" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_23f90d7361a5468995d9a90765d69528-8"></a><span class="w"> </span><span class="p">...</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">]</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
</pre></div>
<p>and this, where the feature array has been reversed,</p>
<div class="code"><pre class="code javascript"><a id="rest_code_b8c6ad036f1045569e9cb6fed9478fb3-1" name="rest_code_b8c6ad036f1045569e9cb6fed9478fb3-1" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b8c6ad036f1045569e9cb6fed9478fb3-1"></a><span class="p">{</span><span class="w"> </span><span class="s2">"type"</span><span class="o">:</span><span class="w"> </span><span class="s2">"FeatureCollection"</span><span class="p">,</span><span class="w"></span>
<a id="rest_code_b8c6ad036f1045569e9cb6fed9478fb3-2" name="rest_code_b8c6ad036f1045569e9cb6fed9478fb3-2" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b8c6ad036f1045569e9cb6fed9478fb3-2"></a><span class="w"> </span><span class="s2">"features"</span><span class="o">:</span><span class="w"> </span><span class="p">[</span><span class="w"></span>
<a id="rest_code_b8c6ad036f1045569e9cb6fed9478fb3-3" name="rest_code_b8c6ad036f1045569e9cb6fed9478fb3-3" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b8c6ad036f1045569e9cb6fed9478fb3-3"></a><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"type"</span><span class="o">:</span><span class="w"> </span><span class="s2">"Feature"</span><span class="p">,</span><span class="w"></span>
<a id="rest_code_b8c6ad036f1045569e9cb6fed9478fb3-4" name="rest_code_b8c6ad036f1045569e9cb6fed9478fb3-4" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b8c6ad036f1045569e9cb6fed9478fb3-4"></a><span class="w"> </span><span class="s2">"id"</span><span class="o">:</span><span class="w"> </span><span class="s2">"bar"</span><span class="p">,</span><span class="w"></span>
<a id="rest_code_b8c6ad036f1045569e9cb6fed9478fb3-5" name="rest_code_b8c6ad036f1045569e9cb6fed9478fb3-5" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b8c6ad036f1045569e9cb6fed9478fb3-5"></a><span class="w"> </span><span class="p">...</span><span class="w"> </span><span class="p">},</span><span class="w"></span>
<a id="rest_code_b8c6ad036f1045569e9cb6fed9478fb3-6" name="rest_code_b8c6ad036f1045569e9cb6fed9478fb3-6" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b8c6ad036f1045569e9cb6fed9478fb3-6"></a><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"type"</span><span class="o">:</span><span class="w"> </span><span class="s2">"Feature"</span><span class="p">,</span><span class="w"></span>
<a id="rest_code_b8c6ad036f1045569e9cb6fed9478fb3-7" name="rest_code_b8c6ad036f1045569e9cb6fed9478fb3-7" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b8c6ad036f1045569e9cb6fed9478fb3-7"></a><span class="w"> </span><span class="s2">"id"</span><span class="o">:</span><span class="w"> </span><span class="s2">"foo"</span><span class="p">,</span><span class="w"></span>
<a id="rest_code_b8c6ad036f1045569e9cb6fed9478fb3-8" name="rest_code_b8c6ad036f1045569e9cb6fed9478fb3-8" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b8c6ad036f1045569e9cb6fed9478fb3-8"></a><span class="w"> </span><span class="p">...</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">]</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
</pre></div>
<p>be expected? Strictly speaking, no, because in JSON (see <a class="reference external" href="http://www.json.org">json.org</a> or <a class="reference external" href="http://www.ecma-international.org/publications/standards/Ecma-404.htm">ECMA 404</a>)</p>
<blockquote>
<p>An array is an ordered collection of values.</p>
</blockquote>
<p>whereas</p>
<blockquote>
<p>An object is an unordered set of name/value pairs.</p>
</blockquote>
<p>My question is related to <a class="reference external" href="http://www.ietf.org/mail-archive/web/apps-discuss/current/msg08749.html">one asked on the IETF's apps-discuss
list</a> in
January. Should we expect to be able to patch GeoJSON documents using the ids
of individual features? Being able to do so is more or less the reason why
GeoJSON Features have unique ids, but it's clear to me that a generic RFC 6902
won't do. As James Snell points out in that thread, more expressive paths will
be required.</p>
<p>In my previous post on this topic (see link at the top of this one) I looked at
the addition of a new feature to the tail of the features array. The JSON patch
in this case was very simple. But what if that feature had been inserted at the
head of the features array? Is the resulting patch going to be something that
reads like "push back existing items and add new item to the head?" The result
from python-json-patch isn't pretty.</p>
<div class="code"><pre class="code javascript"><a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-1" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-1" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-1"></a><span class="p">[</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-2" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-2" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-2"></a><span class="w"> </span><span class="p">{</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-3" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-3" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-3"></a><span class="w"> </span><span class="s2">"path"</span><span class="o">:</span><span class="w"> </span><span class="s2">"/features/0/geometry/coordinates/0"</span><span class="p">,</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-4" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-4" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-4"></a><span class="w"> </span><span class="s2">"value"</span><span class="o">:</span><span class="w"> </span><span class="o">-</span><span class="mf">122.65496134757996</span><span class="p">,</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-5" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-5" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-5"></a><span class="w"> </span><span class="s2">"op"</span><span class="o">:</span><span class="w"> </span><span class="s2">"replace"</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-6" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-6" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-6"></a><span class="w"> </span><span class="p">},</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-7" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-7" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-7"></a><span class="w"> </span><span class="p">{</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-8" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-8" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-8"></a><span class="w"> </span><span class="s2">"path"</span><span class="o">:</span><span class="w"> </span><span class="s2">"/features/0/geometry/coordinates/1"</span><span class="p">,</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-9" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-9" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-9"></a><span class="w"> </span><span class="s2">"value"</span><span class="o">:</span><span class="w"> </span><span class="mf">45.5212590460849</span><span class="p">,</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-10" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-10" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-10"></a><span class="w"> </span><span class="s2">"op"</span><span class="o">:</span><span class="w"> </span><span class="s2">"replace"</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-11" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-11" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-11"></a><span class="w"> </span><span class="p">},</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-12" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-12" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-12"></a><span class="w"> </span><span class="p">{</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-13" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-13" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-13"></a><span class="w"> </span><span class="s2">"path"</span><span class="o">:</span><span class="w"> </span><span class="s2">"/features/0/properties/Notes"</span><span class="p">,</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-14" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-14" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-14"></a><span class="w"> </span><span class="s2">"op"</span><span class="o">:</span><span class="w"> </span><span class="s2">"remove"</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-15" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-15" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-15"></a><span class="w"> </span><span class="p">},</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-16" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-16" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-16"></a><span class="w"> </span><span class="p">{</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-17" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-17" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-17"></a><span class="w"> </span><span class="s2">"path"</span><span class="o">:</span><span class="w"> </span><span class="s2">"/features/0/properties/Name"</span><span class="p">,</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-18" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-18" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-18"></a><span class="w"> </span><span class="s2">"value"</span><span class="o">:</span><span class="w"> </span><span class="s2">"Three Friends Coffeehouse"</span><span class="p">,</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-19" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-19" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-19"></a><span class="w"> </span><span class="s2">"op"</span><span class="o">:</span><span class="w"> </span><span class="s2">"replace"</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-20" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-20" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-20"></a><span class="w"> </span><span class="p">},</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-21" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-21" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-21"></a><span class="w"> </span><span class="p">{</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-22" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-22" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-22"></a><span class="w"> </span><span class="s2">"path"</span><span class="o">:</span><span class="w"> </span><span class="s2">"/features/0/properties/Address"</span><span class="p">,</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-23" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-23" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-23"></a><span class="w"> </span><span class="s2">"value"</span><span class="o">:</span><span class="w"> </span><span class="s2">"201 SE 12th Ave, Portland, OR 97214"</span><span class="p">,</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-24" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-24" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-24"></a><span class="w"> </span><span class="s2">"op"</span><span class="o">:</span><span class="w"> </span><span class="s2">"replace"</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-25" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-25" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-25"></a><span class="w"> </span><span class="p">},</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-26" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-26" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-26"></a><span class="w"> </span><span class="p">{</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-27" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-27" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-27"></a><span class="w"> </span><span class="s2">"path"</span><span class="o">:</span><span class="w"> </span><span class="s2">"/features/1/geometry/coordinates/0"</span><span class="p">,</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-28" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-28" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-28"></a><span class="w"> </span><span class="s2">"value"</span><span class="o">:</span><span class="w"> </span><span class="o">-</span><span class="mf">122.67516911029816</span><span class="p">,</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-29" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-29" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-29"></a><span class="w"> </span><span class="s2">"op"</span><span class="o">:</span><span class="w"> </span><span class="s2">"replace"</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-30" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-30" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-30"></a><span class="w"> </span><span class="p">},</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-31" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-31" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-31"></a><span class="w"> </span><span class="p">{</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-32" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-32" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-32"></a><span class="w"> </span><span class="s2">"path"</span><span class="o">:</span><span class="w"> </span><span class="s2">"/features/1/geometry/coordinates/1"</span><span class="p">,</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-33" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-33" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-33"></a><span class="w"> </span><span class="s2">"value"</span><span class="o">:</span><span class="w"> </span><span class="mf">45.55673233031101</span><span class="p">,</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-34" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-34" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-34"></a><span class="w"> </span><span class="s2">"op"</span><span class="o">:</span><span class="w"> </span><span class="s2">"replace"</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-35" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-35" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-35"></a><span class="w"> </span><span class="p">},</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-36" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-36" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-36"></a><span class="w"> </span><span class="p">{</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-37" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-37" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-37"></a><span class="w"> </span><span class="s2">"path"</span><span class="o">:</span><span class="w"> </span><span class="s2">"/features/1/properties/Notes"</span><span class="p">,</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-38" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-38" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-38"></a><span class="w"> </span><span class="s2">"value"</span><span class="o">:</span><span class="w"> </span><span class="s2">"usually busy, outlets on side wall only"</span><span class="p">,</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-39" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-39" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-39"></a><span class="w"> </span><span class="s2">"op"</span><span class="o">:</span><span class="w"> </span><span class="s2">"replace"</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-40" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-40" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-40"></a><span class="w"> </span><span class="p">},</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-41" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-41" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-41"></a><span class="w"> </span><span class="p">{</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-42" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-42" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-42"></a><span class="w"> </span><span class="s2">"path"</span><span class="o">:</span><span class="w"> </span><span class="s2">"/features/1/properties/Name"</span><span class="p">,</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-43" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-43" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-43"></a><span class="w"> </span><span class="s2">"value"</span><span class="o">:</span><span class="w"> </span><span class="s2">"Albina Press"</span><span class="p">,</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-44" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-44" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-44"></a><span class="w"> </span><span class="s2">"op"</span><span class="o">:</span><span class="w"> </span><span class="s2">"replace"</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-45" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-45" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-45"></a><span class="w"> </span><span class="p">},</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-46" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-46" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-46"></a><span class="w"> </span><span class="p">{</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-47" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-47" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-47"></a><span class="w"> </span><span class="s2">"path"</span><span class="o">:</span><span class="w"> </span><span class="s2">"/features/1/properties/Address"</span><span class="p">,</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-48" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-48" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-48"></a><span class="w"> </span><span class="s2">"value"</span><span class="o">:</span><span class="w"> </span><span class="s2">"4637 N Albina Ave Portland, OR 97217"</span><span class="p">,</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-49" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-49" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-49"></a><span class="w"> </span><span class="s2">"op"</span><span class="o">:</span><span class="w"> </span><span class="s2">"replace"</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-50" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-50" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-50"></a><span class="w"> </span><span class="p">},</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-51" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-51" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-51"></a><span class="w"> </span><span class="p">{</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-52" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-52" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-52"></a><span class="w"> </span><span class="s2">"path"</span><span class="o">:</span><span class="w"> </span><span class="s2">"/features/2"</span><span class="p">,</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-53" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-53" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-53"></a><span class="w"> </span><span class="s2">"value"</span><span class="o">:</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-54" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-54" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-54"></a><span class="w"> </span><span class="s2">"geometry"</span><span class="o">:</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-55" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-55" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-55"></a><span class="w"> </span><span class="s2">"type"</span><span class="o">:</span><span class="w"> </span><span class="s2">"Point"</span><span class="p">,</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-56" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-56" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-56"></a><span class="w"> </span><span class="s2">"coordinates"</span><span class="o">:</span><span class="w"> </span><span class="p">[</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-57" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-57" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-57"></a><span class="w"> </span><span class="o">-</span><span class="mf">122.68242716789246</span><span class="p">,</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-58" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-58" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-58"></a><span class="w"> </span><span class="mf">45.56997505986905</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-59" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-59" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-59"></a><span class="w"> </span><span class="p">]</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-60" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-60" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-60"></a><span class="w"> </span><span class="p">},</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-61" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-61" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-61"></a><span class="w"> </span><span class="s2">"type"</span><span class="o">:</span><span class="w"> </span><span class="s2">"Feature"</span><span class="p">,</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-62" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-62" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-62"></a><span class="w"> </span><span class="s2">"properties"</span><span class="o">:</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-63" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-63" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-63"></a><span class="w"> </span><span class="s2">"Notes"</span><span class="o">:</span><span class="w"> </span><span class="s2">""</span><span class="p">,</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-64" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-64" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-64"></a><span class="w"> </span><span class="s2">"Name"</span><span class="o">:</span><span class="w"> </span><span class="s2">"Arbor Lodge"</span><span class="p">,</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-65" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-65" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-65"></a><span class="w"> </span><span class="s2">"Address"</span><span class="o">:</span><span class="w"> </span><span class="s2">"1507 N Rosa Parks Way Portland, OR 97217"</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-66" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-66" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-66"></a><span class="w"> </span><span class="p">}</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-67" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-67" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-67"></a><span class="w"> </span><span class="p">},</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-68" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-68" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-68"></a><span class="w"> </span><span class="s2">"op"</span><span class="o">:</span><span class="w"> </span><span class="s2">"add"</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-69" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-69" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-69"></a><span class="w"> </span><span class="p">}</span><span class="w"></span>
<a id="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-70" name="rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-70" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_b2f2ef2f978e420a896b9d786d3a5e7f-70"></a><span class="p">]</span><span class="w"></span>
</pre></div>
<p>Unless I misunderstand RFC 6901 and RFC 6902, the following ought to be
possible.</p>
<div class="code"><pre class="code javascript"><a id="rest_code_99f85a7e6fe446b289cd84b5fa01470c-1" name="rest_code_99f85a7e6fe446b289cd84b5fa01470c-1" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_99f85a7e6fe446b289cd84b5fa01470c-1"></a><span class="p">[</span><span class="w"></span>
<a id="rest_code_99f85a7e6fe446b289cd84b5fa01470c-2" name="rest_code_99f85a7e6fe446b289cd84b5fa01470c-2" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_99f85a7e6fe446b289cd84b5fa01470c-2"></a><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"op"</span><span class="o">:</span><span class="w"> </span><span class="s2">"move"</span><span class="p">,</span><span class="w"> </span><span class="s2">"from"</span><span class="o">:</span><span class="w"> </span><span class="s2">"/foo/1"</span><span class="p">,</span><span class="w"> </span><span class="s2">"path"</span><span class="o">:</span><span class="w"> </span><span class="s2">"/foo/2"</span><span class="w"> </span><span class="p">},</span><span class="w"></span>
<a id="rest_code_99f85a7e6fe446b289cd84b5fa01470c-3" name="rest_code_99f85a7e6fe446b289cd84b5fa01470c-3" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_99f85a7e6fe446b289cd84b5fa01470c-3"></a><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"op"</span><span class="o">:</span><span class="w"> </span><span class="s2">"move"</span><span class="p">,</span><span class="w"> </span><span class="s2">"from"</span><span class="o">:</span><span class="w"> </span><span class="s2">"/foo/0"</span><span class="p">,</span><span class="w"> </span><span class="s2">"path"</span><span class="o">:</span><span class="w"> </span><span class="s2">"/foo/1"</span><span class="w"> </span><span class="p">},</span><span class="w"></span>
<a id="rest_code_99f85a7e6fe446b289cd84b5fa01470c-4" name="rest_code_99f85a7e6fe446b289cd84b5fa01470c-4" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_99f85a7e6fe446b289cd84b5fa01470c-4"></a><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"path"</span><span class="o">:</span><span class="w"> </span><span class="s2">"/features/0`"</span><span class="p">,</span><span class="w"></span>
<a id="rest_code_99f85a7e6fe446b289cd84b5fa01470c-5" name="rest_code_99f85a7e6fe446b289cd84b5fa01470c-5" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_99f85a7e6fe446b289cd84b5fa01470c-5"></a><span class="w"> </span><span class="s2">"value"</span><span class="o">:</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<a id="rest_code_99f85a7e6fe446b289cd84b5fa01470c-6" name="rest_code_99f85a7e6fe446b289cd84b5fa01470c-6" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_99f85a7e6fe446b289cd84b5fa01470c-6"></a><span class="w"> </span><span class="s2">"geometry"</span><span class="o">:</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<a id="rest_code_99f85a7e6fe446b289cd84b5fa01470c-7" name="rest_code_99f85a7e6fe446b289cd84b5fa01470c-7" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_99f85a7e6fe446b289cd84b5fa01470c-7"></a><span class="w"> </span><span class="s2">"type"</span><span class="o">:</span><span class="w"> </span><span class="s2">"Point"</span><span class="p">,</span><span class="w"></span>
<a id="rest_code_99f85a7e6fe446b289cd84b5fa01470c-8" name="rest_code_99f85a7e6fe446b289cd84b5fa01470c-8" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_99f85a7e6fe446b289cd84b5fa01470c-8"></a><span class="w"> </span><span class="s2">"coordinates"</span><span class="o">:</span><span class="w"> </span><span class="p">[</span><span class="w"></span>
<a id="rest_code_99f85a7e6fe446b289cd84b5fa01470c-9" name="rest_code_99f85a7e6fe446b289cd84b5fa01470c-9" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_99f85a7e6fe446b289cd84b5fa01470c-9"></a><span class="w"> </span><span class="o">-</span><span class="mf">122.65496134757996</span><span class="p">,</span><span class="w"></span>
<a id="rest_code_99f85a7e6fe446b289cd84b5fa01470c-10" name="rest_code_99f85a7e6fe446b289cd84b5fa01470c-10" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_99f85a7e6fe446b289cd84b5fa01470c-10"></a><span class="w"> </span><span class="mf">45.5212590460849</span><span class="w"></span>
<a id="rest_code_99f85a7e6fe446b289cd84b5fa01470c-11" name="rest_code_99f85a7e6fe446b289cd84b5fa01470c-11" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_99f85a7e6fe446b289cd84b5fa01470c-11"></a><span class="w"> </span><span class="p">]</span><span class="w"></span>
<a id="rest_code_99f85a7e6fe446b289cd84b5fa01470c-12" name="rest_code_99f85a7e6fe446b289cd84b5fa01470c-12" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_99f85a7e6fe446b289cd84b5fa01470c-12"></a><span class="w"> </span><span class="p">},</span><span class="w"></span>
<a id="rest_code_99f85a7e6fe446b289cd84b5fa01470c-13" name="rest_code_99f85a7e6fe446b289cd84b5fa01470c-13" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_99f85a7e6fe446b289cd84b5fa01470c-13"></a><span class="w"> </span><span class="s2">"type"</span><span class="o">:</span><span class="w"> </span><span class="s2">"Feature"</span><span class="p">,</span><span class="w"></span>
<a id="rest_code_99f85a7e6fe446b289cd84b5fa01470c-14" name="rest_code_99f85a7e6fe446b289cd84b5fa01470c-14" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_99f85a7e6fe446b289cd84b5fa01470c-14"></a><span class="w"> </span><span class="s2">"properties"</span><span class="o">:</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<a id="rest_code_99f85a7e6fe446b289cd84b5fa01470c-15" name="rest_code_99f85a7e6fe446b289cd84b5fa01470c-15" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_99f85a7e6fe446b289cd84b5fa01470c-15"></a><span class="w"> </span><span class="s2">"Name"</span><span class="o">:</span><span class="w"> </span><span class="s2">"Three Friends Coffeehouse"</span><span class="p">,</span><span class="w"></span>
<a id="rest_code_99f85a7e6fe446b289cd84b5fa01470c-16" name="rest_code_99f85a7e6fe446b289cd84b5fa01470c-16" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_99f85a7e6fe446b289cd84b5fa01470c-16"></a><span class="w"> </span><span class="s2">"Address"</span><span class="o">:</span><span class="w"> </span><span class="s2">"201 SE 12th Ave, Portland, OR 97214"</span><span class="w"></span>
<a id="rest_code_99f85a7e6fe446b289cd84b5fa01470c-17" name="rest_code_99f85a7e6fe446b289cd84b5fa01470c-17" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_99f85a7e6fe446b289cd84b5fa01470c-17"></a><span class="w"> </span><span class="p">}</span><span class="w"></span>
<a id="rest_code_99f85a7e6fe446b289cd84b5fa01470c-18" name="rest_code_99f85a7e6fe446b289cd84b5fa01470c-18" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_99f85a7e6fe446b289cd84b5fa01470c-18"></a><span class="w"> </span><span class="p">},</span><span class="w"></span>
<a id="rest_code_99f85a7e6fe446b289cd84b5fa01470c-19" name="rest_code_99f85a7e6fe446b289cd84b5fa01470c-19" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_99f85a7e6fe446b289cd84b5fa01470c-19"></a><span class="w"> </span><span class="s2">"op"</span><span class="o">:</span><span class="w"> </span><span class="s2">"add"</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
<a id="rest_code_99f85a7e6fe446b289cd84b5fa01470c-20" name="rest_code_99f85a7e6fe446b289cd84b5fa01470c-20" href="https://sgillies.net/2013/12/06/some-consequences-of-geojson-features-as-arrays.html#rest_code_99f85a7e6fe446b289cd84b5fa01470c-20"></a><span class="p">]</span><span class="w"></span>
</pre></div>
<p>Making concise patches won't be trivial, that seems clear, and the ideal patch
style for GeoJSON could differ from the ideal style for other applications.
I'm certain that we'd need to get to patches like the latter to make GeoJSON
patching something that developers would consider adopting. JSON PATCH provides
a useful grammar but by itself isn't enough. There's more work to be done.</p>
<p>Did we ever consider making FeatureCollection's features key have an object
value? I'll look in the GeoJSON list archive when I have time.</p>
JSON diff and patch for GeoJSON
https://sgillies.net/2013/12/04/json-diff-and-patch-for-geojson.html
2013-12-04T00:00:00-07:00
2013-12-04T00:00:00-07:00
Sean Gillies
<p>We diff and patch source code all the time, but doing the same thing for JSON
data isn't as straightforward. More often than seeing the differences between JSON texts, we're interested in seeing (and sharing
and reapplying) the differences between the objects encoded in the text. We
want to gloss over differences in whitespace and order of object members and
see the real difference in the data. Unix patch and diff operate only on text,
and best on text of consistent and short line length, and aren't very useful
for parsing out differences between objects encoded in JSON. If diff and patch
aren't going to work, what will?</p>
<p>RFC 6902, <a class="reference external" href="http://tools.ietf.org/html/rfc6902">JavaScript Object Notation (JSON) Patch</a> is one attempt at standardizing JSON
patches. From the introduction:</p>
<blockquote>
<p>JavaScript Object Notation (JSON) [<a class="reference external" href="http://tools.ietf.org/html/rfc4627">RFC4627</a>] is a common format for
the exchange and storage of structured data. HTTP PATCH [<a class="reference external" href="http://tools.ietf.org/html/rfc5789">RFC5789</a>]
extends the Hypertext Transfer Protocol (HTTP) [<a class="reference external" href="http://tools.ietf.org/html/rfc2616">RFC2616</a>] with a
method to perform partial modifications to resources.</p>
<p>JSON Patch is a format (identified by the media type "application/
json-patch+json") for expressing a sequence of operations to apply to
a target JSON document; it is suitable for use with the HTTP PATCH
method.</p>
<p>This format is also potentially useful in other cases in which it is
necessary to make partial updates to a JSON document or to a data
structure that has similar constraints (i.e., they can be serialized
as an object or an array using the JSON grammar).</p>
</blockquote>
<p>RFC 6902 comes from developers interested in REST-style interaction with
JSON representations of resources but might be more generally useful. How does
it work? If you're familiar with XPath and XPointer, you might see some
similarities. A JSON patch doc contains an array of path, value, and operation
tuples. The path tells you how to traverse into the JSON document and the
operations specify what is done to objects using the values.</p>
<p>For an example, I'm going to take GeoJSON from Lyzi Diamond's <a class="reference external" href="https://github.com/lyzidiamond/learn-geojson">Learn GeoJSON</a> project and make diffs using
Stefan Kögl's <a class="reference external" href="https://github.com/stefankoegl/python-json-patch">python-json-patch</a> package. RFC 6902 has
implementations in other languages, too, such as <a class="reference external" href="https://github.com/bruth/jsonpatch-js">jsonpatch-js</a> (npm).</p>
<p>Here's a <a class="reference external" href="https://gist.github.com/sgillies/7797688#file-json-diff-py">script</a> that prints out the RFC 6902 diff between commits <a class="reference external" href="https://github.com/lyzidiamond/learn-geojson/blob/44de76ef53b20bdaf51e0cde4aa634df210cd9d4/geojson/hackspots.geojson">44de76ef53</a>
and <a class="reference external" href="https://github.com/lyzidiamond/learn-geojson/blob/e9514f5c317ee980b94ed6580950cfd9fbde53db/geojson/hackspots.geojson">e9514f5c31</a>
of <a class="reference external" href="https://github.com/lyzidiamond/learn-geojson/blob/master/geojson/hackspots.geojson">hackspots.geojson</a>:</p>
<div class="code"><pre class="code python"><a id="rest_code_82d3a6bb16844e1d96947632f48c611f-1" name="rest_code_82d3a6bb16844e1d96947632f48c611f-1" href="https://sgillies.net/2013/12/04/json-diff-and-patch-for-geojson.html#rest_code_82d3a6bb16844e1d96947632f48c611f-1"></a><span class="kn">import</span> <span class="nn">json</span>
<a id="rest_code_82d3a6bb16844e1d96947632f48c611f-2" name="rest_code_82d3a6bb16844e1d96947632f48c611f-2" href="https://sgillies.net/2013/12/04/json-diff-and-patch-for-geojson.html#rest_code_82d3a6bb16844e1d96947632f48c611f-2"></a><span class="kn">import</span> <span class="nn">jsonpatch</span>
<a id="rest_code_82d3a6bb16844e1d96947632f48c611f-3" name="rest_code_82d3a6bb16844e1d96947632f48c611f-3" href="https://sgillies.net/2013/12/04/json-diff-and-patch-for-geojson.html#rest_code_82d3a6bb16844e1d96947632f48c611f-3"></a><span class="kn">import</span> <span class="nn">os.path</span>
<a id="rest_code_82d3a6bb16844e1d96947632f48c611f-4" name="rest_code_82d3a6bb16844e1d96947632f48c611f-4" href="https://sgillies.net/2013/12/04/json-diff-and-patch-for-geojson.html#rest_code_82d3a6bb16844e1d96947632f48c611f-4"></a><span class="kn">import</span> <span class="nn">requests</span>
<a id="rest_code_82d3a6bb16844e1d96947632f48c611f-5" name="rest_code_82d3a6bb16844e1d96947632f48c611f-5" href="https://sgillies.net/2013/12/04/json-diff-and-patch-for-geojson.html#rest_code_82d3a6bb16844e1d96947632f48c611f-5"></a><span class="kn">import</span> <span class="nn">subprocess</span>
<a id="rest_code_82d3a6bb16844e1d96947632f48c611f-6" name="rest_code_82d3a6bb16844e1d96947632f48c611f-6" href="https://sgillies.net/2013/12/04/json-diff-and-patch-for-geojson.html#rest_code_82d3a6bb16844e1d96947632f48c611f-6"></a>
<a id="rest_code_82d3a6bb16844e1d96947632f48c611f-7" name="rest_code_82d3a6bb16844e1d96947632f48c611f-7" href="https://sgillies.net/2013/12/04/json-diff-and-patch-for-geojson.html#rest_code_82d3a6bb16844e1d96947632f48c611f-7"></a><span class="c1"># original</span>
<a id="rest_code_82d3a6bb16844e1d96947632f48c611f-8" name="rest_code_82d3a6bb16844e1d96947632f48c611f-8" href="https://sgillies.net/2013/12/04/json-diff-and-patch-for-geojson.html#rest_code_82d3a6bb16844e1d96947632f48c611f-8"></a><span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="s1">'hackspots-44de76ef53.json'</span><span class="p">):</span>
<a id="rest_code_82d3a6bb16844e1d96947632f48c611f-9" name="rest_code_82d3a6bb16844e1d96947632f48c611f-9" href="https://sgillies.net/2013/12/04/json-diff-and-patch-for-geojson.html#rest_code_82d3a6bb16844e1d96947632f48c611f-9"></a> <span class="n">r</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">'https://github.com/lyzidiamond/learn-geojson/raw/44de76ef53b20bdaf51e0cde4aa634df210cd9d4/geojson/hackspots.geojson'</span><span class="p">)</span>
<a id="rest_code_82d3a6bb16844e1d96947632f48c611f-10" name="rest_code_82d3a6bb16844e1d96947632f48c611f-10" href="https://sgillies.net/2013/12/04/json-diff-and-patch-for-geojson.html#rest_code_82d3a6bb16844e1d96947632f48c611f-10"></a> <span class="n">data</span> <span class="o">=</span> <span class="n">r</span><span class="o">.</span><span class="n">content</span>
<a id="rest_code_82d3a6bb16844e1d96947632f48c611f-11" name="rest_code_82d3a6bb16844e1d96947632f48c611f-11" href="https://sgillies.net/2013/12/04/json-diff-and-patch-for-geojson.html#rest_code_82d3a6bb16844e1d96947632f48c611f-11"></a> <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s1">'hackspots-44de76ef53.json'</span><span class="p">,</span> <span class="s1">'wb'</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
<a id="rest_code_82d3a6bb16844e1d96947632f48c611f-12" name="rest_code_82d3a6bb16844e1d96947632f48c611f-12" href="https://sgillies.net/2013/12/04/json-diff-and-patch-for-geojson.html#rest_code_82d3a6bb16844e1d96947632f48c611f-12"></a> <span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
<a id="rest_code_82d3a6bb16844e1d96947632f48c611f-13" name="rest_code_82d3a6bb16844e1d96947632f48c611f-13" href="https://sgillies.net/2013/12/04/json-diff-and-patch-for-geojson.html#rest_code_82d3a6bb16844e1d96947632f48c611f-13"></a>
<a id="rest_code_82d3a6bb16844e1d96947632f48c611f-14" name="rest_code_82d3a6bb16844e1d96947632f48c611f-14" href="https://sgillies.net/2013/12/04/json-diff-and-patch-for-geojson.html#rest_code_82d3a6bb16844e1d96947632f48c611f-14"></a><span class="c1"># next commit</span>
<a id="rest_code_82d3a6bb16844e1d96947632f48c611f-15" name="rest_code_82d3a6bb16844e1d96947632f48c611f-15" href="https://sgillies.net/2013/12/04/json-diff-and-patch-for-geojson.html#rest_code_82d3a6bb16844e1d96947632f48c611f-15"></a><span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="s1">'hackspots-e9514f5c31.json'</span><span class="p">):</span>
<a id="rest_code_82d3a6bb16844e1d96947632f48c611f-16" name="rest_code_82d3a6bb16844e1d96947632f48c611f-16" href="https://sgillies.net/2013/12/04/json-diff-and-patch-for-geojson.html#rest_code_82d3a6bb16844e1d96947632f48c611f-16"></a> <span class="n">r</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">'https://github.com/lyzidiamond/learn-geojson/raw/e9514f5c317ee980b94ed6580950cfd9fbde53db/geojson/hackspots.geojson'</span><span class="p">)</span>
<a id="rest_code_82d3a6bb16844e1d96947632f48c611f-17" name="rest_code_82d3a6bb16844e1d96947632f48c611f-17" href="https://sgillies.net/2013/12/04/json-diff-and-patch-for-geojson.html#rest_code_82d3a6bb16844e1d96947632f48c611f-17"></a> <span class="n">data</span> <span class="o">=</span> <span class="n">r</span><span class="o">.</span><span class="n">content</span>
<a id="rest_code_82d3a6bb16844e1d96947632f48c611f-18" name="rest_code_82d3a6bb16844e1d96947632f48c611f-18" href="https://sgillies.net/2013/12/04/json-diff-and-patch-for-geojson.html#rest_code_82d3a6bb16844e1d96947632f48c611f-18"></a> <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s1">'hackspots-e9514f5c31.json'</span><span class="p">,</span> <span class="s1">'wb'</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
<a id="rest_code_82d3a6bb16844e1d96947632f48c611f-19" name="rest_code_82d3a6bb16844e1d96947632f48c611f-19" href="https://sgillies.net/2013/12/04/json-diff-and-patch-for-geojson.html#rest_code_82d3a6bb16844e1d96947632f48c611f-19"></a> <span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
<a id="rest_code_82d3a6bb16844e1d96947632f48c611f-20" name="rest_code_82d3a6bb16844e1d96947632f48c611f-20" href="https://sgillies.net/2013/12/04/json-diff-and-patch-for-geojson.html#rest_code_82d3a6bb16844e1d96947632f48c611f-20"></a>
<a id="rest_code_82d3a6bb16844e1d96947632f48c611f-21" name="rest_code_82d3a6bb16844e1d96947632f48c611f-21" href="https://sgillies.net/2013/12/04/json-diff-and-patch-for-geojson.html#rest_code_82d3a6bb16844e1d96947632f48c611f-21"></a><span class="n">diff_text</span> <span class="o">=</span> <span class="n">subprocess</span><span class="o">.</span><span class="n">check_output</span><span class="p">([</span>
<a id="rest_code_82d3a6bb16844e1d96947632f48c611f-22" name="rest_code_82d3a6bb16844e1d96947632f48c611f-22" href="https://sgillies.net/2013/12/04/json-diff-and-patch-for-geojson.html#rest_code_82d3a6bb16844e1d96947632f48c611f-22"></a> <span class="s1">'jsondiff'</span><span class="p">,</span>
<a id="rest_code_82d3a6bb16844e1d96947632f48c611f-23" name="rest_code_82d3a6bb16844e1d96947632f48c611f-23" href="https://sgillies.net/2013/12/04/json-diff-and-patch-for-geojson.html#rest_code_82d3a6bb16844e1d96947632f48c611f-23"></a> <span class="s1">'hackspots-44de76ef53.json'</span><span class="p">,</span>
<a id="rest_code_82d3a6bb16844e1d96947632f48c611f-24" name="rest_code_82d3a6bb16844e1d96947632f48c611f-24" href="https://sgillies.net/2013/12/04/json-diff-and-patch-for-geojson.html#rest_code_82d3a6bb16844e1d96947632f48c611f-24"></a> <span class="s1">'hackspots-e9514f5c31.json'</span><span class="p">])</span>
<a id="rest_code_82d3a6bb16844e1d96947632f48c611f-25" name="rest_code_82d3a6bb16844e1d96947632f48c611f-25" href="https://sgillies.net/2013/12/04/json-diff-and-patch-for-geojson.html#rest_code_82d3a6bb16844e1d96947632f48c611f-25"></a><span class="n">diff</span> <span class="o">=</span> <span class="n">json</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="n">diff_text</span><span class="p">)</span>
<a id="rest_code_82d3a6bb16844e1d96947632f48c611f-26" name="rest_code_82d3a6bb16844e1d96947632f48c611f-26" href="https://sgillies.net/2013/12/04/json-diff-and-patch-for-geojson.html#rest_code_82d3a6bb16844e1d96947632f48c611f-26"></a><span class="nb">print</span><span class="p">(</span><span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="n">diff</span><span class="p">,</span> <span class="n">indent</span><span class="o">=</span><span class="mi">2</span><span class="p">))</span>
</pre></div>
<p>The result looks, to me, like a very reasonable representation of an operation
that adds one feature to a GeoJSON feature collection.</p>
<div class="code"><pre class="code javascript"><a id="rest_code_5869397c285c43c594898ad326a225f0-1" name="rest_code_5869397c285c43c594898ad326a225f0-1" href="https://sgillies.net/2013/12/04/json-diff-and-patch-for-geojson.html#rest_code_5869397c285c43c594898ad326a225f0-1"></a><span class="p">[</span><span class="w"></span>
<a id="rest_code_5869397c285c43c594898ad326a225f0-2" name="rest_code_5869397c285c43c594898ad326a225f0-2" href="https://sgillies.net/2013/12/04/json-diff-and-patch-for-geojson.html#rest_code_5869397c285c43c594898ad326a225f0-2"></a><span class="w"> </span><span class="p">{</span><span class="w"></span>
<a id="rest_code_5869397c285c43c594898ad326a225f0-3" name="rest_code_5869397c285c43c594898ad326a225f0-3" href="https://sgillies.net/2013/12/04/json-diff-and-patch-for-geojson.html#rest_code_5869397c285c43c594898ad326a225f0-3"></a><span class="w"> </span><span class="s2">"path"</span><span class="o">:</span><span class="w"> </span><span class="s2">"/features/2"</span><span class="p">,</span><span class="w"></span>
<a id="rest_code_5869397c285c43c594898ad326a225f0-4" name="rest_code_5869397c285c43c594898ad326a225f0-4" href="https://sgillies.net/2013/12/04/json-diff-and-patch-for-geojson.html#rest_code_5869397c285c43c594898ad326a225f0-4"></a><span class="w"> </span><span class="s2">"value"</span><span class="o">:</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<a id="rest_code_5869397c285c43c594898ad326a225f0-5" name="rest_code_5869397c285c43c594898ad326a225f0-5" href="https://sgillies.net/2013/12/04/json-diff-and-patch-for-geojson.html#rest_code_5869397c285c43c594898ad326a225f0-5"></a><span class="w"> </span><span class="s2">"geometry"</span><span class="o">:</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<a id="rest_code_5869397c285c43c594898ad326a225f0-6" name="rest_code_5869397c285c43c594898ad326a225f0-6" href="https://sgillies.net/2013/12/04/json-diff-and-patch-for-geojson.html#rest_code_5869397c285c43c594898ad326a225f0-6"></a><span class="w"> </span><span class="s2">"type"</span><span class="o">:</span><span class="w"> </span><span class="s2">"Point"</span><span class="p">,</span><span class="w"></span>
<a id="rest_code_5869397c285c43c594898ad326a225f0-7" name="rest_code_5869397c285c43c594898ad326a225f0-7" href="https://sgillies.net/2013/12/04/json-diff-and-patch-for-geojson.html#rest_code_5869397c285c43c594898ad326a225f0-7"></a><span class="w"> </span><span class="s2">"coordinates"</span><span class="o">:</span><span class="w"> </span><span class="p">[</span><span class="w"></span>
<a id="rest_code_5869397c285c43c594898ad326a225f0-8" name="rest_code_5869397c285c43c594898ad326a225f0-8" href="https://sgillies.net/2013/12/04/json-diff-and-patch-for-geojson.html#rest_code_5869397c285c43c594898ad326a225f0-8"></a><span class="w"> </span><span class="o">-</span><span class="mf">122.65496134757996</span><span class="p">,</span><span class="w"></span>
<a id="rest_code_5869397c285c43c594898ad326a225f0-9" name="rest_code_5869397c285c43c594898ad326a225f0-9" href="https://sgillies.net/2013/12/04/json-diff-and-patch-for-geojson.html#rest_code_5869397c285c43c594898ad326a225f0-9"></a><span class="w"> </span><span class="mf">45.5212590460849</span><span class="w"></span>
<a id="rest_code_5869397c285c43c594898ad326a225f0-10" name="rest_code_5869397c285c43c594898ad326a225f0-10" href="https://sgillies.net/2013/12/04/json-diff-and-patch-for-geojson.html#rest_code_5869397c285c43c594898ad326a225f0-10"></a><span class="w"> </span><span class="p">]</span><span class="w"></span>
<a id="rest_code_5869397c285c43c594898ad326a225f0-11" name="rest_code_5869397c285c43c594898ad326a225f0-11" href="https://sgillies.net/2013/12/04/json-diff-and-patch-for-geojson.html#rest_code_5869397c285c43c594898ad326a225f0-11"></a><span class="w"> </span><span class="p">},</span><span class="w"></span>
<a id="rest_code_5869397c285c43c594898ad326a225f0-12" name="rest_code_5869397c285c43c594898ad326a225f0-12" href="https://sgillies.net/2013/12/04/json-diff-and-patch-for-geojson.html#rest_code_5869397c285c43c594898ad326a225f0-12"></a><span class="w"> </span><span class="s2">"type"</span><span class="o">:</span><span class="w"> </span><span class="s2">"Feature"</span><span class="p">,</span><span class="w"></span>
<a id="rest_code_5869397c285c43c594898ad326a225f0-13" name="rest_code_5869397c285c43c594898ad326a225f0-13" href="https://sgillies.net/2013/12/04/json-diff-and-patch-for-geojson.html#rest_code_5869397c285c43c594898ad326a225f0-13"></a><span class="w"> </span><span class="s2">"properties"</span><span class="o">:</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<a id="rest_code_5869397c285c43c594898ad326a225f0-14" name="rest_code_5869397c285c43c594898ad326a225f0-14" href="https://sgillies.net/2013/12/04/json-diff-and-patch-for-geojson.html#rest_code_5869397c285c43c594898ad326a225f0-14"></a><span class="w"> </span><span class="s2">"Name"</span><span class="o">:</span><span class="w"> </span><span class="s2">"Three Friends Coffeehouse"</span><span class="p">,</span><span class="w"></span>
<a id="rest_code_5869397c285c43c594898ad326a225f0-15" name="rest_code_5869397c285c43c594898ad326a225f0-15" href="https://sgillies.net/2013/12/04/json-diff-and-patch-for-geojson.html#rest_code_5869397c285c43c594898ad326a225f0-15"></a><span class="w"> </span><span class="s2">"Address"</span><span class="o">:</span><span class="w"> </span><span class="s2">"201 SE 12th Ave, Portland, OR 97214"</span><span class="w"></span>
<a id="rest_code_5869397c285c43c594898ad326a225f0-16" name="rest_code_5869397c285c43c594898ad326a225f0-16" href="https://sgillies.net/2013/12/04/json-diff-and-patch-for-geojson.html#rest_code_5869397c285c43c594898ad326a225f0-16"></a><span class="w"> </span><span class="p">}</span><span class="w"></span>
<a id="rest_code_5869397c285c43c594898ad326a225f0-17" name="rest_code_5869397c285c43c594898ad326a225f0-17" href="https://sgillies.net/2013/12/04/json-diff-and-patch-for-geojson.html#rest_code_5869397c285c43c594898ad326a225f0-17"></a><span class="w"> </span><span class="p">},</span><span class="w"></span>
<a id="rest_code_5869397c285c43c594898ad326a225f0-18" name="rest_code_5869397c285c43c594898ad326a225f0-18" href="https://sgillies.net/2013/12/04/json-diff-and-patch-for-geojson.html#rest_code_5869397c285c43c594898ad326a225f0-18"></a><span class="w"> </span><span class="s2">"op"</span><span class="o">:</span><span class="w"> </span><span class="s2">"add"</span><span class="w"></span>
<a id="rest_code_5869397c285c43c594898ad326a225f0-19" name="rest_code_5869397c285c43c594898ad326a225f0-19" href="https://sgillies.net/2013/12/04/json-diff-and-patch-for-geojson.html#rest_code_5869397c285c43c594898ad326a225f0-19"></a><span class="w"> </span><span class="p">}</span><span class="w"></span>
<a id="rest_code_5869397c285c43c594898ad326a225f0-20" name="rest_code_5869397c285c43c594898ad326a225f0-20" href="https://sgillies.net/2013/12/04/json-diff-and-patch-for-geojson.html#rest_code_5869397c285c43c594898ad326a225f0-20"></a><span class="p">]</span><span class="w"></span>
</pre></div>
<p>A hypothetical change of this same feature's coordinates from <a class="reference external" href="https://github.com/lyzidiamond/learn-geojson/blob/e9514f5c317ee980b94ed6580950cfd9fbde53db/geojson/hackspots.geojson">e9514f5c31</a>
to <a class="reference external" href="https://gist.github.com/sgillies/7797688#file-foo-geojson">https://gist.github.com/sgillies/7797688#file-foo-geojson</a> looks like this:</p>
<div class="code"><pre class="code javascript"><a id="rest_code_19e83f84d84340ebbc65a8efb0212946-1" name="rest_code_19e83f84d84340ebbc65a8efb0212946-1" href="https://sgillies.net/2013/12/04/json-diff-and-patch-for-geojson.html#rest_code_19e83f84d84340ebbc65a8efb0212946-1"></a><span class="p">[</span><span class="w"></span>
<a id="rest_code_19e83f84d84340ebbc65a8efb0212946-2" name="rest_code_19e83f84d84340ebbc65a8efb0212946-2" href="https://sgillies.net/2013/12/04/json-diff-and-patch-for-geojson.html#rest_code_19e83f84d84340ebbc65a8efb0212946-2"></a><span class="w"> </span><span class="p">{</span><span class="w"></span>
<a id="rest_code_19e83f84d84340ebbc65a8efb0212946-3" name="rest_code_19e83f84d84340ebbc65a8efb0212946-3" href="https://sgillies.net/2013/12/04/json-diff-and-patch-for-geojson.html#rest_code_19e83f84d84340ebbc65a8efb0212946-3"></a><span class="w"> </span><span class="s2">"path"</span><span class="o">:</span><span class="w"> </span><span class="s2">"/features/2/geometry/coordinates/0"</span><span class="p">,</span><span class="w"></span>
<a id="rest_code_19e83f84d84340ebbc65a8efb0212946-4" name="rest_code_19e83f84d84340ebbc65a8efb0212946-4" href="https://sgillies.net/2013/12/04/json-diff-and-patch-for-geojson.html#rest_code_19e83f84d84340ebbc65a8efb0212946-4"></a><span class="w"> </span><span class="s2">"value"</span><span class="o">:</span><span class="w"> </span><span class="o">-</span><span class="mf">122.655</span><span class="p">,</span><span class="w"></span>
<a id="rest_code_19e83f84d84340ebbc65a8efb0212946-5" name="rest_code_19e83f84d84340ebbc65a8efb0212946-5" href="https://sgillies.net/2013/12/04/json-diff-and-patch-for-geojson.html#rest_code_19e83f84d84340ebbc65a8efb0212946-5"></a><span class="w"> </span><span class="s2">"op"</span><span class="o">:</span><span class="w"> </span><span class="s2">"replace"</span><span class="w"></span>
<a id="rest_code_19e83f84d84340ebbc65a8efb0212946-6" name="rest_code_19e83f84d84340ebbc65a8efb0212946-6" href="https://sgillies.net/2013/12/04/json-diff-and-patch-for-geojson.html#rest_code_19e83f84d84340ebbc65a8efb0212946-6"></a><span class="w"> </span><span class="p">},</span><span class="w"></span>
<a id="rest_code_19e83f84d84340ebbc65a8efb0212946-7" name="rest_code_19e83f84d84340ebbc65a8efb0212946-7" href="https://sgillies.net/2013/12/04/json-diff-and-patch-for-geojson.html#rest_code_19e83f84d84340ebbc65a8efb0212946-7"></a><span class="w"> </span><span class="p">{</span><span class="w"></span>
<a id="rest_code_19e83f84d84340ebbc65a8efb0212946-8" name="rest_code_19e83f84d84340ebbc65a8efb0212946-8" href="https://sgillies.net/2013/12/04/json-diff-and-patch-for-geojson.html#rest_code_19e83f84d84340ebbc65a8efb0212946-8"></a><span class="w"> </span><span class="s2">"path"</span><span class="o">:</span><span class="w"> </span><span class="s2">"/features/2/geometry/coordinates/1"</span><span class="p">,</span><span class="w"></span>
<a id="rest_code_19e83f84d84340ebbc65a8efb0212946-9" name="rest_code_19e83f84d84340ebbc65a8efb0212946-9" href="https://sgillies.net/2013/12/04/json-diff-and-patch-for-geojson.html#rest_code_19e83f84d84340ebbc65a8efb0212946-9"></a><span class="w"> </span><span class="s2">"value"</span><span class="o">:</span><span class="w"> </span><span class="mf">45.522</span><span class="p">,</span><span class="w"></span>
<a id="rest_code_19e83f84d84340ebbc65a8efb0212946-10" name="rest_code_19e83f84d84340ebbc65a8efb0212946-10" href="https://sgillies.net/2013/12/04/json-diff-and-patch-for-geojson.html#rest_code_19e83f84d84340ebbc65a8efb0212946-10"></a><span class="w"> </span><span class="s2">"op"</span><span class="o">:</span><span class="w"> </span><span class="s2">"replace"</span><span class="w"></span>
<a id="rest_code_19e83f84d84340ebbc65a8efb0212946-11" name="rest_code_19e83f84d84340ebbc65a8efb0212946-11" href="https://sgillies.net/2013/12/04/json-diff-and-patch-for-geojson.html#rest_code_19e83f84d84340ebbc65a8efb0212946-11"></a><span class="w"> </span><span class="p">}</span><span class="w"></span>
<a id="rest_code_19e83f84d84340ebbc65a8efb0212946-12" name="rest_code_19e83f84d84340ebbc65a8efb0212946-12" href="https://sgillies.net/2013/12/04/json-diff-and-patch-for-geojson.html#rest_code_19e83f84d84340ebbc65a8efb0212946-12"></a><span class="p">]</span><span class="w"></span>
</pre></div>
<p>There's a potential for RFC 6902 style GeoJSON diffs to become very large if
highly detailed lines and polygons are being modified (via simplication or
reprojection). But GeoJSON itself is quite verbose already and a verbose patch
representation feels not surprising. If you already think GeoJSON sucks, JSON
patch for GeoJSON is going to look exta sucky because of the lengths of paths
to individual coordinate items. I don't think there's any way around that,
although GeoJSON's recursive coordinates member helps a little – consider that
the path to the first 'x' coordinate of the exterior ring of the first part of
a multi-polygon is "just" '/features/42/geometry/coordinates/0/0/0/0'.</p>
<p>I'm not sure how RFC 6902 patches will play out at scale, but I think it's
worth further consideration.</p>