package de.komoot.photon.nominatim; import de.komoot.photon.PhotonDoc; import de.komoot.photon.Updater; import de.komoot.photon.nominatim.model.UpdateRow; import org.apache.commons.dbcp.BasicDataSource; import org.postgis.jts.JtsWrapper; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; import java.util.Map; /** * Nominatim update logic * * @author felix */ public class NominatimUpdater { private static final org.slf4j.Logger LOGGER = org.slf4j.LoggerFactory.getLogger(NominatimUpdater.class); private final Integer minRank = 1; private final Integer maxRank = 30; private final JdbcTemplate template; private final NominatimConnector exporter; private Updater updater; public void setUpdater(Updater updater) { this.updater = updater; } public void update() { for(Integer rank = this.minRank; rank <= this.maxRank; rank++) { LOGGER.info(String.format("Starting rank %d", rank)); for(Map<String, Object> sector : getIndexSectors(rank)) for(UpdateRow place : getIndexSectorPlaces(rank, (Integer) sector.get("geometry_sector"))) { template.update("update placex set indexed_status = 0 where place_id = ?", place.getPlaceId()); final PhotonDoc updatedDoc = exporter.getByPlaceId(place.getPlaceId()); switch(place.getIndexdStatus()) { case 1: if(updatedDoc.isUsefulForIndex()) updater.create(updatedDoc); break; case 2: if(!updatedDoc.isUsefulForIndex()) updater.delete(place.getPlaceId()); updater.updateOrCreate(updatedDoc); break; case 100: updater.delete(place.getPlaceId()); break; default: LOGGER.error(String.format("Unknown index status %d", place.getIndexdStatus())); break; } } } updater.finish(); } private List<Map<String, Object>> getIndexSectors(Integer rank) { return template.queryForList("select geometry_sector,count(*) from placex where rank_search = ? " + "and indexed_status > 0 group by geometry_sector order by geometry_sector;", rank); } private List<UpdateRow> getIndexSectorPlaces(Integer rank, Integer geometrySector) { return template.query("select place_id, indexed_status from placex where rank_search = ?" + " and geometry_sector = ? and indexed_status > 0;", new Object[]{rank, geometrySector}, new RowMapper<UpdateRow>() { @Override public UpdateRow mapRow(ResultSet rs, int rowNum) throws SQLException { UpdateRow updateRow = new UpdateRow(); updateRow.setPlaceId(rs.getLong("place_id")); updateRow.setIndexdStatus(rs.getInt("indexed_status")); return updateRow; } }); } /** */ public NominatimUpdater(String host, int port, String database, String username, String password) { BasicDataSource dataSource = new BasicDataSource(); dataSource.setUrl(String.format("jdbc:postgresql://%s:%d/%s", host, port, database)); dataSource.setUsername(username); dataSource.setPassword(password); dataSource.setDriverClassName(JtsWrapper.class.getCanonicalName()); dataSource.setDefaultAutoCommit(false); exporter = new NominatimConnector(host, port, database, username, password); template = new JdbcTemplate(dataSource); } }