Index: trunk/src/org/openstreetmap/josm/io/GeoJSONWriter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/GeoJSONWriter.java	(revision 15428)
+++ trunk/src/org/openstreetmap/josm/io/GeoJSONWriter.java	(revision 15429)
@@ -5,9 +5,12 @@
 import java.math.BigDecimal;
 import java.math.RoundingMode;
+import java.util.Collection;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
+import java.util.Set;
 import java.util.stream.Stream;
 
@@ -48,4 +51,6 @@
     private final Projection projection;
     private static final BooleanProperty SKIP_EMPTY_NODES = new BooleanProperty("geojson.export.skip-empty-nodes", true);
+    private static final BooleanProperty UNTAGGED_CLOSED_IS_POLYGON = new BooleanProperty("geojson.export.untagged-closed-is-polygon", false);
+    private static final Set<Way> processedMultipolygonWays = new HashSet<>();
 
     /**
@@ -108,9 +113,14 @@
         public void visit(Way w) {
             if (w != null) {
+                if (!w.isTagged() && processedMultipolygonWays.contains(w)) {
+                    // no need to write this object again
+                    return;
+                }
                 final JsonArrayBuilder array = getCoorsArray(w.getNodes());
-                if (w.isClosed() && ElemStyles.hasAreaElemStyle(w, false)) {
-                    final JsonArrayBuilder container = Json.createArrayBuilder().add(array);
+                boolean writeAsPolygon = w.isClosed() && ((!w.isTagged() && UNTAGGED_CLOSED_IS_POLYGON.get())
+                        || ElemStyles.hasAreaElemStyle(w, false));
+                if (writeAsPolygon) {
                     geomObj.add("type", "Polygon");
-                    geomObj.add("coordinates", container);
+                    geomObj.add("coordinates", Json.createArrayBuilder().add(array));
                 } else {
                     geomObj.add("type", "LineString");
@@ -136,8 +146,20 @@
                 final JsonArrayBuilder multiPolygon = Json.createArrayBuilder().add(polygon);
                 geomObj.add("coordinates", multiPolygon);
+                processedMultipolygonWays.addAll(r.getMemberPrimitives(Way.class));
             } catch (MultipolygonBuilder.JoinedPolygonCreationException ex) {
                 Logging.warn("GeoJSON: Failed to export multipolygon {0}", r.getUniqueId());
                 Logging.warn(ex);
             }
+        }
+
+        private JsonArrayBuilder getCoorsArray(Iterable<Node> nodes) {
+            final JsonArrayBuilder builder = Json.createArrayBuilder();
+            for (Node n : nodes) {
+                LatLon ll = n.getCoor();
+                if (ll != null) {
+                    builder.add(getCoorArray(null, ll));
+                }
+            }
+            return builder;
         }
     }
@@ -153,15 +175,4 @@
     }
 
-    private JsonArrayBuilder getCoorsArray(Iterable<Node> nodes) {
-        final JsonArrayBuilder builder = Json.createArrayBuilder();
-        for (Node n : nodes) {
-            LatLon ll = n.getCoor();
-            if (ll != null) {
-                builder.add(getCoorArray(null, ll));
-            }
-        }
-        return builder;
-    }
-
     protected void appendPrimitive(OsmPrimitive p, JsonArrayBuilder array) {
         if (p.isIncomplete() ||
@@ -182,9 +193,11 @@
         final JsonObject geom = geomObj.build();
 
-        // Build primitive JSON object
-        array.add(Json.createObjectBuilder()
-                .add("type", "Feature")
-                .add("properties", prop.isEmpty() ? JsonValue.NULL : prop)
-                .add("geometry", geom.isEmpty() ? JsonValue.NULL : geom));
+        if (!geom.isEmpty()) {
+            // Build primitive JSON object
+            array.add(Json.createObjectBuilder()
+                    .add("type", "Feature")
+                    .add("properties", prop.isEmpty() ? JsonValue.NULL : prop)
+                    .add("geometry", geom.isEmpty() ? JsonValue.NULL : geom));
+        }
     }
 
@@ -214,5 +227,16 @@
         JsonArrayBuilder array = Json.createArrayBuilder();
         if (ds != null) {
-            ds.allNonDeletedPrimitives().forEach(p -> appendPrimitive(p, array));
+            processedMultipolygonWays.clear();
+            Collection<OsmPrimitive> primitives = ds.allNonDeletedPrimitives();
+            // Relations first
+            for (OsmPrimitive p : primitives) {
+                if (p instanceof Relation)
+                    appendPrimitive(p, array);
+            }
+            for (OsmPrimitive p : primitives) {
+                if (!(p instanceof Relation))
+                    appendPrimitive(p, array);
+            }
+            processedMultipolygonWays.clear();
         }
         object.add("features", array);
