Index: tools/gformat.py
===================================================================
--- tools/gformat.py	(revision 14314)
+++ tools/gformat.py	(revision 14335)
@@ -2351,4 +2351,6 @@
           datadump = get_yaml(system)
           print system, datadump['rdnap_x'], datadump['rdnap_y']
+      elif sys.argv[2] == "nodeplanner.json":
+        print make_network_kml.make_nodeplanner_json()
       elif sys.argv[2] == 'ssh_config':
         print  '''
Index: tools/merge-nodeplanner-json.py
===================================================================
--- tools/merge-nodeplanner-json.py	(revision 14335)
+++ tools/merge-nodeplanner-json.py	(revision 14335)
@@ -0,0 +1,39 @@
+#!/usr/bin/env python3
+import datetime
+import json
+import os
+import socket
+import sys
+
+comment = 'Autogenerated by %s@%s at %s' % (os.environ.get('USER'), socket.gethostname(), datetime.datetime.today().isoformat())
+
+points_seens = []
+points = []
+links = []
+
+# Include auto-generated data
+data = json.load(open(sys.argv[1], 'r'))
+for point in data['points']:
+    if not point['name'] in points_seens:
+        points_seens.append(point['name'])
+        point['comment'] = comment
+        points.append(point)
+for link in data['links']:
+    link['comment'] = comment
+    links.append(link)
+
+
+# Filter out manual modifications
+data = json.load(open(sys.argv[2], 'r'))
+for point in data['points']:
+    if not point['name'] in points_seens:
+        if point['state'] in ['planned', 'wish']:
+            points.append(point)
+
+for link in data['links']:
+    if link['state'] in ['planned', 'wish']:
+        links.append(link)
+
+
+
+print(json.dumps({'points': points, 'links': links}, indent=2, sort_keys=True))
