You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@baremaps.apache.org by bc...@apache.org on 2022/12/06 23:54:11 UTC

[incubator-baremaps] branch main updated: Simplify natural and landuse layers (#532)

This is an automated email from the ASF dual-hosted git repository.

bchapuis pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-baremaps.git


The following commit(s) were added to refs/heads/main by this push:
     new 9a1c1685 Simplify natural and landuse layers (#532)
9a1c1685 is described below

commit 9a1c1685198e548d2582e2961400af3ac2e507e7
Author: Bertil Chapuis <bc...@gmail.com>
AuthorDate: Wed Dec 7 00:54:07 2022 +0100

    Simplify natural and landuse layers (#532)
    
    * Simplify natural and landuse layers
    
    * Apply convensions in SQL files
    
    * Parallelize the workflow
    
    * Fix concurrent bug and improve error logging
    
    * Fix IDE run config
    
    * Disable parallel execution
    
    * Finalize the sql scripts and create config file
    
    Co-authored-by: LeonardBesseau <le...@heig-vd.ch>
---
 .run/{import.run.xml => workflow-execute.run.xml}  |   8 +-
 .../apache/baremaps/workflow/WorkflowExecutor.java |  23 +-
 .../apache/baremaps/workflow/tasks/ExecuteSql.java |   5 +-
 map/config.js                                      |   6 +
 map/layers/aerialway/tileset.js                    |   2 +-
 map/layers/amenity/tileset.js                      |   2 +-
 map/layers/attraction/tileset.js                   |   2 +-
 map/layers/barrier/tileset.js                      |   2 +-
 map/layers/boundary/tileset.js                     |   2 +-
 map/layers/building/tileset.js                     |   4 +-
 map/layers/highway/tileset.js                      |   2 +-
 map/layers/landuse/tileset.js                      |  30 +-
 map/layers/leisure/tileset.js                      |   4 +-
 map/layers/man_made/tileset.js                     |   2 +-
 map/layers/natural/tileset.js                      |  18 +-
 map/layers/point/tileset.js                        |   2 +-
 map/layers/power/tileset.js                        |   2 +-
 map/layers/railway/tileset.js                      |   2 +-
 map/layers/route/tileset.js                        |   4 +-
 map/layers/tourism/tileset.js                      |   2 +-
 map/layers/waterway/tileset.js                     |   6 +-
 map/queries/osm_boundary.sql                       |  48 ++--
 map/queries/osm_boundary_index.sql                 |  13 +
 map/queries/osm_boundary_prepare.sql               |  13 +
 map/queries/osm_boundary_simplify.sql              |  83 ++++++
 map/queries/osm_highway.sql                        |  99 -------
 map/queries/osm_highway_index.sql                  |  12 +
 map/queries/osm_highway_prepare.sql                |  24 ++
 map/queries/osm_highway_simplify.sql               |  83 ++++++
 map/queries/osm_landuse.sql                        |  93 -------
 map/queries/osm_landuse_index.sql                  |  12 +
 map/queries/osm_landuse_prepare.sql                | 157 +++++++++++
 map/queries/osm_landuse_simplify.sql               |  83 ++++++
 map/queries/osm_linestring.sql                     |   2 +-
 map/queries/osm_natural.sql                        |  93 -------
 map/queries/osm_natural_index.sql                  |  12 +
 map/queries/osm_natural_prepare.sql                | 303 +++++++++++++++++++++
 map/queries/osm_natural_simplify.sql               |  95 +++++++
 map/queries/osm_node.sql                           |  73 -----
 map/queries/osm_nodes_clean.sql                    |  24 ++
 map/queries/osm_nodes_index.sql                    |  13 +
 map/queries/osm_nodes_prepare.sql                  |   2 +
 map/queries/osm_nodes_simplify.sql                 |  59 ++++
 map/queries/osm_point.sql                          | 120 --------
 map/queries/osm_polygon.sql                        |   9 -
 map/queries/osm_polygon_index.sql                  |   3 +
 map/queries/osm_polygon_prepare.sql                |  18 ++
 map/queries/osm_railway.sql                        | 118 --------
 map/queries/osm_railway_index.sql                  |  13 +
 map/queries/osm_railway_prepare.sql                |  16 ++
 map/queries/osm_railway_simplify.sql               |  83 ++++++
 map/queries/osm_relation.sql                       | 152 -----------
 map/queries/osm_relations_clean.sql                |  24 ++
 map/queries/osm_relations_index.sql                |  12 +
 map/queries/osm_relations_prepare.sql              |   2 +
 map/queries/osm_relations_simplify.sql             | 143 ++++++++++
 map/queries/osm_way.sql                            | 152 -----------
 map/queries/osm_ways_clean.sql                     |  26 ++
 map/queries/osm_ways_index.sql                     |  14 +
 .../{osm_way_member.sql => osm_ways_prepare.sql}   |   7 +-
 map/queries/osm_ways_simplify.sql                  | 145 ++++++++++
 map/style.js                                       |  10 +-
 map/tileset.js                                     |  11 +-
 map/workflow.js                                    | 218 +++++++++++++--
 64 files changed, 1774 insertions(+), 1048 deletions(-)

diff --git a/.run/import.run.xml b/.run/workflow-execute.run.xml
similarity index 75%
rename from .run/import.run.xml
rename to .run/workflow-execute.run.xml
index 716b7e29..1f0821b2 100644
--- a/.run/import.run.xml
+++ b/.run/workflow-execute.run.xml
@@ -1,9 +1,9 @@
 <component name="ProjectRunConfigurationManager">
   <configuration default="false" name="workflow-execute" type="Application" factoryName="Application">
-    <option name="MAIN_CLASS_NAME" value="org.apache.baremaps.Baremaps" />
-    <module name="baremaps-benchmark" />
-    <option name="PROGRAM_PARAMETERS" value="workflow execute --file workflow.json" />
-    <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/docs/examples/openstreetmap" />
+    <option name="MAIN_CLASS_NAME" value="org.apache.baremaps.cli.Baremaps" />
+    <module name="baremaps-cli" />
+    <option name="PROGRAM_PARAMETERS" value="workflow execute --file workflow.js" />
+    <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/map" />
     <extension name="coverage">
       <pattern>
         <option name="PATTERN" value="org.apache.baremaps.server.ogcapi.*" />
diff --git a/baremaps-core/src/main/java/org/apache/baremaps/workflow/WorkflowExecutor.java b/baremaps-core/src/main/java/org/apache/baremaps/workflow/WorkflowExecutor.java
index 1ad4470d..a90e0832 100644
--- a/baremaps-core/src/main/java/org/apache/baremaps/workflow/WorkflowExecutor.java
+++ b/baremaps-core/src/main/java/org/apache/baremaps/workflow/WorkflowExecutor.java
@@ -19,10 +19,7 @@ import com.google.common.graph.GraphBuilder;
 import com.google.common.graph.Graphs;
 import com.google.common.graph.ImmutableGraph;
 import java.util.Map;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
+import java.util.concurrent.*;
 import java.util.stream.Collectors;
 
 /**
@@ -59,7 +56,7 @@ public class WorkflowExecutor implements AutoCloseable {
     this.executorService = executorService;
     this.context = new WorkflowContext();
     this.steps = workflow.getSteps().stream().collect(Collectors.toMap(s -> s.getId(), s -> s));
-    this.futures = new ConcurrentHashMap<>();
+    this.futures = new ConcurrentSkipListMap<>();
 
     // Build the execution graph
     ImmutableGraph.Builder<String> graphBuilder = GraphBuilder.directed().immutable();
@@ -74,7 +71,7 @@ public class WorkflowExecutor implements AutoCloseable {
       }
     }
     this.graph = graphBuilder.build();
-    if (Graphs.hasCycle(graph)) {
+    if (Graphs.hasCycle(this.graph)) {
       throw new WorkflowException("The workflow must be a directed acyclic graph");
     }
   }
@@ -92,9 +89,9 @@ public class WorkflowExecutor implements AutoCloseable {
     return futures.computeIfAbsent(step, this::initStep);
   }
 
-  private CompletableFuture<Void> initStep(String step) {
-    var future = previousSteps(step);
-    for (Task task : steps.get(step).getTasks()) {
+  private CompletableFuture<Void> initStep(String stepId) {
+    var future = previousSteps(stepId);
+    for (Task task : steps.get(stepId).getTasks()) {
       future = future.thenRunAsync(() -> {
         try {
           task.execute(context);
@@ -106,8 +103,8 @@ public class WorkflowExecutor implements AutoCloseable {
     return future;
   }
 
-  private CompletableFuture<Void> previousSteps(String step) {
-    var predecessors = graph.predecessors(step).stream().toList();
+  private CompletableFuture<Void> previousSteps(String stepId) {
+    var predecessors = graph.predecessors(stepId).stream().toList();
     if (predecessors.isEmpty()) {
       return CompletableFuture.completedFuture(null);
     } else if (predecessors.size() == 1) {
@@ -118,8 +115,8 @@ public class WorkflowExecutor implements AutoCloseable {
     }
   }
 
-  private boolean isEndStep(String step) {
-    return graph.successors(step).isEmpty();
+  private boolean isEndStep(String stepId) {
+    return graph.successors(stepId).isEmpty();
   }
 
   @Override
diff --git a/baremaps-core/src/main/java/org/apache/baremaps/workflow/tasks/ExecuteSql.java b/baremaps-core/src/main/java/org/apache/baremaps/workflow/tasks/ExecuteSql.java
index 76a3c581..fb3f8a1b 100644
--- a/baremaps-core/src/main/java/org/apache/baremaps/workflow/tasks/ExecuteSql.java
+++ b/baremaps-core/src/main/java/org/apache/baremaps/workflow/tasks/ExecuteSql.java
@@ -30,7 +30,7 @@ public record ExecuteSql(String database, String file, boolean parallel) impleme
 
   @Override
   public void execute(WorkflowContext context) throws Exception {
-    logger.info("Executing {} into {}", file, database);
+    logger.info("Executing {}", file);
     var queries = Arrays.stream(Files.readString(Paths.get(file)).split(";"));
     if (parallel) {
       queries = queries.parallel();
@@ -41,10 +41,11 @@ public record ExecuteSql(String database, String file, boolean parallel) impleme
         try (var connection = dataSource.getConnection()) {
           connection.createStatement().execute(query);
         } catch (SQLException e) {
+          logger.error("Failed executing {}", query);
           throw new WorkflowException(e);
         }
       });
-    logger.info("Finished executing {} into {}", file, database);
+    logger.info("Finished executing {}", file);
   }
   
 }
diff --git a/map/config.js b/map/config.js
new file mode 100644
index 00000000..cf76c900
--- /dev/null
+++ b/map/config.js
@@ -0,0 +1,6 @@
+export default {
+    "host": "http://localhost:9000",
+    "database": "jdbc:postgresql://localhost:5432/baremaps?&user=baremaps&password=baremaps",
+    "center": [6.6323, 46.5197],
+    "zoom": 14,
+}
diff --git a/map/layers/aerialway/tileset.js b/map/layers/aerialway/tileset.js
index f1029cb9..f477aeb2 100644
--- a/map/layers/aerialway/tileset.js
+++ b/map/layers/aerialway/tileset.js
@@ -5,7 +5,7 @@ export default {
             minzoom: 13,
             maxzoom: 20,
             sql:
-                "SELECT id, tags, geom FROM osm_way_z$zoom WHERE tags ? 'aerialway'",
+                "SELECT id, tags, geom FROM osm_ways_z$zoom WHERE tags ? 'aerialway'",
         },
     ],
 }
diff --git a/map/layers/amenity/tileset.js b/map/layers/amenity/tileset.js
index 0c93fb15..d6aa8c89 100644
--- a/map/layers/amenity/tileset.js
+++ b/map/layers/amenity/tileset.js
@@ -4,7 +4,7 @@ export default {
         {
             minzoom: 13,
             maxzoom: 20,
-            sql: "SELECT id, tags, geom FROM osm_way_z$zoom WHERE tags ? 'amenity'",
+            sql: "SELECT id, tags, geom FROM osm_ways_z$zoom WHERE tags ? 'amenity'",
         },
     ],
 }
diff --git a/map/layers/attraction/tileset.js b/map/layers/attraction/tileset.js
index e2d80e40..60160612 100644
--- a/map/layers/attraction/tileset.js
+++ b/map/layers/attraction/tileset.js
@@ -4,7 +4,7 @@ export default {
         {
             minzoom: 13,
             maxzoom: 20,
-            sql: "SELECT id, tags, geom FROM osm_way_z$zoom WHERE tags ? 'attraction'",
+            sql: "SELECT id, tags, geom FROM osm_ways_z$zoom WHERE tags ? 'attraction'",
         },
     ],
 }
diff --git a/map/layers/barrier/tileset.js b/map/layers/barrier/tileset.js
index 96aeb506..754cb8bf 100644
--- a/map/layers/barrier/tileset.js
+++ b/map/layers/barrier/tileset.js
@@ -5,7 +5,7 @@ export default {
             minzoom: 14,
             maxzoom: 20,
             sql:
-                "SELECT id, tags, geom FROM osm_way_z$zoom WHERE tags ? 'barrier'",
+                "SELECT id, tags, geom FROM osm_ways_z$zoom WHERE tags ? 'barrier'",
         },
     ],
 }
diff --git a/map/layers/boundary/tileset.js b/map/layers/boundary/tileset.js
index 41909d63..0064584a 100644
--- a/map/layers/boundary/tileset.js
+++ b/map/layers/boundary/tileset.js
@@ -17,7 +17,7 @@ export default {
             minzoom: 13,
             maxzoom: 20,
             sql:
-                "SELECT id, tags, geom FROM osm_way_z$zoom WHERE tags ? 'boundary'",
+                "SELECT id, tags, geom FROM osm_ways_z$zoom WHERE tags ? 'boundary'",
         },
     ],
 }
diff --git a/map/layers/building/tileset.js b/map/layers/building/tileset.js
index 59a5a3c8..067be538 100644
--- a/map/layers/building/tileset.js
+++ b/map/layers/building/tileset.js
@@ -5,13 +5,13 @@ export default {
             minzoom: 13,
             maxzoom: 20,
             sql:
-                "SELECT id, tags, geom FROM osm_way_z$zoom WHERE tags ? 'building'",
+                "SELECT id, tags, geom FROM osm_ways_z$zoom WHERE tags ? 'building'",
         },
         {
             minzoom: 13,
             maxzoom: 20,
             sql:
-                "SELECT id, tags, geom FROM osm_relation_z$zoom WHERE tags ? 'building'",
+                "SELECT id, tags, geom FROM osm_relations_z$zoom WHERE tags ? 'building'",
         },
     ],
 }
diff --git a/map/layers/highway/tileset.js b/map/layers/highway/tileset.js
index bab77466..6d83f82b 100644
--- a/map/layers/highway/tileset.js
+++ b/map/layers/highway/tileset.js
@@ -35,7 +35,7 @@ export default {
             minzoom: 14,
             maxzoom: 20,
             sql:
-                "SELECT id, tags, geom FROM osm_way_z$zoom WHERE tags ? 'highway'",
+                "SELECT id, tags, geom FROM osm_ways_z$zoom WHERE tags ? 'highway'",
         },
     ],
 }
diff --git a/map/layers/landuse/tileset.js b/map/layers/landuse/tileset.js
index ee914669..13d052c7 100644
--- a/map/layers/landuse/tileset.js
+++ b/map/layers/landuse/tileset.js
@@ -5,37 +5,23 @@ export default {
             minzoom: 3,
             maxzoom: 6,
             sql:
-                "SELECT id, tags, geom FROM osm_way_z$zoom WHERE tags ->> 'landuse' IN ('farmland', 'forest', 'meadow')",
-        },
-        {
-            minzoom: 3,
-            maxzoom: 6,
-            sql:
-                "SELECT id, tags, geom FROM osm_relation_z$zoom WHERE tags ->> 'landuse' IN ('farmland', 'forest', 'meadow')",
-        },
-        {
-            minzoom: 6,
-            maxzoom: 10,
-            sql:
-                "SELECT id, tags, geom FROM osm_way_z$zoom WHERE tags ->> 'landuse' IN ('farmland', 'forest', 'meadow', 'residential', 'forest')",
+                "SELECT id, tags, geom FROM osm_landuse_z$zoom WHERE tags ->> 'landuse' IN ('farmland', 'forest', 'meadow')",
         },
         {
             minzoom: 6,
-            maxzoom: 10,
+            maxzoom: 12,
             sql:
-                "SELECT id, tags, geom FROM osm_relation_z$zoom WHERE tags ->> 'landuse' IN ('farmland', 'forest', 'meadow', 'residential', 'forest')",
+                "SELECT id, tags, geom FROM osm_landuse_z$zoom WHERE tags ->> 'landuse' IN ('farmland', 'forest', 'meadow', 'residential', 'vineyard')",
         },
         {
-            minzoom: 10,
+            minzoom: 12,
             maxzoom: 20,
-            sql:
-                "SELECT id, tags, geom FROM osm_way_z$zoom WHERE tags ? 'landuse'",
+            sql: "SELECT id, tags, geom FROM osm_ways_z$zoom WHERE tags ? 'landuse'"
         },
         {
-            minzoom: 10,
+            minzoom: 12,
             maxzoom: 20,
-            sql:
-                "SELECT id, tags, geom FROM osm_relation_z$zoom WHERE tags ? 'landuse'",
-        },
+            sql: "SELECT id, tags, geom FROM osm_relations_z$zoom WHERE tags ? 'landuse'"
+        }
     ],
 }
diff --git a/map/layers/leisure/tileset.js b/map/layers/leisure/tileset.js
index da872797..6260c926 100644
--- a/map/layers/leisure/tileset.js
+++ b/map/layers/leisure/tileset.js
@@ -5,13 +5,13 @@ export default {
             minzoom: 13,
             maxzoom: 20,
             sql:
-                "SELECT id, tags, geom FROM osm_way_z$zoom WHERE tags ? 'leisure'",
+                "SELECT id, tags, geom FROM osm_ways_z$zoom WHERE tags ? 'leisure'",
         },
         {
             minzoom: 13,
             maxzoom: 20,
             sql:
-                "SELECT id, tags, geom FROM osm_relation_z$zoom WHERE tags ? 'leisure'",
+                "SELECT id, tags, geom FROM osm_relations_z$zoom WHERE tags ? 'leisure'",
         },
     ],
 }
diff --git a/map/layers/man_made/tileset.js b/map/layers/man_made/tileset.js
index 03e8ff39..17452a0e 100644
--- a/map/layers/man_made/tileset.js
+++ b/map/layers/man_made/tileset.js
@@ -4,7 +4,7 @@ export default {
         {
             "minzoom": 14,
             "maxzoom": 20,
-            "sql": "SELECT id, tags, geom FROM osm_way_z$zoom WHERE tags ? 'man_made'"
+            "sql": "SELECT id, tags, geom FROM osm_ways_z$zoom WHERE tags ? 'man_made'"
         }
     ]
 }
diff --git a/map/layers/natural/tileset.js b/map/layers/natural/tileset.js
index 7fbfc04b..cfd6739e 100644
--- a/map/layers/natural/tileset.js
+++ b/map/layers/natural/tileset.js
@@ -4,32 +4,22 @@ export default {
         {
             "minzoom": 3,
             "maxzoom": 6,
-            "sql": "SELECT id, tags, geom FROM osm_way_z$zoom WHERE tags ->> 'natural' IN ('wood', 'scrub', 'heath', 'grassland', 'bare_rock', 'scree', 'shingle', 'sand', 'mud', 'water', 'wetland', 'glacier', 'beach')"
-        },
-        {
-            "minzoom": 3,
-            "maxzoom": 6,
-            "sql": "SELECT id, tags, geom FROM osm_relation_z$zoom WHERE tags ->> 'natural' IN ('wood', 'scrub', 'heath', 'grassland', 'bare_rock', 'scree', 'shingle', 'sand', 'mud', 'water', 'wetland', 'glacier', 'beach')"
-        },
-        {
-            "minzoom": 6,
-            "maxzoom": 12,
-            "sql": "SELECT id, tags, geom FROM osm_way_z$zoom WHERE tags ->> 'natural' IN ('wood', 'scrub', 'heath', 'grassland', 'bare_rock', 'scree', 'shingle', 'sand', 'mud', 'water', 'wetland', 'glacier', 'beach')"
+            "sql": "SELECT id, tags, geom FROM osm_natural_z$zoom WHERE tags ->> 'natural' IN ('wood', 'scrub', 'heath', 'grassland', 'bare_rock', 'scree', 'shingle', 'sand', 'mud', 'water', 'wetland', 'glacier', 'beach')"
         },
         {
             "minzoom": 6,
             "maxzoom": 12,
-            "sql": "SELECT id, tags, geom FROM osm_relation_z$zoom WHERE tags ->> 'natural' IN ('wood', 'scrub', 'heath', 'grassland', 'bare_rock', 'scree', 'shingle', 'sand', 'mud', 'water', 'wetland', 'glacier', 'beach')"
+            "sql": "SELECT id, tags, geom FROM osm_natural_z$zoom WHERE tags ->> 'natural' IN ('wood', 'scrub', 'heath', 'grassland', 'bare_rock', 'scree', 'shingle', 'sand', 'mud', 'water', 'wetland', 'glacier', 'beach')"
         },
         {
             "minzoom": 12,
             "maxzoom": 20,
-            "sql": "SELECT id, tags, geom FROM osm_way_z$zoom WHERE tags ? 'natural' AND tags ->> 'natural' NOT IN ('coastline')"
+            "sql": "SELECT id, tags, geom FROM osm_ways_z$zoom WHERE tags ? 'natural' AND tags ->> 'natural' NOT IN ('coastline')"
         },
         {
             "minzoom": 12,
             "maxzoom": 20,
-            "sql": "SELECT id, tags, geom FROM osm_relation_z$zoom WHERE tags ? 'natural' AND tags ->> 'natural' NOT IN ('coastline')"
+            "sql": "SELECT id, tags, geom FROM osm_relations_z$zoom WHERE tags ? 'natural' AND tags ->> 'natural' NOT IN ('coastline')"
         }
     ]
 }
diff --git a/map/layers/point/tileset.js b/map/layers/point/tileset.js
index a7748ae7..758048a2 100644
--- a/map/layers/point/tileset.js
+++ b/map/layers/point/tileset.js
@@ -4,7 +4,7 @@ export default {
         {
             "minzoom": 1,
             "maxzoom": 20,
-            "sql": "SELECT id, tags, geom FROM osm_node_z$zoom WHERE tags != '{}'"
+            "sql": "SELECT id, tags, geom FROM osm_nodes_z$zoom WHERE tags != '{}'"
         }
     ]
 }
diff --git a/map/layers/power/tileset.js b/map/layers/power/tileset.js
index 93643d1b..9b74bfa8 100644
--- a/map/layers/power/tileset.js
+++ b/map/layers/power/tileset.js
@@ -4,7 +4,7 @@ export default {
         {
             "minzoom": 12,
             "maxzoom": 20,
-            "sql": "SELECT id, tags, geom FROM osm_way_z$zoom WHERE tags ->> 'power' IN ('cable', 'line', 'minor_line', 'plant', 'substation')"
+            "sql": "SELECT id, tags, geom FROM osm_ways_z$zoom WHERE tags ->> 'power' IN ('cable', 'line', 'minor_line', 'plant', 'substation')"
         }
     ]
 }
diff --git a/map/layers/railway/tileset.js b/map/layers/railway/tileset.js
index 28a279b7..67770827 100644
--- a/map/layers/railway/tileset.js
+++ b/map/layers/railway/tileset.js
@@ -9,7 +9,7 @@ export default {
         {
             "minzoom": 12,
             "maxzoom": 20,
-            "sql": "SELECT id, tags, geom FROM osm_way_z$zoom WHERE tags ? 'railway'"
+            "sql": "SELECT id, tags, geom FROM osm_ways_z$zoom WHERE tags ? 'railway'"
         }
     ]
 }
diff --git a/map/layers/route/tileset.js b/map/layers/route/tileset.js
index d9fa9d75..3b8c82f5 100644
--- a/map/layers/route/tileset.js
+++ b/map/layers/route/tileset.js
@@ -4,12 +4,12 @@ export default {
         {
             "minzoom": 9,
             "maxzoom": 12,
-            "sql": "SELECT id, tags, geom FROM osm_way_z$zoom WHERE tags ? 'route'"
+            "sql": "SELECT id, tags, geom FROM osm_ways_z$zoom WHERE tags ? 'route'"
         },
         {
             "minzoom": 12,
             "maxzoom": 20,
-            "sql": "SELECT id, tags, geom FROM osm_way_z$zoom WHERE tags ? 'route'"
+            "sql": "SELECT id, tags, geom FROM osm_ways_z$zoom WHERE tags ? 'route'"
         }
     ]
 }
diff --git a/map/layers/tourism/tileset.js b/map/layers/tourism/tileset.js
index 6521cd3e..b5249bc4 100644
--- a/map/layers/tourism/tileset.js
+++ b/map/layers/tourism/tileset.js
@@ -4,7 +4,7 @@ export default {
         {
             "minzoom": 14,
             "maxzoom": 20,
-            "sql": "SELECT id, tags, geom FROM osm_relation_z$zoom WHERE tags ? 'tourism'"
+            "sql": "SELECT id, tags, geom FROM osm_relations_z$zoom WHERE tags ? 'tourism'"
         }
     ]
 }
diff --git a/map/layers/waterway/tileset.js b/map/layers/waterway/tileset.js
index 51718f07..d84fcbd9 100644
--- a/map/layers/waterway/tileset.js
+++ b/map/layers/waterway/tileset.js
@@ -4,17 +4,17 @@ export default {
         {
             "minzoom": 6,
             "maxzoom": 10,
-            "sql": "SELECT id, tags, geom FROM osm_way_z$zoom WHERE tags ->> 'waterway' IN ('river')"
+            "sql": "SELECT id, tags, geom FROM osm_ways_z$zoom WHERE tags ->> 'waterway' IN ('river')"
         },
         {
             "minzoom": 10,
             "maxzoom": 12,
-            "sql": "SELECT id, tags, geom FROM osm_way_z$zoom WHERE tags ->> 'waterway' IN ('river', 'stream')"
+            "sql": "SELECT id, tags, geom FROM osm_ways_z$zoom WHERE tags ->> 'waterway' IN ('river', 'stream')"
         },
         {
             "minzoom": 12,
             "maxzoom": 20,
-            "sql": "SELECT id, tags, geom FROM osm_way_z$zoom WHERE tags ? 'waterway'"
+            "sql": "SELECT id, tags, geom FROM osm_ways_z$zoom WHERE tags ? 'waterway'"
         }
     ]
 }
diff --git a/map/queries/osm_boundary.sql b/map/queries/osm_boundary.sql
index a56b36cf..5e5a4b8a 100644
--- a/map/queries/osm_boundary.sql
+++ b/map/queries/osm_boundary.sql
@@ -12,63 +12,63 @@ FROM (
 
 CREATE MATERIALIZED VIEW osm_boundary_z1 AS
 SELECT id, tags, geom
-FROM (SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 1)) AS geom FROM osm_boundary) AS osm_boundary
-WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((39135 / power(2, 1)), 2));
+FROM (SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 1)) AS geom FROM osm_boundary) AS osm_boundary
+WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((78270 / power(2, 1)), 2));
 
 CREATE MATERIALIZED VIEW osm_boundary_z2 AS
 SELECT id, tags, geom
-FROM (SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 2)) AS geom FROM osm_boundary) AS osm_boundary
-WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((39135 / power(2, 2)), 2));
+FROM (SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 2)) AS geom FROM osm_boundary) AS osm_boundary
+WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((78270 / power(2, 2)), 2));
 
 CREATE MATERIALIZED VIEW osm_boundary_z3 AS
 SELECT id, tags, geom
-FROM (SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 3)) AS geom FROM osm_boundary) AS osm_boundary
-WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((39135 / power(2, 3)), 2));
+FROM (SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 3)) AS geom FROM osm_boundary) AS osm_boundary
+WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((78270 / power(2, 3)), 2));
 
 CREATE MATERIALIZED VIEW osm_boundary_z4 AS
 SELECT id, tags, geom
-FROM (SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 4)) AS geom FROM osm_boundary) AS osm_boundary
-WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((39135 / power(2, 4)), 2));
+FROM (SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 4)) AS geom FROM osm_boundary) AS osm_boundary
+WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((78270 / power(2, 4)), 2));
 
 CREATE MATERIALIZED VIEW osm_boundary_z5 AS
 SELECT id, tags, geom
-FROM (SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 5)) AS geom FROM osm_boundary) AS osm_boundary
-WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((39135 / power(2, 5)), 2));
+FROM (SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 5)) AS geom FROM osm_boundary) AS osm_boundary
+WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((78270 / power(2, 5)), 2));
 
 CREATE MATERIALIZED VIEW osm_boundary_z6 AS
 SELECT id, tags, geom
-FROM (SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 6)) AS geom FROM osm_boundary) AS osm_boundary
-WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((39135 / power(2, 6)), 2));
+FROM (SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 6)) AS geom FROM osm_boundary) AS osm_boundary
+WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((78270 / power(2, 6)), 2));
 
 CREATE MATERIALIZED VIEW osm_boundary_z7 AS
 SELECT id, tags, geom
-FROM (SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 7)) AS geom FROM osm_boundary) AS osm_boundary
-WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((39135 / power(2, 7)), 2));
+FROM (SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 7)) AS geom FROM osm_boundary) AS osm_boundary
+WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((78270 / power(2, 7)), 2));
 
 CREATE MATERIALIZED VIEW osm_boundary_z8 AS
 SELECT id, tags, geom
-FROM (SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 8)) AS geom FROM osm_boundary) AS osm_boundary
-WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((39135 / power(2, 8)), 2));
+FROM (SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 8)) AS geom FROM osm_boundary) AS osm_boundary
+WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((78270 / power(2, 8)), 2));
 
 CREATE MATERIALIZED VIEW osm_boundary_z9 AS
 SELECT id, tags, geom
-FROM (SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 9)) AS geom FROM osm_boundary) AS osm_boundary
-WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((39135 / power(2, 9)), 2));
+FROM (SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 9)) AS geom FROM osm_boundary) AS osm_boundary
+WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((78270 / power(2, 9)), 2));
 
 CREATE MATERIALIZED VIEW osm_boundary_z10 AS
 SELECT id, tags, geom
-FROM (SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 10)) AS geom FROM osm_boundary) AS osm_boundary
-WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((39135 / power(2, 10)), 2));
+FROM (SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 10)) AS geom FROM osm_boundary) AS osm_boundary
+WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((78270 / power(2, 10)), 2));
 
 CREATE MATERIALIZED VIEW osm_boundary_z11 AS
 SELECT id, tags, geom
-FROM (SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 11)) AS geom FROM osm_boundary) AS osm_boundary
-WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((39135 / power(2, 11)), 2));
+FROM (SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 11)) AS geom FROM osm_boundary) AS osm_boundary
+WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((78270 / power(2, 11)), 2));
 
 CREATE MATERIALIZED VIEW osm_boundary_z12 AS
 SELECT id, tags, geom
-FROM (SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 12)) AS geom FROM osm_boundary) AS osm_boundary
-WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((39135 / power(2, 12)), 2));
+FROM (SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 12)) AS geom FROM osm_boundary) AS osm_boundary
+WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((78270 / power(2, 12)), 2));
 
 CREATE VIEW osm_boundary_z13 AS SELECT id, tags, geom FROM osm_boundary;
 CREATE VIEW osm_boundary_z14 AS SELECT id, tags, geom FROM osm_boundary;
diff --git a/map/queries/osm_boundary_index.sql b/map/queries/osm_boundary_index.sql
new file mode 100644
index 00000000..0db0c497
--- /dev/null
+++ b/map/queries/osm_boundary_index.sql
@@ -0,0 +1,13 @@
+CREATE INDEX IF NOT EXISTS osm_boundary_geom_z1_index ON osm_boundary_z1 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_boundary_geom_z2_index ON osm_boundary_z2 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_boundary_geom_z3_index ON osm_boundary_z3 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_boundary_geom_z4_index ON osm_boundary_z4 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_boundary_geom_z5_index ON osm_boundary_z5 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_boundary_geom_z6_index ON osm_boundary_z6 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_boundary_geom_z7_index ON osm_boundary_z7 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_boundary_geom_z8_index ON osm_boundary_z8 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_boundary_geom_z9_index ON osm_boundary_z9 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_boundary_geom_z10_index ON osm_boundary_z10 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_boundary_geom_z11_index ON osm_boundary_z11 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_boundary_geom_z12_index ON osm_boundary_z12 USING SPGIST (geom);
+
diff --git a/map/queries/osm_boundary_prepare.sql b/map/queries/osm_boundary_prepare.sql
new file mode 100644
index 00000000..1f61d905
--- /dev/null
+++ b/map/queries/osm_boundary_prepare.sql
@@ -0,0 +1,13 @@
+DROP MATERIALIZED VIEW IF EXISTS osm_boundary CASCADE;
+
+CREATE MATERIALIZED VIEW osm_boundary AS
+SELECT ROW_NUMBER() OVER () as id, tags, geom
+FROM (
+   SELECT jsonb_build_object('boundary', 'administrative', 'admin_level', tags -> 'admin_level', 'name', tags -> 'name') as tags, (st_dump(st_linemerge(st_collect(geom)))).geom as geom
+   FROM osm_linestring
+   WHERE tags ->> 'boundary' IN ('administrative')
+     AND tags ->> 'admin_level' IN ('1', '2', '3', '4')
+   GROUP BY tags -> 'admin_level', tags -> 'name'
+) AS merge;
+
+CREATE INDEX IF NOT EXISTS osm_boundary_geom_index ON osm_boundary USING SPGIST (geom);
diff --git a/map/queries/osm_boundary_simplify.sql b/map/queries/osm_boundary_simplify.sql
new file mode 100644
index 00000000..8456ffa0
--- /dev/null
+++ b/map/queries/osm_boundary_simplify.sql
@@ -0,0 +1,83 @@
+CREATE VIEW osm_boundary_z20 AS
+SELECT id, tags, geom FROM osm_boundary;
+
+CREATE VIEW osm_boundary_z19 AS
+SELECT id, tags, geom FROM osm_boundary;
+
+CREATE VIEW osm_boundary_z18 AS
+SELECT id, tags, geom FROM osm_boundary;
+
+CREATE VIEW osm_boundary_z17 AS
+SELECT id, tags, geom FROM osm_boundary;
+
+CREATE VIEW osm_boundary_z16 AS
+SELECT id, tags, geom FROM osm_boundary;
+
+CREATE VIEW osm_boundary_z15 AS
+SELECT id, tags, geom FROM osm_boundary;
+
+CREATE VIEW osm_boundary_z14 AS
+SELECT id, tags, geom FROM osm_boundary;
+
+CREATE VIEW osm_boundary_z13 AS
+SELECT id, tags, geom FROM osm_boundary;
+
+CREATE MATERIALIZED VIEW osm_boundary_z12 AS
+SELECT id, tags, geom
+FROM (SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 12)) AS geom FROM osm_boundary) AS osm_boundary
+WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((78270 / power(2, 12)), 2));
+
+CREATE MATERIALIZED VIEW osm_boundary_z11 AS
+SELECT id, tags, geom
+FROM (SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 11)) AS geom FROM osm_boundary) AS osm_boundary
+WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((78270 / power(2, 11)), 2));
+
+CREATE MATERIALIZED VIEW osm_boundary_z10 AS
+SELECT id, tags, geom
+FROM (SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 10)) AS geom FROM osm_boundary) AS osm_boundary
+WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((78270 / power(2, 10)), 2));
+
+CREATE MATERIALIZED VIEW osm_boundary_z9 AS
+SELECT id, tags, geom
+FROM (SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 9)) AS geom FROM osm_boundary) AS osm_boundary
+WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((78270 / power(2, 9)), 2));
+
+CREATE MATERIALIZED VIEW osm_boundary_z8 AS
+SELECT id, tags, geom
+FROM (SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 8)) AS geom FROM osm_boundary) AS osm_boundary
+WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((78270 / power(2, 8)), 2));
+
+CREATE MATERIALIZED VIEW osm_boundary_z7 AS
+SELECT id, tags, geom
+FROM (SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 7)) AS geom FROM osm_boundary) AS osm_boundary
+WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((78270 / power(2, 7)), 2));
+
+CREATE MATERIALIZED VIEW osm_boundary_z6 AS
+SELECT id, tags, geom
+FROM (SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 6)) AS geom FROM osm_boundary) AS osm_boundary
+WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((78270 / power(2, 6)), 2));
+
+CREATE MATERIALIZED VIEW osm_boundary_z5 AS
+SELECT id, tags, geom
+FROM (SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 5)) AS geom FROM osm_boundary) AS osm_boundary
+WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((78270 / power(2, 5)), 2));
+
+CREATE MATERIALIZED VIEW osm_boundary_z4 AS
+SELECT id, tags, geom
+FROM (SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 4)) AS geom FROM osm_boundary) AS osm_boundary
+WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((78270 / power(2, 4)), 2));
+
+CREATE MATERIALIZED VIEW osm_boundary_z3 AS
+SELECT id, tags, geom
+FROM (SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 3)) AS geom FROM osm_boundary) AS osm_boundary
+WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((78270 / power(2, 3)), 2));
+
+CREATE MATERIALIZED VIEW osm_boundary_z2 AS
+SELECT id, tags, geom
+FROM (SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 2)) AS geom FROM osm_boundary) AS osm_boundary
+WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((78270 / power(2, 2)), 2));
+
+CREATE MATERIALIZED VIEW osm_boundary_z1 AS
+SELECT id, tags, geom
+FROM (SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 1)) AS geom FROM osm_boundary) AS osm_boundary
+WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((78270 / power(2, 1)), 2));
diff --git a/map/queries/osm_highway.sql b/map/queries/osm_highway.sql
deleted file mode 100644
index 76b3dda1..00000000
--- a/map/queries/osm_highway.sql
+++ /dev/null
@@ -1,99 +0,0 @@
-DROP MATERIALIZED VIEW IF EXISTS osm_highway CASCADE;
-
-CREATE MATERIALIZED VIEW osm_highway AS
-SELECT ROW_NUMBER() OVER () as id, tags, geom
-FROM (
-    SELECT jsonb_build_object('highway', tags -> 'highway', 'ref', tags -> 'ref') as tags, (st_dump(st_linemerge(st_collect(geom)))).geom as geom
-    FROM osm_linestring
-    WHERE tags ->> 'highway' IN ('motorway', 'motorway_link', 'trunk', 'trunk_link', 'primary', 'primary_link', 'secondary', 'secondary_link', 'tertiary',  'tertiary_link', 'unclassified', 'residential')
-    AND tags ? 'ref'
-    GROUP BY tags -> 'highway', tags -> 'ref'
-    UNION ALL
-    SELECT jsonb_build_object('highway', tags -> 'highway') as tags, geom
-    FROM osm_linestring
-    WHERE tags ->> 'highway' IN ('motorway', 'motorway_link', 'trunk', 'trunk_link', 'primary', 'primary_link', 'secondary', 'secondary_link', 'tertiary',  'tertiary_link', 'unclassified', 'residential')
-    AND NOT tags ? 'ref'
-) AS merge;
-
-CREATE MATERIALIZED VIEW osm_highway_z1 AS
-SELECT id, tags, geom
-FROM (SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 1)) AS geom FROM osm_highway) AS osm_highway
-WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((39135 / power(2, 1)), 2));
-
-CREATE MATERIALIZED VIEW osm_highway_z2 AS
-SELECT id, tags, geom
-FROM (SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 2)) AS geom FROM osm_highway) AS osm_highway
-WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((39135 / power(2, 2)), 2));
-
-CREATE MATERIALIZED VIEW osm_highway_z3 AS
-SELECT id, tags, geom
-FROM (SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 3)) AS geom FROM osm_highway) AS osm_highway
-WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((39135 / power(2, 3)), 2));
-
-CREATE MATERIALIZED VIEW osm_highway_z4 AS
-SELECT id, tags, geom
-FROM (SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 4)) AS geom FROM osm_highway) AS osm_highway
-WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((39135 / power(2, 4)), 2));
-
-CREATE MATERIALIZED VIEW osm_highway_z5 AS
-SELECT id, tags, geom
-FROM (SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 5)) AS geom FROM osm_highway) AS osm_highway
-WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((39135 / power(2, 5)), 2));
-
-CREATE MATERIALIZED VIEW osm_highway_z6 AS
-SELECT id, tags, geom
-FROM (SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 6)) AS geom FROM osm_highway) AS osm_highway
-WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((39135 / power(2, 6)), 2));
-
-CREATE MATERIALIZED VIEW osm_highway_z7 AS
-SELECT id, tags, geom
-FROM (SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 7)) AS geom FROM osm_highway) AS osm_highway
-WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((39135 / power(2, 7)), 2));
-
-CREATE MATERIALIZED VIEW osm_highway_z8 AS
-SELECT id, tags, geom
-FROM (SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 8)) AS geom FROM osm_highway) AS osm_highway
-WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((39135 / power(2, 8)), 2));
-
-CREATE MATERIALIZED VIEW osm_highway_z9 AS
-SELECT id, tags, geom
-FROM (SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 9)) AS geom FROM osm_highway) AS osm_highway
-WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((39135 / power(2, 9)), 2));
-
-CREATE MATERIALIZED VIEW osm_highway_z10 AS
-SELECT id, tags, geom
-FROM (SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 10)) AS geom FROM osm_highway) AS osm_highway
-WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((39135 / power(2, 10)), 2));
-
-CREATE MATERIALIZED VIEW osm_highway_z11 AS
-SELECT id, tags, geom
-FROM (SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 11)) AS geom FROM osm_highway) AS osm_highway
-WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((39135 / power(2, 11)), 2));
-
-CREATE MATERIALIZED VIEW osm_highway_z12 AS
-SELECT id, tags, geom
-FROM (SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 12)) AS geom FROM osm_highway) AS osm_highway
-WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((39135 / power(2, 12)), 2));
-
-CREATE VIEW osm_highway_z13 AS SELECT id, tags, geom FROM osm_highway;
-CREATE VIEW osm_highway_z14 AS SELECT id, tags, geom FROM osm_highway;
-CREATE VIEW osm_highway_z15 AS SELECT id, tags, geom FROM osm_highway;
-CREATE VIEW osm_highway_z16 AS SELECT id, tags, geom FROM osm_highway;
-CREATE VIEW osm_highway_z17 AS SELECT id, tags, geom FROM osm_highway;
-CREATE VIEW osm_highway_z18 AS SELECT id, tags, geom FROM osm_highway;
-CREATE VIEW osm_highway_z19 AS SELECT id, tags, geom FROM osm_highway;
-CREATE VIEW osm_highway_z20 AS SELECT id, tags, geom FROM osm_highway;
-
-CREATE INDEX IF NOT EXISTS osm_highway_geom_index ON osm_highway USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_highway_geom_z1_index ON osm_highway_z1 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_highway_geom_z2_index ON osm_highway_z2 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_highway_geom_z3_index ON osm_highway_z3 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_highway_geom_z4_index ON osm_highway_z4 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_highway_geom_z5_index ON osm_highway_z5 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_highway_geom_z6_index ON osm_highway_z6 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_highway_geom_z7_index ON osm_highway_z7 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_highway_geom_z8_index ON osm_highway_z8 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_highway_geom_z9_index ON osm_highway_z9 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_highway_geom_z10_index ON osm_highway_z10 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_highway_geom_z11_index ON osm_highway_z11 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_highway_geom_z12_index ON osm_highway_z12 USING SPGIST (geom);
diff --git a/map/queries/osm_highway_index.sql b/map/queries/osm_highway_index.sql
new file mode 100644
index 00000000..49d5eda4
--- /dev/null
+++ b/map/queries/osm_highway_index.sql
@@ -0,0 +1,12 @@
+CREATE INDEX IF NOT EXISTS osm_highway_geom_z1_index ON osm_highway_z1 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_highway_geom_z2_index ON osm_highway_z2 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_highway_geom_z3_index ON osm_highway_z3 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_highway_geom_z4_index ON osm_highway_z4 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_highway_geom_z5_index ON osm_highway_z5 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_highway_geom_z6_index ON osm_highway_z6 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_highway_geom_z7_index ON osm_highway_z7 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_highway_geom_z8_index ON osm_highway_z8 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_highway_geom_z9_index ON osm_highway_z9 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_highway_geom_z10_index ON osm_highway_z10 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_highway_geom_z11_index ON osm_highway_z11 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_highway_geom_z12_index ON osm_highway_z12 USING SPGIST (geom);
diff --git a/map/queries/osm_highway_prepare.sql b/map/queries/osm_highway_prepare.sql
new file mode 100644
index 00000000..6c02b727
--- /dev/null
+++ b/map/queries/osm_highway_prepare.sql
@@ -0,0 +1,24 @@
+DROP MATERIALIZED VIEW IF EXISTS osm_highway CASCADE;
+
+CREATE MATERIALIZED VIEW osm_highway AS
+SELECT id, tags, geom
+FROM (
+    SELECT
+        min(id) as id,
+        jsonb_build_object('highway', tags -> 'highway', 'ref', tags -> 'ref') as tags,
+        (st_dump(st_linemerge(st_collect(geom)))).geom as geom
+    FROM osm_linestring
+    WHERE tags ->> 'highway' IN ('motorway', 'motorway_link', 'trunk', 'trunk_link', 'primary', 'primary_link', 'secondary', 'secondary_link', 'tertiary',  'tertiary_link', 'unclassified', 'residential')
+    AND tags ? 'ref'
+    GROUP BY tags -> 'highway', tags -> 'ref'
+    UNION ALL
+    SELECT
+        id,
+        jsonb_build_object('highway', tags -> 'highway') as tags,
+        geom
+    FROM osm_linestring
+    WHERE tags ->> 'highway' IN ('motorway', 'motorway_link', 'trunk', 'trunk_link', 'primary', 'primary_link', 'secondary', 'secondary_link', 'tertiary',  'tertiary_link', 'unclassified', 'residential')
+    AND NOT (tags ? 'ref')
+) AS merge;
+
+CREATE INDEX IF NOT EXISTS osm_highway_geom_index ON osm_highway USING SPGIST (geom);
diff --git a/map/queries/osm_highway_simplify.sql b/map/queries/osm_highway_simplify.sql
new file mode 100644
index 00000000..542906b3
--- /dev/null
+++ b/map/queries/osm_highway_simplify.sql
@@ -0,0 +1,83 @@
+CREATE VIEW osm_highway_z20 AS
+SELECT id, tags, geom FROM osm_highway;
+
+CREATE VIEW osm_highway_z19 AS
+SELECT id, tags, geom FROM osm_highway;
+
+CREATE VIEW osm_highway_z18 AS
+SELECT id, tags, geom FROM osm_highway;
+
+CREATE VIEW osm_highway_z17 AS
+SELECT id, tags, geom FROM osm_highway;
+
+CREATE VIEW osm_highway_z16 AS
+SELECT id, tags, geom FROM osm_highway;
+
+CREATE VIEW osm_highway_z15 AS
+SELECT id, tags, geom FROM osm_highway;
+
+CREATE VIEW osm_highway_z14 AS
+SELECT id, tags, geom FROM osm_highway;
+
+CREATE VIEW osm_highway_z13 AS
+SELECT id, tags, geom FROM osm_highway;
+
+CREATE MATERIALIZED VIEW osm_highway_z12 AS
+SELECT id, tags, geom
+FROM (SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 12)) AS geom FROM osm_highway) AS osm_highway
+WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((78270 / power(2, 12)), 2));
+
+CREATE MATERIALIZED VIEW osm_highway_z11 AS
+SELECT id, tags, geom
+FROM (SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 11)) AS geom FROM osm_highway) AS osm_highway
+WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((78270 / power(2, 11)), 2));
+
+CREATE MATERIALIZED VIEW osm_highway_z10 AS
+SELECT id, tags, geom
+FROM (SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 10)) AS geom FROM osm_highway) AS osm_highway
+WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((78270 / power(2, 10)), 2));
+
+CREATE MATERIALIZED VIEW osm_highway_z9 AS
+SELECT id, tags, geom
+FROM (SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 9)) AS geom FROM osm_highway) AS osm_highway
+WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((78270 / power(2, 9)), 2));
+
+CREATE MATERIALIZED VIEW osm_highway_z8 AS
+SELECT id, tags, geom
+FROM (SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 8)) AS geom FROM osm_highway) AS osm_highway
+WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((78270 / power(2, 8)), 2));
+
+CREATE MATERIALIZED VIEW osm_highway_z7 AS
+SELECT id, tags, geom
+FROM (SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 7)) AS geom FROM osm_highway) AS osm_highway
+WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((78270 / power(2, 7)), 2));
+
+CREATE MATERIALIZED VIEW osm_highway_z6 AS
+SELECT id, tags, geom
+FROM (SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 6)) AS geom FROM osm_highway) AS osm_highway
+WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((78270 / power(2, 6)), 2));
+
+CREATE MATERIALIZED VIEW osm_highway_z5 AS
+SELECT id, tags, geom
+FROM (SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 5)) AS geom FROM osm_highway) AS osm_highway
+WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((78270 / power(2, 5)), 2));
+
+CREATE MATERIALIZED VIEW osm_highway_z4 AS
+SELECT id, tags, geom
+FROM (SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 4)) AS geom FROM osm_highway) AS osm_highway
+WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((78270 / power(2, 4)), 2));
+
+CREATE MATERIALIZED VIEW osm_highway_z3 AS
+SELECT id, tags, geom
+FROM (SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 3)) AS geom FROM osm_highway) AS osm_highway
+WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((78270 / power(2, 3)), 2));
+
+CREATE MATERIALIZED VIEW osm_highway_z2 AS
+SELECT id, tags, geom
+FROM (SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 2)) AS geom FROM osm_highway) AS osm_highway
+WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((78270 / power(2, 2)), 2));
+
+CREATE MATERIALIZED VIEW osm_highway_z1 AS
+SELECT id, tags, geom
+FROM (SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 1)) AS geom FROM osm_highway) AS osm_highway
+WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((78270 / power(2, 1)), 2));
diff --git a/map/queries/osm_landuse.sql b/map/queries/osm_landuse.sql
deleted file mode 100644
index 6f63e6ee..00000000
--- a/map/queries/osm_landuse.sql
+++ /dev/null
@@ -1,93 +0,0 @@
-DROP MATERIALIZED VIEW IF EXISTS osm_landuse CASCADE;
-
-CREATE MATERIALIZED VIEW osm_landuse AS
-SELECT id, tags, geom
-FROM osm_polygon
-WHERE tags ?| ARRAY ['landuse']
-UNION ALL
-SELECT id, tags, geom
-FROM osm_relation
-WHERE tags ?| ARRAY ['landuse'];
-
-CREATE MATERIALIZED VIEW osm_landuse_z1 AS
-SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 1)) AS geom
-FROM osm_landuse
-WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((39135 / power(2, 1)), 2));
-
-CREATE MATERIALIZED VIEW osm_landuse_z2 AS
-SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 2)) AS geom
-FROM osm_landuse
-WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((39135 / power(2, 2)), 2));
-
-CREATE MATERIALIZED VIEW osm_landuse_z3 AS
-SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 3)) AS geom
-FROM osm_landuse
-WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((39135 / power(2, 3)), 2));
-
-CREATE MATERIALIZED VIEW osm_landuse_z4 AS
-SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 4)) AS geom
-FROM osm_landuse
-WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((39135 / power(2, 4)), 2));
-
-CREATE MATERIALIZED VIEW osm_landuse_z5 AS
-SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 5)) AS geom
-FROM osm_landuse
-WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((39135 / power(2, 5)), 2));
-
-CREATE MATERIALIZED VIEW osm_landuse_z6 AS
-SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 6)) AS geom
-FROM osm_landuse
-WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((39135 / power(2, 6)), 2));
-
-CREATE MATERIALIZED VIEW osm_landuse_z7 AS
-SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 7)) AS geom
-FROM osm_landuse
-WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((39135 / power(2, 7)), 2));
-
-CREATE MATERIALIZED VIEW osm_landuse_z8 AS
-SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 8)) AS geom
-FROM osm_landuse
-WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((39135 / power(2, 8)), 2));
-
-CREATE MATERIALIZED VIEW osm_landuse_z9 AS
-SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 9)) AS geom
-FROM osm_landuse
-WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((39135 / power(2, 9)), 2));
-
-CREATE MATERIALIZED VIEW osm_landuse_z10 AS
-SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 10)) AS geom
-FROM osm_landuse
-WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((39135 / power(2, 10)), 2));
-
-CREATE MATERIALIZED VIEW osm_landuse_z11 AS
-SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 11)) AS geom
-FROM osm_landuse
-WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((39135 / power(2, 11)), 2));
-
-CREATE MATERIALIZED VIEW osm_landuse_z12 AS
-SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 12)) AS geom
-FROM osm_landuse
-WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((39135 / power(2, 12)), 2));
-
-CREATE VIEW osm_landuse_z13 AS SELECT id, tags, geom FROM osm_landuse;
-CREATE VIEW osm_landuse_z14 AS SELECT id, tags, geom FROM osm_landuse;
-CREATE VIEW osm_landuse_z15 AS SELECT id, tags, geom FROM osm_landuse;
-CREATE VIEW osm_landuse_z16 AS SELECT id, tags, geom FROM osm_landuse;
-CREATE VIEW osm_landuse_z17 AS SELECT id, tags, geom FROM osm_landuse;
-CREATE VIEW osm_landuse_z18 AS SELECT id, tags, geom FROM osm_landuse;
-CREATE VIEW osm_landuse_z19 AS SELECT id, tags, geom FROM osm_landuse;
-CREATE VIEW osm_landuse_z20 AS SELECT id, tags, geom FROM osm_landuse;
-
-CREATE INDEX IF NOT EXISTS osm_landuse_geom_index ON osm_landuse USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_landuse_geom_z1_index ON osm_landuse_z1 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_landuse_geom_z2_index ON osm_landuse_z2 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_landuse_geom_z3_index ON osm_landuse_z3 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_landuse_geom_z4_index ON osm_landuse_z4 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_landuse_geom_z5_index ON osm_landuse_z5 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_landuse_geom_z6_index ON osm_landuse_z6 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_landuse_geom_z7_index ON osm_landuse_z7 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_landuse_geom_z8_index ON osm_landuse_z8 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_landuse_geom_z9_index ON osm_landuse_z9 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_landuse_geom_z10_index ON osm_landuse_z10 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_landuse_geom_z11_index ON osm_landuse_z11 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_landuse_geom_z12_index ON osm_landuse_z12 USING SPGIST (geom);
diff --git a/map/queries/osm_landuse_index.sql b/map/queries/osm_landuse_index.sql
new file mode 100644
index 00000000..b49aafb9
--- /dev/null
+++ b/map/queries/osm_landuse_index.sql
@@ -0,0 +1,12 @@
+CREATE INDEX IF NOT EXISTS osm_landuse_geom_z1_index ON osm_landuse_z1 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_landuse_geom_z2_index ON osm_landuse_z2 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_landuse_geom_z3_index ON osm_landuse_z3 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_landuse_geom_z4_index ON osm_landuse_z4 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_landuse_geom_z5_index ON osm_landuse_z5 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_landuse_geom_z6_index ON osm_landuse_z6 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_landuse_geom_z7_index ON osm_landuse_z7 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_landuse_geom_z8_index ON osm_landuse_z8 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_landuse_geom_z9_index ON osm_landuse_z9 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_landuse_geom_z10_index ON osm_landuse_z10 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_landuse_geom_z11_index ON osm_landuse_z11 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_landuse_geom_z12_index ON osm_landuse_z12 USING SPGIST (geom);
diff --git a/map/queries/osm_landuse_prepare.sql b/map/queries/osm_landuse_prepare.sql
new file mode 100644
index 00000000..4da3675e
--- /dev/null
+++ b/map/queries/osm_landuse_prepare.sql
@@ -0,0 +1,157 @@
+DROP VIEW IF EXISTS osm_landuse CASCADE;
+DROP VIEW IF EXISTS osm_landuse_residential;
+DROP VIEW IF EXISTS osm_landuse_farmland;
+DROP VIEW IF EXISTS osm_landuse_forest;
+DROP VIEW IF EXISTS osm_landuse_meadow;
+DROP VIEW IF EXISTS osm_landuse_orchard;
+DROP VIEW IF EXISTS osm_landuse_vineyard;
+DROP VIEW IF EXISTS osm_landuse_salt_pond;
+DROP VIEW IF EXISTS osm_landuse_water;
+
+CREATE VIEW osm_landuse AS
+SELECT
+    id as id,
+    jsonb_build_object('landuse', tags -> 'landuse') as tags,
+    st_buildarea(st_exteriorring(geom)) as geom
+FROM osm_polygon
+WHERE geom IS NOT NULL AND tags ? 'landuse';
+
+CREATE VIEW osm_landuse_residential AS
+SELECT
+    min(id) as id,
+    jsonb_build_object('landuse', 'residential') as tags,
+    (st_dump(st_union(st_makevalid(geom)))).geom AS geom
+FROM (
+         SELECT
+             id as id,
+             geom as geom,
+             st_clusterdbscan(geom, 0, 1) OVER() AS cluster
+         FROM osm_landuse
+         WHERE tags ->> 'landuse' = 'residential'
+     ) osm_landuse
+GROUP BY cluster;
+
+CREATE VIEW osm_landuse_farmland AS
+SELECT
+    min(id) as id,
+    jsonb_build_object('landuse', 'farmland') as tags,
+    (st_dump(st_union(st_makevalid(geom)))).geom AS geom
+FROM (
+         SELECT
+             id as id,
+             geom as geom,
+             st_clusterdbscan(geom, 0, 1) OVER() AS cluster
+         FROM osm_landuse
+         WHERE tags ->> 'landuse' = 'farmland'
+     ) osm_landuse
+GROUP BY cluster;
+
+CREATE VIEW osm_landuse_forest AS
+SELECT
+    min(id) as id,
+    jsonb_build_object('landuse', 'forest') as tags,
+    (st_dump(st_union(st_makevalid(geom)))).geom AS geom
+FROM (
+         SELECT
+             id as id,
+             geom as geom,
+             st_clusterdbscan(geom, 0, 1) OVER() AS cluster
+         FROM osm_landuse
+         WHERE tags ->> 'landuse' = 'forest'
+     ) osm_landuse
+GROUP BY cluster;
+
+CREATE VIEW osm_landuse_meadow AS
+SELECT
+    min(id) as id,
+    jsonb_build_object('landuse', 'meadow') as tags,
+    (st_dump(st_union(st_makevalid(geom)))).geom AS geom
+FROM (
+         SELECT
+             id as id,
+             geom as geom,
+             st_clusterdbscan(geom, 0, 1) OVER() AS cluster
+         FROM osm_landuse
+         WHERE tags ->> 'landuse' = 'meadow'
+     ) osm_landuse
+GROUP BY cluster;
+
+CREATE VIEW osm_landuse_orchard AS
+SELECT
+    min(id) as id,
+    jsonb_build_object('landuse', 'orchard') as tags,
+    (st_dump(st_union(st_makevalid(geom)))).geom AS geom
+FROM (
+         SELECT
+             id as id,
+             geom as geom,
+             st_clusterdbscan(geom, 0, 1) OVER() AS cluster
+         FROM osm_landuse
+         WHERE tags ->> 'landuse' = 'orchard'
+     ) osm_landuse
+GROUP BY cluster;
+
+CREATE VIEW osm_landuse_vineyard AS
+SELECT
+    min(id) as id,
+    jsonb_build_object('landuse', 'vineyard') as tags,
+    (st_dump(st_union(st_makevalid(geom)))).geom AS geom
+FROM (
+         SELECT
+             id as id,
+             geom as geom,
+             st_clusterdbscan(geom, 0, 1) OVER() AS cluster
+         FROM osm_landuse
+         WHERE tags ->> 'landuse' = 'vineyard'
+     ) osm_landuse
+GROUP BY cluster;
+
+CREATE VIEW osm_landuse_salt_pond AS
+SELECT
+    min(id) as id,
+    jsonb_build_object('landuse', 'salt_pond') as tags,
+    (st_dump(st_union(st_makevalid(geom)))).geom AS geom
+FROM (
+         SELECT
+             id as id,
+             geom as geom,
+             st_clusterdbscan(geom, 0, 1) OVER() AS cluster
+         FROM osm_landuse
+         WHERE tags ->> 'landuse' = 'salt_pond'
+     ) osm_landuse
+GROUP BY cluster;
+
+CREATE VIEW osm_landuse_water AS
+SELECT
+    min(id) as id,
+    jsonb_build_object('landuse', 'water') as tags,
+    (st_dump(st_union(st_makevalid(geom)))).geom AS geom
+FROM (
+         SELECT
+             id as id,
+             geom as geom,
+             st_clusterdbscan(geom, 0, 1) OVER() AS cluster
+         FROM osm_landuse
+         WHERE tags ->> 'landuse' = 'water'
+     ) osm_landuse
+GROUP BY cluster;
+
+CREATE MATERIALIZED VIEW osm_landuse_grouped AS
+SELECT id, tags, geom FROM osm_landuse_residential
+UNION ALL
+SELECT id, tags, geom FROM osm_landuse_farmland
+UNION ALL
+SELECT id, tags, geom FROM osm_landuse_forest
+UNION ALL
+SELECT id, tags, geom FROM osm_landuse_meadow
+UNION ALL
+SELECT id, tags, geom FROM osm_landuse_orchard
+UNION ALL
+SELECT id, tags, geom FROM osm_landuse_vineyard
+UNION ALL
+SELECT id, tags, geom FROM osm_landuse_salt_pond
+UNION ALL
+SELECT id, tags, geom FROM osm_landuse_water;
+
+CREATE INDEX osm_landuse_grouped_geom_idx ON osm_landuse_grouped USING GIST (geom);
+
diff --git a/map/queries/osm_landuse_simplify.sql b/map/queries/osm_landuse_simplify.sql
new file mode 100644
index 00000000..1c4debaa
--- /dev/null
+++ b/map/queries/osm_landuse_simplify.sql
@@ -0,0 +1,83 @@
+CREATE VIEW osm_landuse_z20 AS
+SELECT id, tags, geom FROM osm_landuse;
+
+CREATE VIEW osm_landuse_z19 AS
+SELECT id, tags, geom FROM osm_landuse;
+
+CREATE VIEW osm_landuse_z18 AS
+SELECT id, tags, geom FROM osm_landuse;
+
+CREATE VIEW osm_landuse_z17 AS
+SELECT id, tags, geom FROM osm_landuse;
+
+CREATE VIEW osm_landuse_z16 AS
+SELECT id, tags, geom FROM osm_landuse;
+
+CREATE VIEW osm_landuse_z15 AS
+SELECT id, tags, geom FROM osm_landuse;
+
+CREATE VIEW osm_landuse_z14 AS
+SELECT id, tags, geom FROM osm_landuse;
+
+CREATE VIEW osm_landuse_z13 AS
+SELECT id, tags, geom FROM osm_landuse;
+
+CREATE MATERIALIZED VIEW osm_landuse_z12 AS
+SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 12)) AS geom
+FROM osm_landuse_grouped
+WHERE st_area(st_envelope(geom)) > 10 * power(78270 / power(2, 12), 2);
+
+CREATE MATERIALIZED VIEW osm_landuse_z11 AS
+SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 11)) AS geom
+FROM osm_landuse_grouped
+WHERE st_area(st_envelope(geom)) > 10 * power(78270 / power(2, 11), 2);
+
+CREATE MATERIALIZED VIEW osm_landuse_z10 AS
+SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 10)) AS geom
+FROM osm_landuse_grouped
+WHERE st_area(st_envelope(geom)) > 10 * power(78270 / power(2, 10), 2);
+
+CREATE MATERIALIZED VIEW osm_landuse_z9 AS
+SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 9)) AS geom
+FROM osm_landuse_grouped
+WHERE st_area(st_envelope(geom)) > 10 * power(78270 / power(2, 9), 2);
+
+CREATE MATERIALIZED VIEW osm_landuse_z8 AS
+SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 8)) AS geom
+FROM osm_landuse_grouped
+WHERE st_area(st_envelope(geom)) > 10 * power(78270 / power(2, 8), 2);
+
+CREATE MATERIALIZED VIEW osm_landuse_z7 AS
+SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 7)) AS geom
+FROM osm_landuse_grouped
+WHERE st_area(st_envelope(geom)) > 10 * power(78270 / power(2, 7), 2);
+
+CREATE MATERIALIZED VIEW osm_landuse_z6 AS
+SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 6)) AS geom
+FROM osm_landuse_grouped
+WHERE st_area(st_envelope(geom)) > 10 * power(78270 / power(2, 6), 2);
+
+CREATE MATERIALIZED VIEW osm_landuse_z5 AS
+SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 5)) AS geom
+FROM osm_landuse_grouped
+WHERE st_area(st_envelope(geom)) > 10 * power(78270 / power(2, 5), 2);
+
+CREATE MATERIALIZED VIEW osm_landuse_z4 AS
+SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 4)) AS geom
+FROM osm_landuse_grouped
+WHERE st_area(st_envelope(geom)) > 10 * power(78270 / power(2, 4), 2);
+
+CREATE MATERIALIZED VIEW osm_landuse_z3 AS
+SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 3)) AS geom
+FROM osm_landuse_grouped
+WHERE st_area(st_envelope(geom)) > 10 * power(78270 / power(2, 3), 2);
+
+CREATE MATERIALIZED VIEW osm_landuse_z2 AS
+SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 2)) AS geom
+FROM osm_landuse_grouped
+WHERE st_area(st_envelope(geom)) > 10 * power(78270 / power(2, 2), 2);
+
+CREATE MATERIALIZED VIEW osm_landuse_z1 AS
+SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 1)) AS geom
+FROM osm_landuse_grouped
+WHERE st_area(st_envelope(geom)) > 10 * power(78270 / power(2, 1), 2);
diff --git a/map/queries/osm_linestring.sql b/map/queries/osm_linestring.sql
index 19ebaff4..5ce38638 100644
--- a/map/queries/osm_linestring.sql
+++ b/map/queries/osm_linestring.sql
@@ -3,7 +3,7 @@ DROP VIEW IF EXISTS osm_linestring CASCADE;
 CREATE VIEW osm_linestring AS
 SELECT id, tags, geom
 FROM osm_ways
-LEFT JOIN osm_way_member ON id = way_id
+LEFT JOIN osm_ways_member ON id = way_id
 WHERE ST_GeometryType(osm_ways.geom) = 'ST_LineString'
   AND tags != '{}'
   AND way_id IS NULL;
diff --git a/map/queries/osm_natural.sql b/map/queries/osm_natural.sql
deleted file mode 100644
index d5059e3d..00000000
--- a/map/queries/osm_natural.sql
+++ /dev/null
@@ -1,93 +0,0 @@
-DROP MATERIALIZED VIEW IF EXISTS osm_natural CASCADE;
-
-CREATE MATERIALIZED VIEW osm_natural AS
-SELECT id, tags, geom
-FROM osm_polygon
-WHERE tags ?| ARRAY ['natural']
-UNION ALL
-SELECT id, tags, geom
-FROM osm_relation
-WHERE tags ?| ARRAY ['natural'];
-
-CREATE MATERIALIZED VIEW osm_natural_z1 AS
-SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 1)) AS geom
-FROM osm_natural
-WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((39135 / power(2, 1)), 2));
-
-CREATE MATERIALIZED VIEW osm_natural_z2 AS
-SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 2)) AS geom
-FROM osm_natural
-WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((39135 / power(2, 2)), 2));
-
-CREATE MATERIALIZED VIEW osm_natural_z3 AS
-SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 3)) AS geom
-FROM osm_natural
-WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((39135 / power(2, 3)), 2));
-
-CREATE MATERIALIZED VIEW osm_natural_z4 AS
-SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 4)) AS geom
-FROM osm_natural
-WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((39135 / power(2, 4)), 2));
-
-CREATE MATERIALIZED VIEW osm_natural_z5 AS
-SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 5)) AS geom
-FROM osm_natural
-WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((39135 / power(2, 5)), 2));
-
-CREATE MATERIALIZED VIEW osm_natural_z6 AS
-SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 6)) AS geom
-FROM osm_natural
-WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((39135 / power(2, 6)), 2));
-
-CREATE MATERIALIZED VIEW osm_natural_z7 AS
-SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 7)) AS geom
-FROM osm_natural
-WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((39135 / power(2, 7)), 2));
-
-CREATE MATERIALIZED VIEW osm_natural_z8 AS
-SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 8)) AS geom
-FROM osm_natural
-WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((39135 / power(2, 8)), 2));
-
-CREATE MATERIALIZED VIEW osm_natural_z9 AS
-SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 9)) AS geom
-FROM osm_natural
-WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((39135 / power(2, 9)), 2));
-
-CREATE MATERIALIZED VIEW osm_natural_z10 AS
-SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 10)) AS geom
-FROM osm_natural
-WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((39135 / power(2, 10)), 2));
-
-CREATE MATERIALIZED VIEW osm_natural_z11 AS
-SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 11)) AS geom
-FROM osm_natural
-WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((39135 / power(2, 11)), 2));
-
-CREATE MATERIALIZED VIEW osm_natural_z12 AS
-SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 12)) AS geom
-FROM osm_natural
-WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((39135 / power(2, 12)), 2));
-
-CREATE VIEW osm_natural_z13 AS SELECT id, tags, geom FROM osm_natural;
-CREATE VIEW osm_natural_z14 AS SELECT id, tags, geom FROM osm_natural;
-CREATE VIEW osm_natural_z15 AS SELECT id, tags, geom FROM osm_natural;
-CREATE VIEW osm_natural_z16 AS SELECT id, tags, geom FROM osm_natural;
-CREATE VIEW osm_natural_z17 AS SELECT id, tags, geom FROM osm_natural;
-CREATE VIEW osm_natural_z18 AS SELECT id, tags, geom FROM osm_natural;
-CREATE VIEW osm_natural_z19 AS SELECT id, tags, geom FROM osm_natural;
-CREATE VIEW osm_natural_z20 AS SELECT id, tags, geom FROM osm_natural;
-
-CREATE INDEX IF NOT EXISTS osm_natural_geom_index ON osm_natural USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_natural_geom_z1_index ON osm_natural_z1 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_natural_geom_z2_index ON osm_natural_z2 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_natural_geom_z3_index ON osm_natural_z3 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_natural_geom_z4_index ON osm_natural_z4 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_natural_geom_z5_index ON osm_natural_z5 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_natural_geom_z6_index ON osm_natural_z6 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_natural_geom_z7_index ON osm_natural_z7 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_natural_geom_z8_index ON osm_natural_z8 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_natural_geom_z9_index ON osm_natural_z9 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_natural_geom_z10_index ON osm_natural_z10 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_natural_geom_z11_index ON osm_natural_z11 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_natural_geom_z12_index ON osm_natural_z12 USING SPGIST (geom);
diff --git a/map/queries/osm_natural_index.sql b/map/queries/osm_natural_index.sql
new file mode 100644
index 00000000..84779b17
--- /dev/null
+++ b/map/queries/osm_natural_index.sql
@@ -0,0 +1,12 @@
+CREATE INDEX IF NOT EXISTS osm_natural_geom_z12_index ON osm_natural_z12 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_natural_geom_z11_index ON osm_natural_z11 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_natural_geom_z10_index ON osm_natural_z10 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_natural_geom_z9_index ON osm_natural_z9 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_natural_geom_z8_index ON osm_natural_z8 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_natural_geom_z7_index ON osm_natural_z7 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_natural_geom_z6_index ON osm_natural_z6 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_natural_geom_z5_index ON osm_natural_z5 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_natural_geom_z4_index ON osm_natural_z4 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_natural_geom_z3_index ON osm_natural_z3 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_natural_geom_z2_index ON osm_natural_z2 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_natural_geom_z1_index ON osm_natural_z1 USING SPGIST (geom);
diff --git a/map/queries/osm_natural_prepare.sql b/map/queries/osm_natural_prepare.sql
new file mode 100644
index 00000000..3fad2d28
--- /dev/null
+++ b/map/queries/osm_natural_prepare.sql
@@ -0,0 +1,303 @@
+-- ('grassland', 'heath', 'scrub', 'wood', 'bay', 'beach', 'glacier', 'mud', 'shingle', 'shoal', 'strait', 'water', 'wetland', 'bare_rock', 'sand', 'scree');
+DROP VIEW IF EXISTS osm_natural CASCADE;
+
+DROP VIEW IF EXISTS osm_natural_mud;
+DROP VIEW IF EXISTS osm_natural_grassland;
+DROP VIEW IF EXISTS osm_natural_heath;
+DROP VIEW IF EXISTS osm_natural_scrub;
+DROP VIEW IF EXISTS osm_natural_wood;
+DROP VIEW IF EXISTS osm_natural_bay;
+DROP VIEW IF EXISTS osm_natural_beach;
+DROP VIEW IF EXISTS osm_natural_glacier;
+DROP VIEW IF EXISTS osm_natural_mud;
+DROP VIEW IF EXISTS osm_natural_shingle;
+DROP VIEW IF EXISTS osm_natural_shoal;
+DROP VIEW IF EXISTS osm_natural_strait;
+DROP VIEW IF EXISTS osm_natural_water;
+DROP VIEW IF EXISTS osm_natural_wetland;
+DROP VIEW IF EXISTS osm_natural_bare_rock;
+DROP VIEW IF EXISTS osm_natural_sand;
+DROP VIEW IF EXISTS osm_natural_scree;
+
+CREATE VIEW osm_natural AS
+SELECT
+    id as id,
+    jsonb_build_object('natural', tags -> 'natural') as tags,
+    st_buildarea(st_exteriorring(geom)) as geom
+FROM osm_polygon
+WHERE geom IS NOT NULL AND tags ? 'natural';
+
+CREATE VIEW osm_natural_grassland AS
+SELECT
+    min(id) as id,
+    jsonb_build_object('natural', 'grassland') as tags,
+    (st_dump(st_union(st_makevalid(geom)))).geom AS geom
+FROM (
+         SELECT
+             id as id,
+             geom as geom,
+             st_clusterdbscan(geom, 0, 1) OVER() AS cluster
+         FROM osm_natural
+         WHERE tags ->> 'natural' = 'grassland'
+     ) osm_natural
+GROUP BY cluster;
+
+CREATE VIEW osm_natural_heath AS
+SELECT
+    min(id) as id,
+    jsonb_build_object('natural', 'heath') as tags,
+    (st_dump(st_union(st_makevalid(geom)))).geom AS geom
+FROM (
+         SELECT
+             id as id,
+             geom as geom,
+             st_clusterdbscan(geom, 0, 1) OVER() AS cluster
+         FROM osm_natural
+         WHERE tags ->> 'natural' = 'heath'
+     ) osm_natural
+GROUP BY cluster;
+
+CREATE VIEW osm_natural_scrub AS
+SELECT
+    min(id) as id,
+    jsonb_build_object('natural', 'scrub') as tags,
+    (st_dump(st_union(st_makevalid(geom)))).geom AS geom
+FROM (
+         SELECT
+             id as id,
+             geom as geom,
+             st_clusterdbscan(geom, 0, 1) OVER() AS cluster
+         FROM osm_natural
+         WHERE tags ->> 'natural' = 'scrub'
+     ) osm_natural
+GROUP BY cluster;
+
+CREATE VIEW osm_natural_wood AS
+SELECT
+    min(id) as id,
+    jsonb_build_object('natural', 'wood') as tags,
+    (st_dump(st_union(st_makevalid(geom)))).geom AS geom
+FROM (
+         SELECT
+             id as id,
+             geom as geom,
+             st_clusterdbscan(geom, 0, 1) OVER() AS cluster
+         FROM osm_natural
+         WHERE tags ->> 'natural' = 'wood'
+     ) osm_natural
+GROUP BY cluster;
+
+CREATE VIEW osm_natural_bay AS
+SELECT
+    min(id) as id,
+    jsonb_build_object('natural', 'bay') as tags,
+    (st_dump(st_union(st_makevalid(geom)))).geom AS geom
+FROM (
+         SELECT
+             id as id,
+             geom as geom,
+             st_clusterdbscan(geom, 0, 1) OVER() AS cluster
+         FROM osm_natural
+         WHERE tags ->> 'natural' = 'bay'
+     ) osm_natural
+GROUP BY cluster;
+
+CREATE VIEW osm_natural_beach AS
+SELECT
+    min(id) as id,
+    jsonb_build_object('natural', 'beach') as tags,
+    (st_dump(st_union(st_makevalid(geom)))).geom AS geom
+FROM (
+         SELECT
+             id as id,
+             geom as geom,
+             st_clusterdbscan(geom, 0, 1) OVER() AS cluster
+         FROM osm_natural
+         WHERE tags ->> 'natural' = 'beach'
+     ) osm_natural
+GROUP BY cluster;
+
+CREATE VIEW osm_natural_glacier AS
+SELECT
+    min(id) as id,
+    jsonb_build_object('natural', 'glacier') as tags,
+    (st_dump(st_union(st_makevalid(geom)))).geom AS geom
+FROM (
+         SELECT
+             id as id,
+             geom as geom,
+             st_clusterdbscan(geom, 0, 1) OVER() AS cluster
+         FROM osm_natural
+         WHERE tags ->> 'natural' = 'glacier'
+     ) osm_natural
+GROUP BY cluster;
+
+CREATE VIEW osm_natural_mud AS
+SELECT
+    min(id) as id,
+    jsonb_build_object('natural', 'mud') as tags,
+    (st_dump(st_union(st_makevalid(geom)))).geom AS geom
+FROM (
+         SELECT
+             id as id,
+             geom as geom,
+             st_clusterdbscan(geom, 0, 1) OVER() AS cluster
+         FROM osm_natural
+         WHERE tags ->> 'natural' = 'mud'
+     ) osm_natural
+GROUP BY cluster;
+
+CREATE VIEW osm_natural_shingle AS
+SELECT
+    min(id) as id,
+    jsonb_build_object('natural', 'shingle') as tags,
+    (st_dump(st_union(st_makevalid(geom)))).geom AS geom
+FROM (
+         SELECT
+             id as id,
+             geom as geom,
+             st_clusterdbscan(geom, 0, 1) OVER() AS cluster
+         FROM osm_natural
+         WHERE tags ->> 'natural' = 'shingle'
+     ) osm_natural
+GROUP BY cluster;
+
+CREATE VIEW osm_natural_shoal AS
+SELECT
+    min(id) as id,
+    jsonb_build_object('natural', 'shoal') as tags,
+    (st_dump(st_union(st_makevalid(geom)))).geom AS geom
+FROM (
+         SELECT
+             id as id,
+             geom as geom,
+             st_clusterdbscan(geom, 0, 1) OVER() AS cluster
+         FROM osm_natural
+         WHERE tags ->> 'natural' = 'shoal'
+     ) osm_natural
+GROUP BY cluster;
+
+CREATE VIEW osm_natural_strait AS
+SELECT
+    min(id) as id,
+    jsonb_build_object('natural', 'strait') as tags,
+    (st_dump(st_union(st_makevalid(geom)))).geom AS geom
+FROM (
+         SELECT
+             id as id,
+             geom as geom,
+             st_clusterdbscan(geom, 0, 1) OVER() AS cluster
+         FROM osm_natural
+         WHERE tags ->> 'natural' = 'strait'
+     ) osm_natural
+GROUP BY cluster;
+
+CREATE VIEW osm_natural_water AS
+SELECT
+    min(id) as id,
+    jsonb_build_object('natural', 'water') as tags,
+    (st_dump(st_union(st_makevalid(geom)))).geom AS geom
+FROM (
+         SELECT
+             id as id,
+             geom as geom,
+             st_clusterdbscan(geom, 0, 1) OVER() AS cluster
+         FROM osm_natural
+         WHERE tags ->> 'natural' = 'water'
+     ) osm_natural
+GROUP BY cluster;
+
+CREATE VIEW osm_natural_wetland AS
+SELECT
+    min(id) as id,
+    jsonb_build_object('natural', 'wetland') as tags,
+    (st_dump(st_union(st_makevalid(geom)))).geom AS geom
+FROM (
+         SELECT
+             id as id,
+             geom as geom,
+             st_clusterdbscan(geom, 0, 1) OVER() AS cluster
+         FROM osm_natural
+         WHERE tags ->> 'natural' = 'wetland'
+     ) osm_natural
+GROUP BY cluster;
+
+CREATE VIEW osm_natural_bare_rock AS
+SELECT
+    min(id) as id,
+    jsonb_build_object('natural', 'bare_rock') as tags,
+    (st_dump(st_union(st_makevalid(geom)))).geom AS geom
+FROM (
+         SELECT
+             id as id,
+             geom as geom,
+             st_clusterdbscan(geom, 0, 1) OVER() AS cluster
+         FROM osm_natural
+         WHERE tags ->> 'natural' = 'bare_rock'
+     ) osm_natural
+GROUP BY cluster;
+
+CREATE VIEW osm_natural_sand AS
+SELECT
+    min(id) as id,
+    jsonb_build_object('natural', 'sand') as tags,
+    (st_dump(st_union(st_makevalid(geom)))).geom AS geom
+FROM (
+         SELECT
+             id as id,
+             geom as geom,
+             st_clusterdbscan(geom, 0, 1) OVER() AS cluster
+         FROM osm_natural
+         WHERE tags ->> 'natural' = 'sand'
+     ) osm_natural
+GROUP BY cluster;
+
+CREATE VIEW osm_natural_scree AS
+SELECT
+    min(id) as id,
+    jsonb_build_object('natural', 'scree') as tags,
+    (st_dump(st_union(st_makevalid(geom)))).geom AS geom
+FROM (
+         SELECT
+             id as id,
+             geom as geom,
+             st_clusterdbscan(geom, 0, 1) OVER() AS cluster
+         FROM osm_natural
+         WHERE tags ->> 'natural' = 'scree'
+     ) osm_natural
+GROUP BY cluster;
+
+CREATE MATERIALIZED VIEW osm_natural_grouped AS
+SELECT id, tags, geom FROM osm_natural_grassland
+UNION ALL
+SELECT id, tags, geom FROM osm_natural_heath
+UNION ALL
+SELECT id, tags, geom FROM osm_natural_scrub
+UNION ALL
+SELECT id, tags, geom FROM osm_natural_wood
+UNION ALL
+SELECT id, tags, geom FROM osm_natural_bay
+UNION ALL
+SELECT id, tags, geom FROM osm_natural_beach
+UNION ALL
+SELECT id, tags, geom FROM osm_natural_glacier
+UNION ALL
+SELECT id, tags, geom FROM osm_natural_mud
+UNION ALL
+SELECT id, tags, geom FROM osm_natural_shingle
+UNION ALL
+SELECT id, tags, geom FROM osm_natural_shoal
+UNION ALL
+SELECT id, tags, geom FROM osm_natural_strait
+UNION ALL
+SELECT id, tags, geom FROM osm_natural_water
+UNION ALL
+SELECT id, tags, geom FROM osm_natural_wetland
+UNION ALL
+SELECT id, tags, geom FROM osm_natural_bare_rock
+UNION ALL
+SELECT id, tags, geom FROM osm_natural_sand
+UNION ALL
+SELECT id, tags, geom FROM osm_natural_scree;
+
+
diff --git a/map/queries/osm_natural_simplify.sql b/map/queries/osm_natural_simplify.sql
new file mode 100644
index 00000000..cf0c1bbc
--- /dev/null
+++ b/map/queries/osm_natural_simplify.sql
@@ -0,0 +1,95 @@
+CREATE VIEW osm_natural_z20 AS
+SELECT id, tags, geom FROM osm_natural;
+
+CREATE VIEW osm_natural_z19 AS
+SELECT id, tags, geom FROM osm_natural;
+
+CREATE VIEW osm_natural_z18 AS
+SELECT id, tags, geom FROM osm_natural;
+
+CREATE VIEW osm_natural_z17 AS
+SELECT id, tags, geom FROM osm_natural;
+
+CREATE VIEW osm_natural_z16 AS
+SELECT id, tags, geom FROM osm_natural;
+
+CREATE VIEW osm_natural_z15 AS
+SELECT id, tags, geom FROM osm_natural;
+
+CREATE VIEW osm_natural_z14 AS
+SELECT id, tags, geom FROM osm_natural;
+
+CREATE VIEW osm_natural_z13 AS
+SELECT id, tags, geom FROM osm_natural;
+
+DROP MATERIALIZED VIEW IF EXISTS osm_natural_z12 CASCADE;
+CREATE MATERIALIZED VIEW osm_natural_z12 AS
+SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 12)) AS geom
+FROM osm_natural_grouped
+WHERE st_area(st_envelope(geom)) > 10 * power(78270 / power(2, 12), 2);
+
+DROP MATERIALIZED VIEW IF EXISTS osm_natural_z11 CASCADE;
+CREATE MATERIALIZED VIEW osm_natural_z11 AS
+SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 11)) AS geom
+FROM osm_natural_grouped
+WHERE st_area(st_envelope(geom)) > 10 * power(78270 / power(2, 11), 2);
+
+DROP MATERIALIZED VIEW IF EXISTS osm_natural_z10 CASCADE;
+CREATE MATERIALIZED VIEW osm_natural_z10 AS
+SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 10)) AS geom
+FROM osm_natural_grouped
+WHERE st_area(st_envelope(geom)) > 10 * power(78270 / power(2, 10), 2);
+
+DROP MATERIALIZED VIEW IF EXISTS osm_natural_z9 CASCADE;
+CREATE MATERIALIZED VIEW osm_natural_z9 AS
+SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 9)) AS geom
+FROM osm_natural_grouped
+WHERE st_area(st_envelope(geom)) > 10 * power(78270 / power(2, 9), 2);
+
+DROP MATERIALIZED VIEW IF EXISTS osm_natural_z8 CASCADE;
+CREATE MATERIALIZED VIEW osm_natural_z8 AS
+SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 8)) AS geom
+FROM osm_natural_grouped
+WHERE st_area(st_envelope(geom)) > 10 * power(78270 / power(2, 8), 2);
+
+DROP MATERIALIZED VIEW IF EXISTS osm_natural_z7 CASCADE;
+CREATE MATERIALIZED VIEW osm_natural_z7 AS
+SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 7)) AS geom
+FROM osm_natural_grouped
+WHERE st_area(st_envelope(geom)) > 10 * power(78270 / power(2, 7), 2);
+
+DROP MATERIALIZED VIEW IF EXISTS osm_natural_z6 CASCADE;
+CREATE MATERIALIZED VIEW osm_natural_z6 AS
+SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 6)) AS geom
+FROM osm_natural_grouped
+WHERE st_area(st_envelope(geom)) > 10 * power(78270 / power(2, 6), 2);
+
+DROP MATERIALIZED VIEW IF EXISTS osm_natural_z5 CASCADE;
+CREATE MATERIALIZED VIEW osm_natural_z5 AS
+SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 5)) AS geom
+FROM osm_natural_grouped
+WHERE st_area(st_envelope(geom)) > 10 * power(78270 / power(2, 5), 2);
+
+DROP MATERIALIZED VIEW IF EXISTS osm_natural_z4 CASCADE;
+CREATE MATERIALIZED VIEW osm_natural_z4 AS
+SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 4)) AS geom
+FROM osm_natural_grouped
+WHERE st_area(st_envelope(geom)) > 10 * power(78270 / power(2, 4), 2);
+
+DROP MATERIALIZED VIEW IF EXISTS osm_natural_z3 CASCADE;
+CREATE MATERIALIZED VIEW osm_natural_z3 AS
+SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 3)) AS geom
+FROM osm_natural_grouped
+WHERE st_area(st_envelope(geom)) > 10 * power(78270 / power(2, 3), 2);
+
+DROP MATERIALIZED VIEW IF EXISTS osm_natural_z2 CASCADE;
+CREATE MATERIALIZED VIEW osm_natural_z2 AS
+SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 2)) AS geom
+FROM osm_natural_grouped
+WHERE st_area(st_envelope(geom)) > 10 * power(78270 / power(2, 2), 2);
+
+DROP MATERIALIZED VIEW IF EXISTS osm_natural_z1 CASCADE;
+CREATE MATERIALIZED VIEW osm_natural_z1 AS
+SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 1)) AS geom
+FROM osm_natural_grouped
+WHERE st_area(st_envelope(geom)) > 10 * power(78270 / power(2, 1), 2);
diff --git a/map/queries/osm_node.sql b/map/queries/osm_node.sql
deleted file mode 100644
index 96066689..00000000
--- a/map/queries/osm_node.sql
+++ /dev/null
@@ -1,73 +0,0 @@
-DROP VIEW IF EXISTS osm_node CASCADE;
-
-CREATE VIEW osm_node AS SELECT * FROM osm_nodes;
-
-DROP INDEX IF EXISTS osm_node_tags_index;
-DROP INDEX IF EXISTS osm_node_geom_index;
-
-CREATE INDEX osm_node_tags_index ON osm_nodes USING gin (tags);
-CREATE INDEX osm_node_geom_index ON osm_nodes USING spgist (geom);
-
-CREATE MATERIALIZED VIEW osm_node_z1 AS
-SELECT id, tags, geom FROM osm_node WHERE tags != '{}' AND tags ->> 'place' IN ('country');
-
-CREATE MATERIALIZED VIEW osm_node_z2 AS
-SELECT id, tags, geom FROM osm_node WHERE tags != '{}' AND tags ->> 'place' IN ('country');
-
-CREATE MATERIALIZED VIEW osm_node_z3 AS
-SELECT id, tags, geom FROM osm_node WHERE tags != '{}' AND tags ->> 'place' IN ('country', 'city', 'sea');
-
-CREATE MATERIALIZED VIEW osm_node_z4 AS
-SELECT id, tags, geom FROM osm_node WHERE tags != '{}' AND tags ->> 'place' IN ('country', 'city', 'sea');
-
-CREATE MATERIALIZED VIEW osm_node_z5 AS
-SELECT id, tags, geom FROM osm_node WHERE tags != '{}' AND tags ->> 'place' IN ('country', 'city', 'sea', 'state', 'county');
-
-CREATE MATERIALIZED VIEW osm_node_z6 AS
-SELECT id, tags, geom FROM osm_node WHERE tags != '{}' AND tags ->> 'place' IN ('country', 'city', 'sea', 'state', 'county');
-
-CREATE MATERIALIZED VIEW osm_node_z7 AS
-SELECT id, tags, geom FROM osm_node WHERE tags != '{}' AND tags ->> 'place' IN ('country', 'city', 'sea', 'state', 'county');
-
-CREATE MATERIALIZED VIEW osm_node_z8 AS
-SELECT id, tags, geom FROM osm_node WHERE tags != '{}' AND tags ->> 'place' IN ('country', 'state', 'region', 'province', 'district', 'county', 'municipality', 'city', 'town');
-
-CREATE MATERIALIZED VIEW osm_node_z9 AS
-SELECT id, tags, geom FROM osm_node WHERE tags != '{}' AND tags ->> 'place' IN ('country', 'state', 'region', 'province', 'district', 'county', 'municipality', 'city', 'town');
-
-CREATE MATERIALIZED VIEW osm_node_z10 AS
-SELECT id, tags, geom FROM osm_node WHERE tags != '{}' AND (tags ->> 'place' IN ('country', 'state', 'region', 'province', 'district', 'county', 'municipality', 'city', 'town')) OR (tags ->> 'natural' IN ('peak', 'volcano')) OR (tags ->> 'highway' IN ('motorway_junction'));
-
-CREATE MATERIALIZED VIEW osm_node_z11 AS
-SELECT id, tags, geom FROM osm_node WHERE tags != '{}' AND (tags ->> 'place' IN ('country', 'state', 'region', 'province', 'district', 'county', 'municipality', 'city', 'town', 'village')) OR (tags ->> 'natural' IN ('peak', 'volcano')) OR (tags ->> 'highway' IN ('motorway_junction'));
-
-CREATE MATERIALIZED VIEW osm_node_z12 AS
-SELECT id, tags, geom FROM osm_node WHERE tags != '{}' AND (tags ->> 'place' IN ('region', 'province', 'district', 'county', 'municipality', 'city', 'town', 'village')) OR (tags ->> 'natural' IN ('peak', 'volcano')) OR (tags ->> 'highway' IN ('motorway_junction')) OR (tags ->> 'tourism' IN ('wilderness_hut')) OR (tags ->> 'waterway' IN ('waterfall'));
-
-CREATE MATERIALIZED VIEW osm_node_z13 AS
-SELECT id, tags, geom FROM osm_node WHERE tags != '{}' AND (tags ->> 'place' IN ('region', 'province', 'district', 'county', 'municipality', 'city', 'town', 'village', 'quarter', 'hamlet')) OR (tags ->> 'natural' IN ('peak', 'volcano')) OR (tags ->> 'highway' IN ('motorway_junction')) OR (tags ->> 'tourism' IN ('wilderness_hut')) OR (tags ->> 'waterway' IN ('waterfall')) OR (tags ->> 'natural' IN ('spring')) OR (tags ->> 'railway' IN ('level_crossing'));
-
-CREATE MATERIALIZED VIEW osm_node_z14 AS
-SELECT id, tags, geom FROM osm_node WHERE tags != '{}';
-
-CREATE VIEW osm_node_z15 AS SELECT id, tags, geom FROM osm_node_z14;
-CREATE VIEW osm_node_z16 AS SELECT id, tags, geom FROM osm_node_z14;
-CREATE VIEW osm_node_z17 AS SELECT id, tags, geom FROM osm_node_z14;
-CREATE VIEW osm_node_z18 AS SELECT id, tags, geom FROM osm_node_z14;
-CREATE VIEW osm_node_z19 AS SELECT id, tags, geom FROM osm_node_z14;
-CREATE VIEW osm_node_z20 AS SELECT id, tags, geom FROM osm_node_z14;
-
-CREATE INDEX IF NOT EXISTS osm_node_geom_z1_index ON osm_node_z1 USING gist (geom);
-CREATE INDEX IF NOT EXISTS osm_node_geom_z2_index ON osm_node_z2 USING gist (geom);
-CREATE INDEX IF NOT EXISTS osm_node_geom_z3_index ON osm_node_z3 USING gist (geom);
-CREATE INDEX IF NOT EXISTS osm_node_geom_z4_index ON osm_node_z4 USING gist (geom);
-CREATE INDEX IF NOT EXISTS osm_node_geom_z5_index ON osm_node_z5 USING gist (geom);
-CREATE INDEX IF NOT EXISTS osm_node_geom_z6_index ON osm_node_z6 USING gist (geom);
-CREATE INDEX IF NOT EXISTS osm_node_geom_z7_index ON osm_node_z7 USING gist (geom);
-CREATE INDEX IF NOT EXISTS osm_node_geom_z8_index ON osm_node_z8 USING gist (geom);
-CREATE INDEX IF NOT EXISTS osm_node_geom_z9_index ON osm_node_z9 USING gist (geom);
-CREATE INDEX IF NOT EXISTS osm_node_geom_z10_index ON osm_node_z10 USING gist (geom);
-CREATE INDEX IF NOT EXISTS osm_node_geom_z11_index ON osm_node_z11 USING gist (geom);
-CREATE INDEX IF NOT EXISTS osm_node_geom_z12_index ON osm_node_z12 USING gist (geom);
-CREATE INDEX IF NOT EXISTS osm_node_geom_z13_index ON osm_node_z13 USING gist (geom);
-CREATE INDEX IF NOT EXISTS osm_node_geom_z14_index ON osm_node_z14 USING gist (geom);
diff --git a/map/queries/osm_nodes_clean.sql b/map/queries/osm_nodes_clean.sql
new file mode 100644
index 00000000..6fc26ca3
--- /dev/null
+++ b/map/queries/osm_nodes_clean.sql
@@ -0,0 +1,24 @@
+DROP INDEX IF EXISTS osm_nodes_tags_index;
+DROP INDEX IF EXISTS osm_nodes_geom_index;
+
+DROP VIEW IF EXISTS osm_nodes_z20 CASCADE;
+DROP VIEW IF EXISTS osm_nodes_z19 CASCADE;
+DROP VIEW IF EXISTS osm_nodes_z18 CASCADE;
+DROP VIEW IF EXISTS osm_nodes_z17 CASCADE;
+DROP VIEW IF EXISTS osm_nodes_z16 CASCADE;
+DROP VIEW IF EXISTS osm_nodes_z15 CASCADE;
+DROP VIEW IF EXISTS osm_nodes_z14 CASCADE;
+
+DROP MATERIALIZED VIEW IF EXISTS osm_nodes_z13 CASCADE;
+DROP MATERIALIZED VIEW IF EXISTS osm_nodes_z12 CASCADE;
+DROP MATERIALIZED VIEW IF EXISTS osm_nodes_z11 CASCADE;
+DROP MATERIALIZED VIEW IF EXISTS osm_nodes_z10 CASCADE;
+DROP MATERIALIZED VIEW IF EXISTS osm_nodes_z9 CASCADE;
+DROP MATERIALIZED VIEW IF EXISTS osm_nodes_z8 CASCADE;
+DROP MATERIALIZED VIEW IF EXISTS osm_nodes_z7 CASCADE;
+DROP MATERIALIZED VIEW IF EXISTS osm_nodes_z6 CASCADE;
+DROP MATERIALIZED VIEW IF EXISTS osm_nodes_z5 CASCADE;
+DROP MATERIALIZED VIEW IF EXISTS osm_nodes_z4 CASCADE;
+DROP MATERIALIZED VIEW IF EXISTS osm_nodes_z3 CASCADE;
+DROP MATERIALIZED VIEW IF EXISTS osm_nodes_z2 CASCADE;
+DROP MATERIALIZED VIEW IF EXISTS osm_nodes_z1 CASCADE;
diff --git a/map/queries/osm_nodes_index.sql b/map/queries/osm_nodes_index.sql
new file mode 100644
index 00000000..4a9c9fe0
--- /dev/null
+++ b/map/queries/osm_nodes_index.sql
@@ -0,0 +1,13 @@
+CREATE INDEX IF NOT EXISTS osm_nodes_geom_z13_index ON osm_nodes_z13 USING gist (geom);
+CREATE INDEX IF NOT EXISTS osm_nodes_geom_z12_index ON osm_nodes_z12 USING gist (geom);
+CREATE INDEX IF NOT EXISTS osm_nodes_geom_z11_index ON osm_nodes_z11 USING gist (geom);
+CREATE INDEX IF NOT EXISTS osm_nodes_geom_z10_index ON osm_nodes_z10 USING gist (geom);
+CREATE INDEX IF NOT EXISTS osm_nodes_geom_z9_index ON osm_nodes_z9 USING gist (geom);
+CREATE INDEX IF NOT EXISTS osm_nodes_geom_z8_index ON osm_nodes_z8 USING gist (geom);
+CREATE INDEX IF NOT EXISTS osm_nodes_geom_z7_index ON osm_nodes_z7 USING gist (geom);
+CREATE INDEX IF NOT EXISTS osm_nodes_geom_z6_index ON osm_nodes_z6 USING gist (geom);
+CREATE INDEX IF NOT EXISTS osm_nodes_geom_z5_index ON osm_nodes_z5 USING gist (geom);
+CREATE INDEX IF NOT EXISTS osm_nodes_geom_z4_index ON osm_nodes_z4 USING gist (geom);
+CREATE INDEX IF NOT EXISTS osm_nodes_geom_z3_index ON osm_nodes_z3 USING gist (geom);
+CREATE INDEX IF NOT EXISTS osm_nodes_geom_z2_index ON osm_nodes_z2 USING gist (geom);
+CREATE INDEX IF NOT EXISTS osm_nodes_geom_z1_index ON osm_nodes_z1 USING gist (geom);
diff --git a/map/queries/osm_nodes_prepare.sql b/map/queries/osm_nodes_prepare.sql
new file mode 100644
index 00000000..e7bd764f
--- /dev/null
+++ b/map/queries/osm_nodes_prepare.sql
@@ -0,0 +1,2 @@
+CREATE INDEX IF NOT EXISTS osm_nodes_tags_index ON osm_nodes USING gin (tags);
+CREATE INDEX IF NOT EXISTS osm_nodes_geom_index ON osm_nodes USING spgist (geom);
diff --git a/map/queries/osm_nodes_simplify.sql b/map/queries/osm_nodes_simplify.sql
new file mode 100644
index 00000000..1085a068
--- /dev/null
+++ b/map/queries/osm_nodes_simplify.sql
@@ -0,0 +1,59 @@
+CREATE VIEW osm_nodes_z20 AS
+SELECT id, tags, geom FROM osm_nodes WHERE tags != '{}';
+
+CREATE VIEW osm_nodes_z19 AS
+SELECT id, tags, geom FROM osm_nodes WHERE tags != '{}';
+
+CREATE VIEW osm_nodes_z18 AS
+SELECT id, tags, geom FROM osm_nodes WHERE tags != '{}';
+
+CREATE VIEW osm_nodes_z17 AS
+SELECT id, tags, geom FROM osm_nodes WHERE tags != '{}';
+
+CREATE VIEW osm_nodes_z16 AS
+SELECT id, tags, geom FROM osm_nodes WHERE tags != '{}';
+
+CREATE VIEW osm_nodes_z15 AS
+SELECT id, tags, geom FROM osm_nodes WHERE tags != '{}';
+
+CREATE VIEW osm_nodes_z14 AS
+SELECT id, tags, geom FROM osm_nodes WHERE tags != '{}';
+
+CREATE MATERIALIZED VIEW osm_nodes_z13 AS
+SELECT id, tags, geom FROM osm_nodes WHERE tags != '{}' AND (tags ->> 'place' IN ('region', 'province', 'district', 'county', 'municipality', 'city', 'town', 'village', 'quarter', 'hamlet')) OR (tags ->> 'natural' IN ('peak', 'volcano')) OR (tags ->> 'highway' IN ('motorway_junction')) OR (tags ->> 'tourism' IN ('wilderness_hut')) OR (tags ->> 'waterway' IN ('waterfall')) OR (tags ->> 'natural' IN ('spring')) OR (tags ->> 'railway' IN ('level_crossing'));
+
+CREATE MATERIALIZED VIEW osm_nodes_z12 AS
+SELECT id, tags, geom FROM osm_nodes WHERE tags != '{}' AND (tags ->> 'place' IN ('region', 'province', 'district', 'county', 'municipality', 'city', 'town', 'village')) OR (tags ->> 'natural' IN ('peak', 'volcano')) OR (tags ->> 'highway' IN ('motorway_junction')) OR (tags ->> 'tourism' IN ('wilderness_hut')) OR (tags ->> 'waterway' IN ('waterfall'));
+
+CREATE MATERIALIZED VIEW osm_nodes_z11 AS
+SELECT id, tags, geom FROM osm_nodes WHERE tags != '{}' AND (tags ->> 'place' IN ('country', 'state', 'region', 'province', 'district', 'county', 'municipality', 'city', 'town', 'village')) OR (tags ->> 'natural' IN ('peak', 'volcano')) OR (tags ->> 'highway' IN ('motorway_junction'));
+
+CREATE MATERIALIZED VIEW osm_nodes_z10 AS
+SELECT id, tags, geom FROM osm_nodes WHERE tags != '{}' AND (tags ->> 'place' IN ('country', 'state', 'region', 'province', 'district', 'county', 'municipality', 'city', 'town')) OR (tags ->> 'natural' IN ('peak', 'volcano')) OR (tags ->> 'highway' IN ('motorway_junction'));
+
+CREATE MATERIALIZED VIEW osm_nodes_z9 AS
+SELECT id, tags, geom FROM osm_nodes WHERE tags != '{}' AND tags ->> 'place' IN ('country', 'state', 'region', 'province', 'district', 'county', 'municipality', 'city', 'town');
+
+CREATE MATERIALIZED VIEW osm_nodes_z8 AS
+SELECT id, tags, geom FROM osm_nodes WHERE tags != '{}' AND tags ->> 'place' IN ('country', 'state', 'region', 'province', 'district', 'county', 'municipality', 'city', 'town');
+
+CREATE MATERIALIZED VIEW osm_nodes_z7 AS
+SELECT id, tags, geom FROM osm_nodes WHERE tags != '{}' AND tags ->> 'place' IN ('country', 'city', 'sea', 'state', 'county');
+
+CREATE MATERIALIZED VIEW osm_nodes_z6 AS
+SELECT id, tags, geom FROM osm_nodes WHERE tags != '{}' AND tags ->> 'place' IN ('country', 'city', 'sea', 'state', 'county');
+
+CREATE MATERIALIZED VIEW osm_nodes_z5 AS
+SELECT id, tags, geom FROM osm_nodes WHERE tags != '{}' AND tags ->> 'place' IN ('country', 'city', 'sea', 'state', 'county');
+
+CREATE MATERIALIZED VIEW osm_nodes_z4 AS
+SELECT id, tags, geom FROM osm_nodes WHERE tags != '{}' AND tags ->> 'place' IN ('country', 'city', 'sea');
+
+CREATE MATERIALIZED VIEW osm_nodes_z3 AS
+SELECT id, tags, geom FROM osm_nodes WHERE tags != '{}' AND tags ->> 'place' IN ('country', 'city', 'sea');
+
+CREATE MATERIALIZED VIEW osm_nodes_z2 AS
+SELECT id, tags, geom FROM osm_nodes WHERE tags != '{}' AND tags ->> 'place' IN ('country');
+
+CREATE MATERIALIZED VIEW osm_nodes_z1 AS
+SELECT id, tags, geom FROM osm_nodes WHERE tags != '{}' AND tags ->> 'place' IN ('country');
diff --git a/map/queries/osm_point.sql b/map/queries/osm_point.sql
deleted file mode 100644
index 6bfa8888..00000000
--- a/map/queries/osm_point.sql
+++ /dev/null
@@ -1,120 +0,0 @@
-DROP VIEW IF EXISTS osm_point CASCADE;
-
-CREATE VIEW osm_point AS SELECT id, tags, geom FROM osm_node WHERE tags != '{}';
-
-CREATE VIEW osm_point_z1 AS SELECT id, tags, geom FROM osm_point;
-CREATE VIEW osm_point_z2 AS SELECT id, tags, geom FROM osm_point;
-CREATE VIEW osm_point_z3 AS SELECT id, tags, geom FROM osm_point;
-CREATE VIEW osm_point_z4 AS SELECT id, tags, geom FROM osm_point;
-CREATE VIEW osm_point_z5 AS SELECT id, tags, geom FROM osm_point;
-CREATE VIEW osm_point_z6 AS SELECT id, tags, geom FROM osm_point;
-CREATE VIEW osm_point_z7 AS SELECT id, tags, geom FROM osm_point;
-CREATE VIEW osm_point_z8 AS SELECT id, tags, geom FROM osm_point;
-CREATE VIEW osm_point_z9 AS SELECT id, tags, geom FROM osm_point;
-CREATE VIEW osm_point_z10 AS SELECT id, tags, geom FROM osm_point;
-CREATE VIEW osm_point_z11 AS SELECT id, tags, geom FROM osm_point;
-CREATE VIEW osm_point_z12 AS SELECT id, tags, geom FROM osm_point;
-CREATE VIEW osm_point_z13 AS SELECT id, tags, geom FROM osm_point;
-CREATE VIEW osm_point_z14 AS SELECT id, tags, geom FROM osm_point;
-CREATE VIEW osm_point_z15 AS SELECT id, tags, geom FROM osm_point;
-CREATE VIEW osm_point_z16 AS SELECT id, tags, geom FROM osm_point;
-CREATE VIEW osm_point_z17 AS SELECT id, tags, geom FROM osm_point;
-CREATE VIEW osm_point_z18 AS SELECT id, tags, geom FROM osm_point;
-CREATE VIEW osm_point_z19 AS SELECT id, tags, geom FROM osm_point;
-CREATE VIEW osm_point_z20 AS SELECT id, tags, geom FROM osm_point;
-
-
---
---CREATE MATERIALIZED VIEW osm_point_z13 AS
---SELECT id, tags, geom
---FROM osm_point
---WHERE (tags ->> 'place' IN ('region', 'province', 'district', 'county', 'municipality', 'city', 'town', 'village', 'quarter', 'hamlet'))
---OR (tags ->> 'natural' IN ('peak', 'volcano'))
---OR (tags ->> 'highway' IN ('motorway_junction'))
---OR (tags ->> 'tourism' IN ('wilderness_hut'))
---OR (tags ->> 'waterway' IN ('waterfall'))
---OR (tags ->> 'natural' IN ('spring'))
---OR (tags ->> 'railway' IN ('level_crossing'));
---
---CREATE MATERIALIZED VIEW osm_point_z12 AS
---SELECT id, tags, geom
---FROM osm_point
---WHERE (tags ->> 'place' IN ('region', 'province', 'district', 'county', 'municipality', 'city', 'town', 'village'))
---OR (tags ->> 'natural' IN ('peak', 'volcano'))
---OR (tags ->> 'highway' IN ('motorway_junction'))
---OR (tags ->> 'tourism' IN ('wilderness_hut'))
---OR (tags ->> 'waterway' IN ('waterfall'));
---
---CREATE MATERIALIZED VIEW osm_point_z11 AS
---SELECT id, tags, geom
---FROM osm_point
---WHERE (tags ->> 'place' IN ('country', 'state', 'region', 'province', 'district', 'county', 'municipality', 'city', 'town', 'village'))
---OR (tags ->> 'natural' IN ('peak', 'volcano'))
---OR (tags ->> 'highway' IN ('motorway_junction'));
---
---CREATE MATERIALIZED VIEW osm_point_z10 AS
---SELECT id, tags, geom
---FROM osm_point
---WHERE (tags ->> 'place' IN ('country', 'state', 'region', 'province', 'district', 'county', 'municipality', 'city', 'town'))
---OR (tags ->> 'natural' IN ('peak', 'volcano'))
---OR (tags ->> 'highway' IN ('motorway_junction'));
---
---CREATE MATERIALIZED VIEW osm_point_z9 AS
---SELECT id, tags, geom
---FROM osm_point
---WHERE tags ->> 'place' IN ('country', 'state', 'region', 'province', 'district', 'county', 'municipality', 'city', 'town');
---
---CREATE MATERIALIZED VIEW osm_point_z8 AS
---SELECT id, tags, geom
---FROM osm_point
---WHERE tags ->> 'place' IN ('country', 'state', 'region', 'province', 'district', 'county', 'municipality', 'city', 'town');
---
---CREATE MATERIALIZED VIEW osm_point_z7 AS
---SELECT id, tags, geom
---FROM osm_point
---WHERE tags ->> 'place' IN ('country', 'city', 'sea', 'state', 'county');
---
---CREATE MATERIALIZED VIEW osm_point_z6 AS
---SELECT id, tags, geom
---FROM osm_point
---WHERE tags ->> 'place' IN ('country', 'city', 'sea', 'state', 'county');
---
---CREATE MATERIALIZED VIEW osm_point_z5 AS
---SELECT id, tags, geom
---FROM osm_point
---WHERE tags ->> 'place' IN ('country', 'city', 'sea', 'state', 'county');
---
---CREATE MATERIALIZED VIEW osm_point_z4 AS
---SELECT id, tags, geom
---FROM osm_point
---WHERE tags ->> 'place' IN ('country', 'city', 'sea');
---
---CREATE MATERIALIZED VIEW osm_point_z3 AS
---SELECT id, tags, geom
---FROM osm_point
---WHERE tags ->> 'place' IN ('country', 'city', 'sea');
---
---CREATE MATERIALIZED VIEW osm_point_z2 AS
---SELECT id, tags, geom
---FROM osm_point
---WHERE tags ->> 'place' IN ('country');
---
---CREATE  VIEW osm_point_z1 AS
---SELECT id, tags, geom
---FROM osm_point
---WHERE tags ->> 'place' IN ('country');
---
---CREATE INDEX IF NOT EXISTS osm_point_spgist ON osm_point USING SPGIST (geom);
---CREATE INDEX IF NOT EXISTS osm_point_z1_spgist ON osm_point_z1 USING SPGIST (geom);
---CREATE INDEX IF NOT EXISTS osm_point_z2_spgist ON osm_point_z2 USING SPGIST (geom);
---CREATE INDEX IF NOT EXISTS osm_point_z3_spgist ON osm_point_z3 USING SPGIST (geom);
---CREATE INDEX IF NOT EXISTS osm_point_z4_spgist ON osm_point_z4 USING SPGIST (geom);
---CREATE INDEX IF NOT EXISTS osm_point_z5_spgist ON osm_point_z5 USING SPGIST (geom);
---CREATE INDEX IF NOT EXISTS osm_point_z6_spgist ON osm_point_z6 USING SPGIST (geom);
---CREATE INDEX IF NOT EXISTS osm_point_z7_spgist ON osm_point_z7 USING SPGIST (geom);
---CREATE INDEX IF NOT EXISTS osm_point_z8_spgist ON osm_point_z8 USING SPGIST (geom);
---CREATE INDEX IF NOT EXISTS osm_point_z9_spgist ON osm_point_z9 USING SPGIST (geom);
---CREATE INDEX IF NOT EXISTS osm_point_z10_spgist ON osm_point_z10 USING SPGIST (geom);
---CREATE INDEX IF NOT EXISTS osm_point_z11_spgist ON osm_point_z11 USING SPGIST (geom);
---CREATE INDEX IF NOT EXISTS osm_point_z12_spgist ON osm_point_z12 USING SPGIST (geom);
---CREATE INDEX IF NOT EXISTS osm_point_z13_spgist ON osm_point_z13 USING SPGIST (geom);
diff --git a/map/queries/osm_polygon.sql b/map/queries/osm_polygon.sql
deleted file mode 100644
index 4678dc01..00000000
--- a/map/queries/osm_polygon.sql
+++ /dev/null
@@ -1,9 +0,0 @@
-DROP VIEW IF EXISTS osm_polygon CASCADE;
-
-CREATE VIEW osm_polygon AS
-SELECT id, tags, geom
-FROM osm_ways
-LEFT JOIN osm_way_member ON id = way_id
-WHERE ST_GeometryType(osm_ways.geom) = 'ST_Polygon'
-  AND tags != '{}'
-  AND way_id IS NULL;
diff --git a/map/queries/osm_polygon_index.sql b/map/queries/osm_polygon_index.sql
new file mode 100644
index 00000000..99675be1
--- /dev/null
+++ b/map/queries/osm_polygon_index.sql
@@ -0,0 +1,3 @@
+CREATE INDEX osm_polygon_geom_idx ON osm_polygon USING GIST (geom);
+CREATE INDEX osm_polygon_tags_idx ON osm_polygon USING GIN (tags);
+
diff --git a/map/queries/osm_polygon_prepare.sql b/map/queries/osm_polygon_prepare.sql
new file mode 100644
index 00000000..5da3b1e0
--- /dev/null
+++ b/map/queries/osm_polygon_prepare.sql
@@ -0,0 +1,18 @@
+DROP MATERIALIZED VIEW IF EXISTS osm_polygon CASCADE;
+
+CREATE MATERIALIZED VIEW osm_polygon AS
+SELECT id, tags, geom
+FROM osm_ways LEFT JOIN osm_ways_member ON id = way_id
+WHERE ST_GeometryType(osm_ways.geom) = 'ST_Polygon'
+  AND tags != '{}'
+  AND way_id IS NULL
+UNION
+SELECT id, tags, geom
+FROM osm_relations
+WHERE ST_GeometryType(osm_relations.geom) = 'ST_Polygon'
+  AND tags != '{}'
+UNION
+SELECT id, tags, (st_dump(geom)).geom as geom
+FROM osm_relations
+WHERE ST_GeometryType(osm_relations.geom) = 'ST_MultiPolygon'
+  AND tags != '{}';
diff --git a/map/queries/osm_railway.sql b/map/queries/osm_railway.sql
deleted file mode 100644
index 20b2130a..00000000
--- a/map/queries/osm_railway.sql
+++ /dev/null
@@ -1,118 +0,0 @@
-DROP MATERIALIZED VIEW IF EXISTS osm_railway CASCADE;
-
-CREATE MATERIALIZED VIEW osm_railway AS
-SELECT ROW_NUMBER() OVER () as id, tags, geom
-FROM (
-   SELECT jsonb_build_object('railway', tags -> 'railway') as tags, (st_dump(st_linemerge(st_collect(geom)))).geom as geom
-   FROM osm_ways
-   WHERE tags ->> 'railway' IN ('light_rail', 'monorail', 'rail', 'subway', 'tram')
-   AND NOT tags ? 'service'
-   GROUP BY tags -> 'railway'
-) AS merge;
-
-CREATE MATERIALIZED VIEW osm_railway_z1 AS
-SELECT id, tags, geom
-FROM (SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 1)) AS geom FROM osm_railway) AS osm_railway
-WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((39135 / power(2, 1)), 2));
-
-CREATE MATERIALIZED VIEW osm_railway_z2 AS
-SELECT id, tags, geom
-FROM (SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 2)) AS geom FROM osm_railway) AS osm_railway
-WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((39135 / power(2, 2)), 2));
-
-CREATE MATERIALIZED VIEW osm_railway_z3 AS
-SELECT id, tags, geom
-FROM (SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 3)) AS geom FROM osm_railway) AS osm_railway
-WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((39135 / power(2, 3)), 2));
-
-CREATE MATERIALIZED VIEW osm_railway_z4 AS
-SELECT id, tags, geom
-FROM (SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 4)) AS geom FROM osm_railway) AS osm_railway
-WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((39135 / power(2, 4)), 2));
-
-CREATE MATERIALIZED VIEW osm_railway_z5 AS
-SELECT id, tags, geom
-FROM (SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 5)) AS geom FROM osm_railway) AS osm_railway
-WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((39135 / power(2, 5)), 2));
-
-CREATE MATERIALIZED VIEW osm_railway_z6 AS
-SELECT id, tags, geom
-FROM (SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 6)) AS geom FROM osm_railway) AS osm_railway
-WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((39135 / power(2, 6)), 2));
-
-CREATE MATERIALIZED VIEW osm_railway_z7 AS
-SELECT id, tags, geom
-FROM (SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 7)) AS geom FROM osm_railway) AS osm_railway
-WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((39135 / power(2, 7)), 2));
-
-CREATE MATERIALIZED VIEW osm_railway_z8 AS
-SELECT id, tags, geom
-FROM (SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 8)) AS geom FROM osm_railway) AS osm_railway
-WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((39135 / power(2, 8)), 2));
-
-CREATE MATERIALIZED VIEW osm_railway_z9 AS
-SELECT id, tags, geom
-FROM (SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 9)) AS geom FROM osm_railway) AS osm_railway
-WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((39135 / power(2, 9)), 2));
-
-CREATE MATERIALIZED VIEW osm_railway_z10 AS
-SELECT id, tags, geom
-FROM (SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 10)) AS geom FROM osm_railway) AS osm_railway
-WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((39135 / power(2, 10)), 2));
-
-CREATE MATERIALIZED VIEW osm_railway_z11 AS
-SELECT id, tags, geom
-FROM (SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 11)) AS geom FROM osm_railway) AS osm_railway
-WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((39135 / power(2, 11)), 2));
-
-CREATE MATERIALIZED VIEW osm_railway_z12 AS
-SELECT id, tags, geom
-FROM (SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 12)) AS geom FROM osm_railway) AS osm_railway
-WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((39135 / power(2, 12)), 2));
-
-CREATE MATERIALIZED VIEW osm_railway_z13 AS
-SELECT id, tags, geom
-FROM osm_railway;
-
-CREATE MATERIALIZED VIEW osm_railway_z14 AS
-SELECT id, tags, geom
-FROM osm_railway;
-
-CREATE MATERIALIZED VIEW osm_railway_z15 AS
-SELECT id, tags, geom
-FROM osm_railway;
-
-CREATE MATERIALIZED VIEW osm_railway_z16 AS
-SELECT id, tags, geom
-FROM osm_railway;
-
-CREATE MATERIALIZED VIEW osm_railway_z17 AS
-SELECT id, tags, geom
-FROM osm_railway;
-
-CREATE MATERIALIZED VIEW osm_railway_z18 AS
-SELECT id, tags, geom
-FROM osm_railway;
-
-CREATE MATERIALIZED VIEW osm_railway_z19 AS
-SELECT id, tags, geom
-FROM osm_railway;
-
-CREATE MATERIALIZED VIEW osm_railway_z20 AS
-SELECT id, tags, geom
-FROM osm_railway;
-
-CREATE INDEX IF NOT EXISTS osm_railway_geom_index ON osm_railway USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_railway_geom_z1_index ON osm_railway_z1 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_railway_geom_z2_index ON osm_railway_z2 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_railway_geom_z3_index ON osm_railway_z3 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_railway_geom_z4_index ON osm_railway_z4 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_railway_geom_z5_index ON osm_railway_z5 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_railway_geom_z6_index ON osm_railway_z6 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_railway_geom_z7_index ON osm_railway_z7 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_railway_geom_z8_index ON osm_railway_z8 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_railway_geom_z9_index ON osm_railway_z9 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_railway_geom_z10_index ON osm_railway_z10 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_railway_geom_z11_index ON osm_railway_z11 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_railway_geom_z12_index ON osm_railway_z12 USING SPGIST (geom);
-
diff --git a/map/queries/osm_railway_index.sql b/map/queries/osm_railway_index.sql
new file mode 100644
index 00000000..44b86295
--- /dev/null
+++ b/map/queries/osm_railway_index.sql
@@ -0,0 +1,13 @@
+CREATE INDEX IF NOT EXISTS osm_railway_geom_z12_index ON osm_railway_z12 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_railway_geom_z11_index ON osm_railway_z11 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_railway_geom_z10_index ON osm_railway_z10 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_railway_geom_z9_index ON osm_railway_z9 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_railway_geom_z8_index ON osm_railway_z8 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_railway_geom_z7_index ON osm_railway_z7 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_railway_geom_z6_index ON osm_railway_z6 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_railway_geom_z5_index ON osm_railway_z5 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_railway_geom_z4_index ON osm_railway_z4 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_railway_geom_z3_index ON osm_railway_z3 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_railway_geom_z2_index ON osm_railway_z2 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_railway_geom_z1_index ON osm_railway_z1 USING SPGIST (geom);
+
diff --git a/map/queries/osm_railway_prepare.sql b/map/queries/osm_railway_prepare.sql
new file mode 100644
index 00000000..8325424c
--- /dev/null
+++ b/map/queries/osm_railway_prepare.sql
@@ -0,0 +1,16 @@
+DROP MATERIALIZED VIEW IF EXISTS osm_railway CASCADE;
+
+CREATE MATERIALIZED VIEW osm_railway AS
+SELECT id, tags, geom
+FROM (
+   SELECT
+       min(id) as id,
+       jsonb_build_object('railway', tags -> 'railway') as tags,
+       (st_dump(st_linemerge(st_collect(geom)))).geom as geom
+   FROM osm_ways
+   WHERE tags ->> 'railway' IN ('light_rail', 'monorail', 'rail', 'subway', 'tram')
+   AND NOT tags ? 'service'
+   GROUP BY tags -> 'railway'
+) AS merge;
+
+CREATE INDEX IF NOT EXISTS osm_railway_geom_index ON osm_railway USING SPGIST (geom);
diff --git a/map/queries/osm_railway_simplify.sql b/map/queries/osm_railway_simplify.sql
new file mode 100644
index 00000000..b35c73ab
--- /dev/null
+++ b/map/queries/osm_railway_simplify.sql
@@ -0,0 +1,83 @@
+CREATE VIEW osm_railway_z20 AS
+SELECT id, tags, geom FROM osm_railway;
+
+CREATE VIEW osm_railway_z19 AS
+SELECT id, tags, geom FROM osm_railway;
+
+CREATE VIEW osm_railway_z18 AS
+SELECT id, tags, geom FROM osm_railway;
+
+CREATE VIEW osm_railway_z17 AS
+SELECT id, tags, geom FROM osm_railway;
+
+CREATE VIEW osm_railway_z16 AS
+SELECT id, tags, geom FROM osm_railway;
+
+CREATE VIEW osm_railway_z15 AS
+SELECT id, tags, geom FROM osm_railway;
+
+CREATE VIEW osm_railway_z14 AS
+SELECT id, tags, geom FROM osm_railway;
+
+CREATE VIEW osm_railway_z13 AS
+SELECT id, tags, geom FROM osm_railway;
+
+CREATE MATERIALIZED VIEW osm_railway_z12 AS
+SELECT id, tags, geom
+FROM (SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 12)) AS geom FROM osm_railway) AS osm_railway
+WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((78270 / power(2, 12)), 2));
+
+CREATE MATERIALIZED VIEW osm_railway_z11 AS
+SELECT id, tags, geom
+FROM (SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 11)) AS geom FROM osm_railway) AS osm_railway
+WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((78270 / power(2, 11)), 2));
+
+CREATE MATERIALIZED VIEW osm_railway_z10 AS
+SELECT id, tags, geom
+FROM (SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 10)) AS geom FROM osm_railway) AS osm_railway
+WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((78270 / power(2, 10)), 2));
+
+CREATE MATERIALIZED VIEW osm_railway_z9 AS
+SELECT id, tags, geom
+FROM (SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 9)) AS geom FROM osm_railway) AS osm_railway
+WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((78270 / power(2, 9)), 2));
+
+CREATE MATERIALIZED VIEW osm_railway_z8 AS
+SELECT id, tags, geom
+FROM (SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 8)) AS geom FROM osm_railway) AS osm_railway
+WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((78270 / power(2, 8)), 2));
+
+CREATE MATERIALIZED VIEW osm_railway_z7 AS
+SELECT id, tags, geom
+FROM (SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 7)) AS geom FROM osm_railway) AS osm_railway
+WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((78270 / power(2, 7)), 2));
+
+CREATE MATERIALIZED VIEW osm_railway_z6 AS
+SELECT id, tags, geom
+FROM (SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 6)) AS geom FROM osm_railway) AS osm_railway
+WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((78270 / power(2, 6)), 2));
+
+CREATE MATERIALIZED VIEW osm_railway_z5 AS
+SELECT id, tags, geom
+FROM (SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 5)) AS geom FROM osm_railway) AS osm_railway
+WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((78270 / power(2, 5)), 2));
+
+CREATE MATERIALIZED VIEW osm_railway_z4 AS
+SELECT id, tags, geom
+FROM (SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 4)) AS geom FROM osm_railway) AS osm_railway
+WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((78270 / power(2, 4)), 2));
+
+CREATE MATERIALIZED VIEW osm_railway_z3 AS
+SELECT id, tags, geom
+FROM (SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 3)) AS geom FROM osm_railway) AS osm_railway
+WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((78270 / power(2, 3)), 2));
+
+CREATE MATERIALIZED VIEW osm_railway_z2 AS
+SELECT id, tags, geom
+FROM (SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 2)) AS geom FROM osm_railway) AS osm_railway
+WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((78270 / power(2, 2)), 2));
+
+CREATE MATERIALIZED VIEW osm_railway_z1 AS
+SELECT id, tags, geom
+FROM (SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 1)) AS geom FROM osm_railway) AS osm_railway
+WHERE geom IS NOT NULL AND (st_area(st_envelope(geom)) > power((78270 / power(2, 1)), 2));
diff --git a/map/queries/osm_relation.sql b/map/queries/osm_relation.sql
deleted file mode 100644
index 05ec054a..00000000
--- a/map/queries/osm_relation.sql
+++ /dev/null
@@ -1,152 +0,0 @@
-DROP VIEW IF EXISTS osm_relation CASCADE;
-
-CREATE VIEW osm_relation AS SELECT * FROM osm_relations;
-
-DROP INDEX IF EXISTS osm_relation_tags_index;
-DROP INDEX IF EXISTS osm_relation_geom_index;
-
-CREATE INDEX osm_relation_tags_index ON osm_relations USING gin (tags);
-CREATE INDEX osm_relation_geom_index ON osm_relations USING spgist (geom);
-
-CREATE MATERIALIZED VIEW osm_relation_z1 AS
-SELECT id, tags, geom
-FROM (
-         SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 1)) AS geom
-         FROM osm_relations
-         WHERE tags ?| ARRAY ['landuse', 'natural']
-     ) AS osm_relations
-WHERE geom IS NOT NULL
-  AND (st_area(st_envelope(geom)) > power((39135 / power(2, 1)), 2));
-
-CREATE MATERIALIZED VIEW osm_relation_z2 AS
-SELECT id, tags, geom
-FROM (
-         SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 2)) AS geom
-         FROM osm_relations
-         WHERE tags ?| ARRAY ['landuse', 'natural']
-     ) AS osm_relations
-WHERE geom IS NOT NULL
-  AND (st_area(st_envelope(geom)) > power((39135 / power(2, 2)), 2));
-
-CREATE MATERIALIZED VIEW osm_relation_z3 AS
-SELECT id, tags, geom
-FROM (
-         SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 3)) AS geom
-         FROM osm_relations
-         WHERE tags ?| ARRAY ['landuse', 'natural']
-     ) AS osm_relations
-WHERE geom IS NOT NULL
-  AND (st_area(st_envelope(geom)) > power((39135 / power(2, 3)), 2));
-
-CREATE MATERIALIZED VIEW osm_relation_z4 AS
-SELECT id, tags, geom
-FROM (
-         SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 4)) AS geom
-         FROM osm_relations
-         WHERE tags ?| ARRAY ['landuse', 'natural']
-     ) AS osm_relations
-WHERE geom IS NOT NULL
-  AND (st_area(st_envelope(geom)) > power((39135 / power(2, 4)), 2));
-
-CREATE MATERIALIZED VIEW osm_relation_z5 AS
-SELECT id, tags, geom
-FROM (
-         SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 5)) AS geom
-         FROM osm_relations
-         WHERE tags ?| ARRAY ['landuse', 'natural']
-     ) AS osm_relations
-WHERE geom IS NOT NULL
-  AND (st_area(st_envelope(geom)) > power((39135 / power(2, 5)), 2));
-
-CREATE MATERIALIZED VIEW osm_relation_z6 AS
-SELECT id, tags, geom
-FROM (
-         SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 6)) AS geom
-         FROM osm_relations
-         WHERE tags ?| ARRAY ['landuse', 'natural', 'waterway']
-     ) AS osm_relations
-WHERE geom IS NOT NULL
-  AND (st_area(st_envelope(geom)) > power((39135 / power(2, 6)), 2));
-
-CREATE MATERIALIZED VIEW osm_relation_z7 AS
-SELECT id, tags, geom
-FROM (
-         SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 7)) AS geom
-         FROM osm_relations
-         WHERE tags ?| ARRAY ['landuse', 'natural', 'waterway']
-     ) AS osm_relations
-WHERE geom IS NOT NULL
-  AND (st_area(st_envelope(geom)) > power((39135 / power(2, 7)), 2));
-
-CREATE MATERIALIZED VIEW osm_relation_z8 AS
-SELECT id, tags, geom
-FROM (
-         SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 8)) AS geom
-         FROM osm_relations
-         WHERE tags ?| ARRAY ['landuse', 'natural', 'waterway']
-     ) AS osm_relations
-WHERE geom IS NOT NULL
-  AND (st_area(st_envelope(geom)) > power((39135 / power(2, 8)), 2));
-
-CREATE MATERIALIZED VIEW osm_relation_z9 AS
-SELECT id, tags, geom
-FROM (
-         SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 9)) AS geom
-         FROM osm_relations
-         WHERE tags ?| ARRAY ['landuse', 'natural', 'waterway']
-     ) AS osm_relations
-WHERE geom IS NOT NULL
-  AND (st_area(st_envelope(geom)) > power((39135 / power(2, 9)), 2));
-
-CREATE MATERIALIZED VIEW osm_relation_z10 AS
-SELECT id, tags, geom
-FROM (
-         SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 10)) AS geom
-         FROM osm_relations
-         WHERE tags ?| ARRAY ['landuse', 'natural', 'waterway']
-     ) AS osm_relations
-WHERE geom IS NOT NULL
-  AND (st_area(st_envelope(geom)) > power((39135 / power(2, 10)), 2));
-
-CREATE MATERIALIZED VIEW osm_relation_z11 AS
-SELECT id, tags, geom
-FROM (
-         SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 11)) AS geom
-         FROM osm_relations
-         WHERE tags ?| ARRAY ['landuse', 'natural', 'waterway']
-     ) AS osm_relations
-WHERE geom IS NOT NULL
-  AND (st_area(st_envelope(geom)) > power((39135 / power(2, 11)), 2));
-
-CREATE MATERIALIZED VIEW osm_relation_z12 AS
-SELECT id, tags, geom
-FROM (
-         SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 12)) AS geom
-         FROM osm_relations
-         WHERE tags ?| ARRAY ['landuse', 'natural', 'power', 'railway', 'route', 'waterway']
-     ) AS osm_relations
-WHERE geom IS NOT NULL
-  AND (st_area(st_envelope(geom)) > power((39135 / power(2, 12)), 2));
-
-CREATE VIEW osm_relation_z13 AS SELECT id, tags, geom FROM osm_relations;
-CREATE VIEW osm_relation_z14 AS SELECT id, tags, geom FROM osm_relations;
-CREATE VIEW osm_relation_z15 AS SELECT id, tags, geom FROM osm_relations;
-CREATE VIEW osm_relation_z16 AS SELECT id, tags, geom FROM osm_relations;
-CREATE VIEW osm_relation_z17 AS SELECT id, tags, geom FROM osm_relations;
-CREATE VIEW osm_relation_z18 AS SELECT id, tags, geom FROM osm_relations;
-CREATE VIEW osm_relation_z19 AS SELECT id, tags, geom FROM osm_relations;
-CREATE VIEW osm_relation_z20 AS SELECT id, tags, geom FROM osm_relations;
-
-CREATE INDEX IF NOT EXISTS osm_relation_geom_index ON osm_relations USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_relation_geom_z1_index ON osm_relation_z1 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_relation_geom_z2_index ON osm_relation_z2 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_relation_geom_z3_index ON osm_relation_z3 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_relation_geom_z4_index ON osm_relation_z4 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_relation_geom_z5_index ON osm_relation_z5 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_relation_geom_z6_index ON osm_relation_z6 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_relation_geom_z7_index ON osm_relation_z7 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_relation_geom_z8_index ON osm_relation_z8 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_relation_geom_z9_index ON osm_relation_z9 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_relation_geom_z10_index ON osm_relation_z10 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_relation_geom_z11_index ON osm_relation_z11 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_relation_geom_z12_index ON osm_relation_z12 USING SPGIST (geom);
diff --git a/map/queries/osm_relations_clean.sql b/map/queries/osm_relations_clean.sql
new file mode 100644
index 00000000..395c9271
--- /dev/null
+++ b/map/queries/osm_relations_clean.sql
@@ -0,0 +1,24 @@
+DROP INDEX IF EXISTS osm_relations_tags_index;
+DROP INDEX IF EXISTS osm_relations_geom_index;
+
+DROP VIEW IF EXISTS osm_relations_z20 CASCADE;
+DROP VIEW IF EXISTS osm_relations_z19 CASCADE;
+DROP VIEW IF EXISTS osm_relations_z18 CASCADE;
+DROP VIEW IF EXISTS osm_relations_z17 CASCADE;
+DROP VIEW IF EXISTS osm_relations_z16 CASCADE;
+DROP VIEW IF EXISTS osm_relations_z15 CASCADE;
+DROP VIEW IF EXISTS osm_relations_z14 CASCADE;
+DROP VIEW IF EXISTS osm_relations_z13 CASCADE;
+
+DROP MATERIALIZED VIEW IF EXISTS osm_relations_z12 CASCADE;
+DROP MATERIALIZED VIEW IF EXISTS osm_relations_z11 CASCADE;
+DROP MATERIALIZED VIEW IF EXISTS osm_relations_z10 CASCADE;
+DROP MATERIALIZED VIEW IF EXISTS osm_relations_z9 CASCADE;
+DROP MATERIALIZED VIEW IF EXISTS osm_relations_z8 CASCADE;
+DROP MATERIALIZED VIEW IF EXISTS osm_relations_z7 CASCADE;
+DROP MATERIALIZED VIEW IF EXISTS osm_relations_z6 CASCADE;
+DROP MATERIALIZED VIEW IF EXISTS osm_relations_z5 CASCADE;
+DROP MATERIALIZED VIEW IF EXISTS osm_relations_z4 CASCADE;
+DROP MATERIALIZED VIEW IF EXISTS osm_relations_z3 CASCADE;
+DROP MATERIALIZED VIEW IF EXISTS osm_relations_z2 CASCADE;
+DROP MATERIALIZED VIEW IF EXISTS osm_relations_z1 CASCADE;
diff --git a/map/queries/osm_relations_index.sql b/map/queries/osm_relations_index.sql
new file mode 100644
index 00000000..f064381b
--- /dev/null
+++ b/map/queries/osm_relations_index.sql
@@ -0,0 +1,12 @@
+CREATE INDEX IF NOT EXISTS osm_relations_geom_z12_index ON osm_relations_z12 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_relations_geom_z11_index ON osm_relations_z11 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_relations_geom_z10_index ON osm_relations_z10 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_relations_geom_z9_index ON osm_relations_z9 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_relations_geom_z8_index ON osm_relations_z8 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_relations_geom_z7_index ON osm_relations_z7 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_relations_geom_z6_index ON osm_relations_z6 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_relations_geom_z5_index ON osm_relations_z5 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_relations_geom_z4_index ON osm_relations_z4 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_relations_geom_z3_index ON osm_relations_z3 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_relations_geom_z2_index ON osm_relations_z2 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_relations_geom_z1_index ON osm_relations_z1 USING SPGIST (geom);
diff --git a/map/queries/osm_relations_prepare.sql b/map/queries/osm_relations_prepare.sql
new file mode 100644
index 00000000..84f41476
--- /dev/null
+++ b/map/queries/osm_relations_prepare.sql
@@ -0,0 +1,2 @@
+CREATE INDEX osm_relations_tags_index ON osm_relations USING gin (tags);
+CREATE INDEX osm_relations_geom_index ON osm_relations USING spgist (geom);
diff --git a/map/queries/osm_relations_simplify.sql b/map/queries/osm_relations_simplify.sql
new file mode 100644
index 00000000..1a625c72
--- /dev/null
+++ b/map/queries/osm_relations_simplify.sql
@@ -0,0 +1,143 @@
+CREATE VIEW osm_relations_z20 AS
+SELECT id, tags, geom FROM osm_relations;
+
+CREATE VIEW osm_relations_z19 AS
+SELECT id, tags, geom FROM osm_relations;
+
+CREATE VIEW osm_relations_z18 AS
+SELECT id, tags, geom FROM osm_relations;
+
+CREATE VIEW osm_relations_z17 AS
+SELECT id, tags, geom FROM osm_relations;
+
+CREATE VIEW osm_relations_z16 AS
+SELECT id, tags, geom FROM osm_relations;
+
+CREATE VIEW osm_relations_z15 AS
+SELECT id, tags, geom FROM osm_relations;
+
+CREATE VIEW osm_relations_z14 AS
+SELECT id, tags, geom FROM osm_relations;
+
+CREATE VIEW osm_relations_z13 AS
+SELECT id, tags, geom FROM osm_relations;
+
+CREATE MATERIALIZED VIEW osm_relations_z12 AS
+SELECT id, tags, geom
+FROM (
+         SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 12)) AS geom
+         FROM osm_relations
+         WHERE tags ?| ARRAY ['landuse', 'natural', 'power', 'railway', 'route', 'waterway']
+     ) AS osm_relations
+WHERE geom IS NOT NULL
+  AND (st_area(st_envelope(geom)) > power((78270 / power(2, 12)), 2));
+
+CREATE MATERIALIZED VIEW osm_relations_z11 AS
+SELECT id, tags, geom
+FROM (
+         SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 11)) AS geom
+         FROM osm_relations
+         WHERE tags ?| ARRAY ['landuse', 'natural', 'waterway']
+     ) AS osm_relations
+WHERE geom IS NOT NULL
+  AND (st_area(st_envelope(geom)) > power((78270 / power(2, 11)), 2));
+
+CREATE MATERIALIZED VIEW osm_relations_z10 AS
+SELECT id, tags, geom
+FROM (
+         SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 10)) AS geom
+         FROM osm_relations
+         WHERE tags ?| ARRAY ['landuse', 'natural', 'waterway']
+     ) AS osm_relations
+WHERE geom IS NOT NULL
+  AND (st_area(st_envelope(geom)) > power((78270 / power(2, 10)), 2));
+
+CREATE MATERIALIZED VIEW osm_relations_z9 AS
+SELECT id, tags, geom
+FROM (
+         SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 9)) AS geom
+         FROM osm_relations
+         WHERE tags ?| ARRAY ['landuse', 'natural', 'waterway']
+     ) AS osm_relations
+WHERE geom IS NOT NULL
+  AND (st_area(st_envelope(geom)) > power((78270 / power(2, 9)), 2));
+
+CREATE MATERIALIZED VIEW osm_relations_z8 AS
+SELECT id, tags, geom
+FROM (
+         SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 8)) AS geom
+         FROM osm_relations
+         WHERE tags ?| ARRAY ['landuse', 'natural', 'waterway']
+     ) AS osm_relations
+WHERE geom IS NOT NULL
+  AND (st_area(st_envelope(geom)) > power((78270 / power(2, 8)), 2));
+
+CREATE MATERIALIZED VIEW osm_relations_z7 AS
+SELECT id, tags, geom
+FROM (
+         SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 7)) AS geom
+         FROM osm_relations
+         WHERE tags ?| ARRAY ['landuse', 'natural', 'waterway']
+     ) AS osm_relations
+WHERE geom IS NOT NULL
+  AND (st_area(st_envelope(geom)) > power((78270 / power(2, 7)), 2));
+
+CREATE MATERIALIZED VIEW osm_relations_z6 AS
+SELECT id, tags, geom
+FROM (
+         SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 6)) AS geom
+         FROM osm_relations
+         WHERE tags ?| ARRAY ['landuse', 'natural', 'waterway']
+     ) AS osm_relations
+WHERE geom IS NOT NULL
+  AND (st_area(st_envelope(geom)) > power((78270 / power(2, 6)), 2));
+
+CREATE MATERIALIZED VIEW osm_relations_z5 AS
+SELECT id, tags, geom
+FROM (
+         SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 5)) AS geom
+         FROM osm_relations
+         WHERE tags ?| ARRAY ['landuse', 'natural']
+     ) AS osm_relations
+WHERE geom IS NOT NULL
+  AND (st_area(st_envelope(geom)) > power((78270 / power(2, 5)), 2));
+
+CREATE MATERIALIZED VIEW osm_relations_z4 AS
+SELECT id, tags, geom
+FROM (
+         SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 4)) AS geom
+         FROM osm_relations
+         WHERE tags ?| ARRAY ['landuse', 'natural']
+     ) AS osm_relations
+WHERE geom IS NOT NULL
+  AND (st_area(st_envelope(geom)) > power((78270 / power(2, 4)), 2));
+
+CREATE MATERIALIZED VIEW osm_relations_z3 AS
+SELECT id, tags, geom
+FROM (
+         SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 3)) AS geom
+         FROM osm_relations
+         WHERE tags ?| ARRAY ['landuse', 'natural']
+     ) AS osm_relations
+WHERE geom IS NOT NULL
+  AND (st_area(st_envelope(geom)) > power((78270 / power(2, 3)), 2));
+
+CREATE MATERIALIZED VIEW osm_relations_z2 AS
+SELECT id, tags, geom
+FROM (
+         SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 2)) AS geom
+         FROM osm_relations
+         WHERE tags ?| ARRAY ['landuse', 'natural']
+     ) AS osm_relations
+WHERE geom IS NOT NULL
+  AND (st_area(st_envelope(geom)) > power((78270 / power(2, 2)), 2));
+
+CREATE MATERIALIZED VIEW osm_relations_z1 AS
+SELECT id, tags, geom
+FROM (
+         SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 1)) AS geom
+         FROM osm_relations
+         WHERE tags ?| ARRAY ['landuse', 'natural']
+     ) AS osm_relations
+WHERE geom IS NOT NULL
+  AND (st_area(st_envelope(geom)) > power((78270 / power(2, 1)), 2));
diff --git a/map/queries/osm_way.sql b/map/queries/osm_way.sql
deleted file mode 100644
index 8903e443..00000000
--- a/map/queries/osm_way.sql
+++ /dev/null
@@ -1,152 +0,0 @@
-DROP VIEW IF EXISTS osm_way CASCADE;
-
-CREATE VIEW osm_way AS SELECT * FROM osm_ways;
-
-DROP INDEX IF EXISTS osm_way_tags_index;
-DROP INDEX IF EXISTS osm_way_geom_index;
-
-CREATE INDEX osm_way_tags_index ON osm_ways USING gin (tags);
-CREATE INDEX osm_way_geom_index ON osm_ways USING spgist (geom);
-
-CREATE MATERIALIZED VIEW osm_way_z1 AS
-SELECT id, tags, geom
-FROM (
-         SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 1)) AS geom
-         FROM osm_ways
-         WHERE tags ?| ARRAY ['landuse', 'natural']
-     ) AS osm_ways
-WHERE geom IS NOT NULL
-  AND (st_area(st_envelope(geom)) > power((39135 / power(2, 1)), 2));
-
-CREATE MATERIALIZED VIEW osm_way_z2 AS
-SELECT id, tags, geom
-FROM (
-         SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 2)) AS geom
-         FROM osm_ways
-         WHERE tags ?| ARRAY ['landuse', 'natural']
-     ) AS osm_ways
-WHERE geom IS NOT NULL
-  AND (st_area(st_envelope(geom)) > power((39135 / power(2, 2)), 2));
-
-CREATE MATERIALIZED VIEW osm_way_z3 AS
-SELECT id, tags, geom
-FROM (
-         SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 3)) AS geom
-         FROM osm_ways
-         WHERE tags ?| ARRAY ['landuse', 'natural']
-     ) AS osm_ways
-WHERE geom IS NOT NULL
-  AND (st_area(st_envelope(geom)) > power((39135 / power(2, 3)), 2));
-
-CREATE MATERIALIZED VIEW osm_way_z4 AS
-SELECT id, tags, geom
-FROM (
-         SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 4)) AS geom
-         FROM osm_ways
-         WHERE tags ?| ARRAY ['landuse', 'natural']
-     ) AS osm_ways
-WHERE geom IS NOT NULL
-  AND (st_area(st_envelope(geom)) > power((39135 / power(2, 4)), 2));
-
-CREATE MATERIALIZED VIEW osm_way_z5 AS
-SELECT id, tags, geom
-FROM (
-         SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 5)) AS geom
-         FROM osm_ways
-         WHERE tags ?| ARRAY ['landuse', 'natural']
-     ) AS osm_ways
-WHERE geom IS NOT NULL
-  AND (st_area(st_envelope(geom)) > power((39135 / power(2, 5)), 2));
-
-CREATE MATERIALIZED VIEW osm_way_z6 AS
-SELECT id, tags, geom
-FROM (
-         SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 6)) AS geom
-         FROM osm_ways
-         WHERE tags ?| ARRAY ['landuse', 'natural', 'waterway' ]
-     ) AS osm_ways
-WHERE geom IS NOT NULL
-  AND (st_area(st_envelope(geom)) > power((39135 / power(2, 6)), 2));
-
-CREATE MATERIALIZED VIEW osm_way_z7 AS
-SELECT id, tags, geom
-FROM (
-         SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 7)) AS geom
-         FROM osm_ways
-         WHERE tags ?| ARRAY ['landuse', 'natural', 'waterway' ]
-     ) AS osm_ways
-WHERE geom IS NOT NULL
-  AND (st_area(st_envelope(geom)) > power((39135 / power(2, 7)), 2));
-
-CREATE MATERIALIZED VIEW osm_way_z8 AS
-SELECT id, tags, geom
-FROM (
-         SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 8)) AS geom
-         FROM osm_ways
-         WHERE tags ?| ARRAY ['landuse', 'natural', 'waterway' ]
-     ) AS osm_ways
-WHERE geom IS NOT NULL
-  AND (st_area(st_envelope(geom)) > power((39135 / power(2, 8)), 2));
-
-CREATE MATERIALIZED VIEW osm_way_z9 AS
-SELECT id, tags, geom
-FROM (
-         SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 9)) AS geom
-         FROM osm_ways
-         WHERE tags ?| ARRAY ['landuse', 'natural', 'waterway' ]
-     ) AS osm_ways
-WHERE geom IS NOT NULL
-  AND (st_area(st_envelope(geom)) > power((39135 / power(2, 9)), 2));
-
-CREATE MATERIALIZED VIEW osm_way_z10 AS
-SELECT id, tags, geom
-FROM (
-         SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 10)) AS geom
-         FROM osm_ways
-         WHERE tags ?| ARRAY ['landuse', 'natural', 'waterway' ]
-     ) AS osm_ways
-WHERE geom IS NOT NULL
-  AND (st_area(st_envelope(geom)) > power((39135 / power(2, 10)), 2));
-
-CREATE MATERIALIZED VIEW osm_way_z11 AS
-SELECT id, tags, geom
-FROM (
-         SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 11)) AS geom
-         FROM osm_ways
-         WHERE tags ?| ARRAY ['landuse', 'natural', 'waterway' ]
-     ) AS osm_ways
-WHERE geom IS NOT NULL
-  AND (st_area(st_envelope(geom)) > power((39135 / power(2, 11)), 2));
-
-CREATE MATERIALIZED VIEW osm_way_z12 AS
-SELECT id, tags, geom
-FROM (
-         SELECT id, tags, st_simplifypreservetopology(geom, 39135 / power(2, 12)) AS geom
-         FROM osm_ways
-         WHERE tags ?| ARRAY [ 'landuse', 'natural', 'power', 'railway', 'route', 'waterway' ]
-     ) AS osm_ways
-WHERE geom IS NOT NULL
-  AND (st_area(st_envelope(geom)) > power((39135 / power(2, 12)), 2));
-
-CREATE VIEW osm_way_z13 AS SELECT id, tags, geom FROM osm_way;
-CREATE VIEW osm_way_z14 AS SELECT id, tags, geom FROM osm_way;
-CREATE VIEW osm_way_z15 AS SELECT id, tags, geom FROM osm_way;
-CREATE VIEW osm_way_z16 AS SELECT id, tags, geom FROM osm_way;
-CREATE VIEW osm_way_z17 AS SELECT id, tags, geom FROM osm_way;
-CREATE VIEW osm_way_z18 AS SELECT id, tags, geom FROM osm_way;
-CREATE VIEW osm_way_z19 AS SELECT id, tags, geom FROM osm_way;
-CREATE VIEW osm_way_z20 AS SELECT id, tags, geom FROM osm_way;
-
-CREATE INDEX IF NOT EXISTS osm_way_index ON osm_ways USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_way_z1_index ON osm_way_z1 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_way_z2_index ON osm_way_z2 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_way_z3_index ON osm_way_z3 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_way_z4_index ON osm_way_z4 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_way_z5_index ON osm_way_z5 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_way_z6_index ON osm_way_z6 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_way_z7_index ON osm_way_z7 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_way_z8_index ON osm_way_z8 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_way_z9_index ON osm_way_z9 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_way_z10_index ON osm_way_z10 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_way_z11_index ON osm_way_z11 USING SPGIST (geom);
-CREATE INDEX IF NOT EXISTS osm_way_z12_index ON osm_way_z12 USING SPGIST (geom);
diff --git a/map/queries/osm_ways_clean.sql b/map/queries/osm_ways_clean.sql
new file mode 100644
index 00000000..45c0e95b
--- /dev/null
+++ b/map/queries/osm_ways_clean.sql
@@ -0,0 +1,26 @@
+DROP INDEX IF EXISTS osm_ways_tags_index;
+DROP INDEX IF EXISTS osm_ways_geom_index;
+
+DROP VIEW IF EXISTS osm_ways_z20 CASCADE;
+DROP VIEW IF EXISTS osm_ways_z19 CASCADE;
+DROP VIEW IF EXISTS osm_ways_z18 CASCADE;
+DROP VIEW IF EXISTS osm_ways_z17 CASCADE;
+DROP VIEW IF EXISTS osm_ways_z16 CASCADE;
+DROP VIEW IF EXISTS osm_ways_z15 CASCADE;
+DROP VIEW IF EXISTS osm_ways_z14 CASCADE;
+DROP VIEW IF EXISTS osm_ways_z13 CASCADE;
+
+DROP MATERIALIZED VIEW IF EXISTS osm_ways_z12 CASCADE;
+DROP MATERIALIZED VIEW IF EXISTS osm_ways_z11 CASCADE;
+DROP MATERIALIZED VIEW IF EXISTS osm_ways_z10 CASCADE;
+DROP MATERIALIZED VIEW IF EXISTS osm_ways_z9 CASCADE;
+DROP MATERIALIZED VIEW IF EXISTS osm_ways_z8 CASCADE;
+DROP MATERIALIZED VIEW IF EXISTS osm_ways_z7 CASCADE;
+DROP MATERIALIZED VIEW IF EXISTS osm_ways_z6 CASCADE;
+DROP MATERIALIZED VIEW IF EXISTS osm_ways_z5 CASCADE;
+DROP MATERIALIZED VIEW IF EXISTS osm_ways_z4 CASCADE;
+DROP MATERIALIZED VIEW IF EXISTS osm_ways_z3 CASCADE;
+DROP MATERIALIZED VIEW IF EXISTS osm_ways_z2 CASCADE;
+DROP MATERIALIZED VIEW IF EXISTS osm_ways_z1 CASCADE;
+
+DROP MATERIALIZED VIEW IF EXISTS osm_ways_member CASCADE;
diff --git a/map/queries/osm_ways_index.sql b/map/queries/osm_ways_index.sql
new file mode 100644
index 00000000..195587cc
--- /dev/null
+++ b/map/queries/osm_ways_index.sql
@@ -0,0 +1,14 @@
+CREATE INDEX IF NOT EXISTS osm_ways_z12_index ON osm_ways_z12 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_ways_z11_index ON osm_ways_z11 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_ways_z10_index ON osm_ways_z10 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_ways_z9_index ON osm_ways_z9 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_ways_z8_index ON osm_ways_z8 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_ways_z7_index ON osm_ways_z7 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_ways_z6_index ON osm_ways_z6 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_ways_z5_index ON osm_ways_z5 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_ways_z4_index ON osm_ways_z4 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_ways_z3_index ON osm_ways_z3 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_ways_z2_index ON osm_ways_z2 USING SPGIST (geom);
+CREATE INDEX IF NOT EXISTS osm_ways_z1_index ON osm_ways_z1 USING SPGIST (geom);
+
+CREATE INDEX osm_ways_member_index ON osm_ways_member(way_id);
diff --git a/map/queries/osm_way_member.sql b/map/queries/osm_ways_prepare.sql
similarity index 59%
rename from map/queries/osm_way_member.sql
rename to map/queries/osm_ways_prepare.sql
index e0fafc70..b08603f4 100644
--- a/map/queries/osm_way_member.sql
+++ b/map/queries/osm_ways_prepare.sql
@@ -1,11 +1,10 @@
-DROP MATERIALIZED VIEW IF EXISTS osm_way_member CASCADE;
+CREATE INDEX osm_ways_geom_index ON osm_ways USING spgist (geom);
+CREATE INDEX osm_ways_tags_index ON osm_ways USING gin (tags);
 
-CREATE MATERIALIZED VIEW osm_way_member AS
+CREATE MATERIALIZED VIEW osm_ways_member AS
 SELECT DISTINCT member_ref as way_id
 FROM osm_relations, unnest(member_types, member_refs) AS way(member_type, member_ref)
 WHERE geom IS NOT NULL
   AND member_type = 1
   AND tags ->> 'type' = 'multipolygon'
   AND NOT tags ->> 'natural' = 'coastline';
-
-CREATE INDEX osm_way_member_index ON osm_way_member(way_id);
diff --git a/map/queries/osm_ways_simplify.sql b/map/queries/osm_ways_simplify.sql
new file mode 100644
index 00000000..62a7d4f5
--- /dev/null
+++ b/map/queries/osm_ways_simplify.sql
@@ -0,0 +1,145 @@
+CREATE VIEW osm_ways_z20
+AS SELECT id, tags, geom FROM osm_ways;
+
+CREATE VIEW osm_ways_z19 AS
+SELECT id, tags, geom FROM osm_ways;
+
+CREATE VIEW osm_ways_z18 AS
+SELECT id, tags, geom FROM osm_ways;
+
+CREATE VIEW osm_ways_z17 AS
+SELECT id, tags, geom FROM osm_ways;
+
+CREATE VIEW osm_ways_z16 AS
+SELECT id, tags, geom FROM osm_ways;
+
+CREATE VIEW osm_ways_z15 AS
+SELECT id, tags, geom FROM osm_ways;
+
+CREATE VIEW osm_ways_z14 AS
+SELECT id, tags, geom FROM osm_ways;
+
+CREATE VIEW osm_ways_z13 AS
+SELECT id, tags, geom FROM osm_ways;
+
+CREATE MATERIALIZED VIEW osm_ways_z12 AS
+SELECT id, tags, geom
+FROM (
+         SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 12)) AS geom
+         FROM osm_ways
+         WHERE tags ?| ARRAY [ 'landuse', 'natural', 'power', 'railway', 'route', 'waterway' ]
+     ) AS osm_ways
+WHERE geom IS NOT NULL
+  AND (st_area(st_envelope(geom)) > power((78270 / power(2, 12)), 2));
+
+CREATE MATERIALIZED VIEW osm_ways_z11 AS
+SELECT id, tags, geom
+FROM (
+         SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 11)) AS geom
+         FROM osm_ways
+         WHERE tags ?| ARRAY ['landuse', 'natural', 'waterway' ]
+     ) AS osm_ways
+WHERE geom IS NOT NULL
+  AND (st_area(st_envelope(geom)) > power((78270 / power(2, 11)), 2));
+
+CREATE MATERIALIZED VIEW osm_ways_z10 AS
+SELECT id, tags, geom
+FROM (
+         SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 10)) AS geom
+         FROM osm_ways
+         WHERE tags ?| ARRAY ['landuse', 'natural', 'waterway' ]
+     ) AS osm_ways
+WHERE geom IS NOT NULL
+  AND (st_area(st_envelope(geom)) > power((78270 / power(2, 10)), 2));
+
+CREATE MATERIALIZED VIEW osm_ways_z9 AS
+SELECT id, tags, geom
+FROM (
+         SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 9)) AS geom
+         FROM osm_ways
+         WHERE tags ?| ARRAY ['landuse', 'natural', 'waterway' ]
+     ) AS osm_ways
+WHERE geom IS NOT NULL
+  AND (st_area(st_envelope(geom)) > power((78270 / power(2, 9)), 2));
+
+CREATE MATERIALIZED VIEW osm_ways_z8 AS
+SELECT id, tags, geom
+FROM (
+         SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 8)) AS geom
+         FROM osm_ways
+         WHERE tags ?| ARRAY ['landuse', 'natural', 'waterway' ]
+     ) AS osm_ways
+WHERE geom IS NOT NULL
+  AND (st_area(st_envelope(geom)) > power((78270 / power(2, 8)), 2));
+
+CREATE MATERIALIZED VIEW osm_ways_z7 AS
+SELECT id, tags, geom
+FROM (
+         SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 7)) AS geom
+         FROM osm_ways
+         WHERE tags ?| ARRAY ['landuse', 'natural', 'waterway' ]
+     ) AS osm_ways
+WHERE geom IS NOT NULL
+  AND (st_area(st_envelope(geom)) > power((78270 / power(2, 7)), 2));
+
+CREATE MATERIALIZED VIEW osm_ways_z6 AS
+SELECT id, tags, geom
+FROM (
+         SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 6)) AS geom
+         FROM osm_ways
+         WHERE tags ?| ARRAY ['landuse', 'natural', 'waterway' ]
+     ) AS osm_ways
+WHERE geom IS NOT NULL
+  AND (st_area(st_envelope(geom)) > power((78270 / power(2, 6)), 2));
+
+CREATE MATERIALIZED VIEW osm_ways_z5 AS
+SELECT id, tags, geom
+FROM (
+         SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 5)) AS geom
+         FROM osm_ways
+         WHERE tags ?| ARRAY ['landuse', 'natural']
+     ) AS osm_ways
+WHERE geom IS NOT NULL
+  AND (st_area(st_envelope(geom)) > power((78270 / power(2, 5)), 2));
+
+CREATE MATERIALIZED VIEW osm_ways_z4 AS
+SELECT id, tags, geom
+FROM (
+         SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 4)) AS geom
+         FROM osm_ways
+         WHERE tags ?| ARRAY ['landuse', 'natural']
+     ) AS osm_ways
+WHERE geom IS NOT NULL
+  AND (st_area(st_envelope(geom)) > power((78270 / power(2, 4)), 2));
+
+CREATE MATERIALIZED VIEW osm_ways_z3 AS
+SELECT id, tags, geom
+FROM (
+         SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 3)) AS geom
+         FROM osm_ways
+         WHERE tags ?| ARRAY ['landuse', 'natural']
+     ) AS osm_ways
+WHERE geom IS NOT NULL
+  AND (st_area(st_envelope(geom)) > power((78270 / power(2, 3)), 2));
+
+CREATE MATERIALIZED VIEW osm_ways_z2 AS
+SELECT id, tags, geom
+FROM (
+         SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 2)) AS geom
+         FROM osm_ways
+         WHERE tags ?| ARRAY ['landuse', 'natural']
+     ) AS osm_ways
+WHERE geom IS NOT NULL
+  AND (st_area(st_envelope(geom)) > power((78270 / power(2, 2)), 2));
+
+CREATE MATERIALIZED VIEW osm_ways_z1 AS
+SELECT id, tags, geom
+FROM (
+         SELECT id, tags, st_simplifypreservetopology(geom, 78270 / power(2, 1)) AS geom
+         FROM osm_ways
+         WHERE tags ?| ARRAY ['landuse', 'natural']
+     ) AS osm_ways
+WHERE geom IS NOT NULL
+  AND (st_area(st_envelope(geom)) > power((78270 / power(2, 1)), 2));
+
+
diff --git a/map/style.js b/map/style.js
index 33784cc9..ffdb0996 100644
--- a/map/style.js
+++ b/map/style.js
@@ -1,3 +1,5 @@
+import config from "./config.js";
+
 import layer from './utils/layer.js';
 
 import background from "./layers/background/style.js";
@@ -42,15 +44,15 @@ import label from './layers/point/label.js';
 export default {
     "version": 8,
     "name": "OpenStreetMapVecto",
-    "center": [6.6323, 46.5197],
-    "zoom": 14,
+    "center": config.center,
+    "zoom": config.zoom,
     "sources": {
         "baremaps": {
             "type": "vector",
-            "url": "http://localhost:9000/tiles.json"
+            "url": `${config.host}/tiles.json`
         }
     },
-    "sprite": "https://tiles.baremaps.com/sprites/osm/sprite",
+    "sprite": `${config.host}/sprites/osm/sprite`,
     "glyphs": "https://tiles.baremaps.com/fonts/{fontstack}/{range}.pbf",
     "layers": [
         background,
diff --git a/map/tileset.js b/map/tileset.js
index 713c0768..8908d145 100644
--- a/map/tileset.js
+++ b/map/tileset.js
@@ -1,3 +1,5 @@
+import config from "./config.js";
+
 import aerialway from "./layers/aerialway/tileset.js";
 import amenity from "./layers/amenity/tileset.js";
 import attraction from "./layers/attraction/tileset.js";
@@ -18,15 +20,11 @@ import waterway from "./layers/waterway/tileset.js";
 
 export default {
   "tilejson": "2.2.0",
-  "center": [
-    6.5743,
-    46.5189,
-    14.0
-  ],
+  "center": [...config.center, config.zoom],
   "minzoom": 1.0,
   "maxzoom": 14.0,
   "tiles": [
-    "http://localhost:9000/tiles/{z}/{x}/{y}.mvt"
+    `${config.host}/tiles/{z}/{x}/{y}.mvt`
   ],
   attribution: '© <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors',
   "vector_layers": [
@@ -46,7 +44,6 @@ export default {
     power,
     railway,
     route,
-    //tourism,
     waterway,
   ]
 }
diff --git a/map/workflow.js b/map/workflow.js
index ede5206e..cb2a11b8 100644
--- a/map/workflow.js
+++ b/map/workflow.js
@@ -1,3 +1,5 @@
+import config from "./config.js";
+
 export default {
   "steps": [
     {
@@ -17,14 +19,15 @@ export default {
         {
           "type": "ImportGeoPackage",
           "file": "data/natural_earth_vector/packages/natural_earth_vector.gpkg",
-          "database": "jdbc:postgresql://localhost:5432/baremaps?&user=baremaps&password=baremaps",
+          "database": config.database,
           "sourceSRID": 4326,
           "targetSRID": 3857
         },
         {
           "type": "ExecuteSql",
           "file": "queries/ne_index.sql",
-          "database": "jdbc:postgresql://localhost:5432/baremaps?&user=baremaps&password=baremaps"
+          "database": config.database,
+          "parallel": true,
         }
       ]
     },
@@ -45,7 +48,7 @@ export default {
         {
           "type": "ImportShapefile",
           "file": "data/water-polygons-split-3857/water_polygons.shp",
-          "database": "jdbc:postgresql://localhost:5432/baremaps?&user=baremaps&password=baremaps",
+          "database": config.database,
           "sourceSRID": 3857,
           "targetSRID": 3857
         },
@@ -73,19 +76,19 @@ export default {
         {
           "type": "ImportShapefile",
           "file": "data/simplified-water-polygons-split-3857/simplified_water_polygons.shp",
-          "database": "jdbc:postgresql://localhost:5432/baremaps?&user=baremaps&password=baremaps",
+          "database": config.database,
           "sourceSRID": 3857,
           "targetSRID": 3857
         },
         {
           "type": "ExecuteSql",
           "file": "queries/osm_simplified_water_index.sql",
-          "database": "jdbc:postgresql://localhost:5432/baremaps?&user=baremaps&password=baremaps"
+          "database": config.database,
         },
       ]
     },
     {
-      "id": "openstreetmap",
+      "id": "openstreetmap-data",
       "needs": [],
       "tasks": [
         {
@@ -96,53 +99,220 @@ export default {
         {
           "type": "ImportOpenStreetMap",
           "file": "data/data.osm.pbf",
-          "database": "jdbc:postgresql://localhost:5432/baremaps?&user=baremaps&password=baremaps",
+          "database": config.database,
           "databaseSrid": 3857
         },
+      ]
+    },
+    {
+      "id": "openstreetmap-nodes",
+      "needs": ["openstreetmap-data"],
+      "tasks": [
         {
           "type": "ExecuteSql",
-          "file": "queries/osm_node.sql",
-          "database": "jdbc:postgresql://localhost:5432/baremaps?&user=baremaps&password=baremaps"
+          "file": "queries/osm_nodes_clean.sql",
+          "database": config.database,
         },
         {
           "type": "ExecuteSql",
-          "file": "queries/osm_way.sql",
-          "database": "jdbc:postgresql://localhost:5432/baremaps?&user=baremaps&password=baremaps"
+          "file": "queries/osm_nodes_prepare.sql",
+          "database": config.database,
         },
         {
           "type": "ExecuteSql",
-          "file": "queries/osm_way_member.sql",
-          "database": "jdbc:postgresql://localhost:5432/baremaps?&user=baremaps&password=baremaps"
+          "file": "queries/osm_nodes_simplify.sql",
+          "database": config.database,
         },
+        {
+          "type": "ExecuteSql",
+          "file": "queries/osm_nodes_index.sql",
+          "database": config.database,
+        },
+      ]
+    },
+    {
+      "id": "openstreetmap-ways",
+      "needs": ["openstreetmap-data"],
+      "tasks": [
+        {
+          "type": "ExecuteSql",
+          "file": "queries/osm_ways_clean.sql",
+          "database": config.database,
+        },
+        {
+          "type": "ExecuteSql",
+          "file": "queries/osm_ways_prepare.sql",
+          "database": config.database,
+        },
+        {
+          "type": "ExecuteSql",
+          "file": "queries/osm_ways_simplify.sql",
+          "database": config.database,
+        },
+        {
+          "type": "ExecuteSql",
+          "file": "queries/osm_ways_index.sql",
+          "database": config.database,
+        },
+      ]
+    },
+    {
+      "id": "openstreetmap-relations",
+      "needs": ["openstreetmap-data"],
+      "tasks": [
+        {
+          "type": "ExecuteSql",
+          "file": "queries/osm_relations_clean.sql",
+          "database": config.database,
+        },
+        {
+          "type": "ExecuteSql",
+          "file": "queries/osm_relations_prepare.sql",
+          "database": config.database,
+        },
+        {
+          "type": "ExecuteSql",
+          "file": "queries/osm_relations_simplify.sql",
+          "database": config.database,
+        },
+        {
+          "type": "ExecuteSql",
+          "file": "queries/osm_relations_index.sql",
+          "database": config.database,
+        },
+      ]
+    },
+    {
+      "id": "openstreetmap-linestring",
+      "needs": ["openstreetmap-ways"],
+      "tasks": [
         {
           "type": "ExecuteSql",
           "file": "queries/osm_linestring.sql",
-          "database": "jdbc:postgresql://localhost:5432/baremaps?&user=baremaps&password=baremaps"
+          "database": config.database,
         },
+      ]
+    },
+    {
+      "id": "openstreetmap-polygon",
+      "needs": ["openstreetmap-ways", "openstreetmap-relations"],
+      "tasks": [
         {
           "type": "ExecuteSql",
-          "file": "queries/osm_polygon.sql",
-          "database": "jdbc:postgresql://localhost:5432/baremaps?&user=baremaps&password=baremaps"
+          "file": "queries/osm_polygon_prepare.sql",
+          "database": config.database,
         },
         {
           "type": "ExecuteSql",
-          "file": "queries/osm_boundary.sql",
-          "database": "jdbc:postgresql://localhost:5432/baremaps?&user=baremaps&password=baremaps"
+          "file": "queries/osm_polygon_index.sql",
+          "database": config.database,
+        },
+      ]
+    },
+    {
+      "id": "openstreetmap-boundary",
+      "needs": ["openstreetmap-linestring"],
+      "tasks": [
+        {
+          "type": "ExecuteSql",
+          "file": "queries/osm_boundary_prepare.sql",
+          "database": config.database,
         },
         {
           "type": "ExecuteSql",
-          "file": "queries/osm_highway.sql",
-          "database": "jdbc:postgresql://localhost:5432/baremaps?&user=baremaps&password=baremaps"
+          "file": "queries/osm_boundary_simplify.sql",
+          "database": config.database,
         },
         {
           "type": "ExecuteSql",
-          "file": "queries/osm_railway.sql",
-          "database": "jdbc:postgresql://localhost:5432/baremaps?&user=baremaps&password=baremaps"
+          "file": "queries/osm_boundary_index.sql",
+          "database": config.database,
         },
+      ]
+    },
+    {
+      "id": "openstreetmap-highway",
+      "needs": ["openstreetmap-linestring"],
+      "tasks": [
         {
           "type": "ExecuteSql",
-          "file": "queries/osm_relation.sql",
-          "database": "jdbc:postgresql://localhost:5432/baremaps?&user=baremaps&password=baremaps"
+          "file": "queries/osm_highway_prepare.sql",
+          "database": config.database,
+        },
+        {
+          "type": "ExecuteSql",
+          "file": "queries/osm_highway_simplify.sql",
+          "database": config.database,
+        },
+        {
+          "type": "ExecuteSql",
+          "file": "queries/osm_highway_index.sql",
+          "database": config.database,
+        },
+      ]
+    },
+    {
+      "id": "openstreetmap-railway",
+      "needs": ["openstreetmap-linestring"],
+      "tasks": [
+        {
+          "type": "ExecuteSql",
+          "file": "queries/osm_railway_prepare.sql",
+          "database": config.database,
+        },
+        {
+          "type": "ExecuteSql",
+          "file": "queries/osm_railway_simplify.sql",
+          "database": config.database,
+        },
+        {
+          "type": "ExecuteSql",
+          "file": "queries/osm_railway_index.sql",
+          "database": config.database,
+        },
+      ]
+    },
+    {
+      "id": "openstreetmap-natural",
+      "needs": ["openstreetmap-polygon"],
+      "tasks": [
+        {
+          "type": "ExecuteSql",
+          "file": "queries/osm_natural_prepare.sql",
+          "database": config.database,
+        },
+        {
+          "type": "ExecuteSql",
+          "file": "queries/osm_natural_simplify.sql",
+          "database": config.database,
+        },
+        {
+          "type": "ExecuteSql",
+          "file": "queries/osm_natural_index.sql",
+          "database": config.database,
+          "parallel": true
+        },
+      ]
+    },
+    {
+      "id": "openstreetmap-landuse",
+      "needs": ["openstreetmap-polygon"],
+      "tasks": [
+        {
+          "type": "ExecuteSql",
+          "file": "queries/osm_landuse_prepare.sql",
+          "database": config.database,
+        },
+        {
+          "type": "ExecuteSql",
+          "file": "queries/osm_landuse_simplify.sql",
+          "database": config.database,
+        },
+        {
+          "type": "ExecuteSql",
+          "file": "queries/osm_landuse_index.sql",
+          "database": config.database,
+          "parallel": true
         },
       ]
     }