package me.osm.gazetter.join.out_handlers; import java.io.BufferedWriter; import java.io.IOException; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import org.apache.commons.io.output.NullWriter; import org.apache.commons.lang3.StringUtils; import org.json.JSONObject; /** * Allow to pass line handler into external libraries * * <b>IMPORTANT</b> this feature is experimental, and * work only with ExternalSorting lib. * * */ public final class HgnetMergerFakeWriter extends BufferedWriter { private List<String> batch = new ArrayList<>(); private String lastH = null; private GazetteerOutWriter gazetteerOutWriter; /** * @param gazetteerOutWriter */ public HgnetMergerFakeWriter(GazetteerOutWriter gazetteerOutWriter) { super(new NullWriter()); this.gazetteerOutWriter = gazetteerOutWriter; } private void mergeBatch(List<String> netBatch) { JSONObject baseFeature = null; Set<String> members = new HashSet<>(100); Set<JSONObject> geometries = new HashSet<>(100); Set<String> geometryIds = new HashSet<>(100); for(String s : netBatch) { JSONObject obj = new JSONObject(s); if(baseFeature == null) { baseFeature = obj; } for(int i = 0; i < obj.getJSONArray("members").length(); i++) { members.add(obj.getJSONArray("members").getString(i)); } if(geometries != null) { for(int i = 0; i < obj.getJSONArray("geometries").length(); i++) { JSONObject g = obj.getJSONArray("geometries").getJSONObject(i); if(g != null && geometryIds.add(g.getString("id"))) { geometries.add(g); } } } } baseFeature.put("members", members); baseFeature.put("geometries", geometries); /* TODO: Проблема, даже если дороги не соединены, но находятся в пределах * одного набора границ, и имеют одинаковые имена - они будут склеены. * * Можно на этапе джоина, когда мы создаем треды, доставать эндпоинты * и добавлять построенный на них хеш к айдишке сети. * * Но я побаиваюсь накосячить с таким подходом и выкинуть лишнего. */ writeOut(baseFeature.toString()); } private void writeOut(String string) { gazetteerOutWriter.writeMergedHGHNET(string); } @Override public void write(String str) throws IOException { int indexOf = StringUtils.indexOf(str, '\t'); if(indexOf >= 0) { String htag = str.substring(0, indexOf); String json = str.substring(indexOf + 1, str.length()); if(lastH == null) { lastH = htag; } else { if(lastH.equals(htag) || batch.isEmpty()) { batch.add(json); } else if(!batch.isEmpty()) { if(batch.size() == 1) { writeOut(batch.get(0)); } else { mergeBatch(batch); } batch.clear(); batch.add(json); } } lastH = htag; } } @Override public void newLine() throws IOException { } @Override public void flush() throws IOException { } @Override public void close() throws IOException { if(!batch.isEmpty()) { if(batch.size() == 1) { writeOut(batch.get(0)); } else { mergeBatch(batch); } } } }