@Override
  public void readFeatures(Consumer<SimpleFeature> next) throws Exception {
    long id = 0;
    // pass every element in every table through the profile
    var tables = tableNames();
    for (int i = 0; i < tables.size(); i++) {
      String table = tables.get(i);
      LOGGER.trace("Naturalearth loading {}/{}: {}", i, tables.size(), table);

      try (Statement statement = conn.createStatement()) {
        @SuppressWarnings("java:S2077") // table name checked against a regex
        ResultSet rs = statement.executeQuery("SELECT * FROM %s;".formatted(table));
        String[] column = new String[rs.getMetaData().getColumnCount()];
        int geometryColumn = -1;
        for (int c = 0; c < column.length; c++) {
          String name = rs.getMetaData().getColumnName(c + 1);
          column[c] = name;
          if ("GEOMETRY".equals(name)) {
            geometryColumn = c;
          }
        }
        if (geometryColumn >= 0) {
          var wkbReader = GeoUtils.wkbReader();
          while (rs.next()) {
            byte[] geometry = rs.getBytes(geometryColumn + 1);
            if (geometry == null) {
              continue;
            }

            // create the feature and pass to next stage
            Geometry latLonGeometry = wkbReader.read(geometry);
            SimpleFeature readerGeometry = SimpleFeature.create(latLonGeometry, HashMap.newHashMap(column.length - 1),
              sourceName, table, ++id);
            for (int c = 0; c < column.length; c++) {
              if (c != geometryColumn) {
                Object value = rs.getObject(c + 1);
                String key = column[c];
                readerGeometry.setTag(key, value);
              }
            }
            next.accept(readerGeometry);
          }
        }
      }
    }
  }
Returns a JDBC connection to the sqlite file. Input can be the sqlite file itself or a zip file containing it.
planetiler-core/src/main/java/com/onthegomap/planetiler/reader/NaturalEarthReader.java