package ru.exorg.backend.services;
import org.apache.lucene.document.Document;
import java.util.ArrayList;
import java.util.List;
import ru.exorg.core.model.Description;
import ru.exorg.core.model.POI;
import ru.exorg.core.lucene.Search;
import ru.exorg.core.lucene.DocMapper;
import ru.exorg.core.lucene.*;
/**
* Created by IntelliJ IDEA.
* User: lana
* Date: 23.04.11
* Time: 1:43
* To change this template use File | Settings | File Templates.
*/
public class PoiService {
private String sphinx_host;
private int sphinx_port;
private Search searcher;
private POIMapper poiMapper;
private static final int Id = 1;
private static final int Name = 2;
private static final int Type = 3;
private static final int Address = 4;
private static final int Description = 5;
private static final int Description_url = 6;
private static final int Img_url = 7;
private static final int Lat = 8;
private static final int Lng = 9;
private static final int Cluster_id = 10;
private static final int Is_head = 11;
private static final int Square_num = 12;
final private static String POIFields =
"id, name, type, address, descr, descr_ref, img_url, lat, lng, cluster_id, is_head, square_num";
private static class POIMapper implements DocMapper<POI> {
public POI mapDoc(Document doc) {
POI poi = new POI(doc.get("id"), doc.get("name"));
poi.setAddress(doc.get("address"));
poi.setLocation(doc.get("lat"), doc.get("lng"));
poi.setClusterId(doc.get("clusterId"));
poi.setClusterHeadFlag(doc.get("isClusterHead"));
poi.setSquareId(doc.get("squareId"));
String s = doc.get("description");
if (s != null) {
poi.addDescription(s, doc.get("descriptionURL"));
}
s = doc.get("imageURL");
if (s != null) {
poi.addImage(s);
} else {
poi.addImage("");
}
return poi;
}
}
public PoiService() {
this.poiMapper = new POIMapper();
}
public void setSearcher(Search s) {
this.searcher = s;
}
public List<POI> getPoiListByType(final String type) throws Exception {
return this.searcher.search(String.format("type: %s", type), this.poiMapper);
}
public POI getPoiById(long poiId) {
try {
POI poi = getRawPoiById(poiId);
if (poi == null) {
System.out.println("Epic Fail: no POI :(");
}
if (poi.getId() != 0)
{
List<POI> clusteredPois = getClusteredPoiList(poi.getClusterId());
for(POI p: clusteredPois)
{
if (p.getId() != poi.getId()) {
if ((poi.getLocation().getLat() < 0) && (p.getLocation().getLat() > 0)) //hasLocation ??
{
poi.setLocation(p.getLocation().getLat(), p.getLocation().getLng());
}
if ((!poi.hasAddress()) && (p.hasAddress()))
{
poi.setAddress(p.getAddress());
}
/*
if ((poi.getURL().equals("")) && (!p.getURL().equals("")) )
{
System.out.println("getPoiById: update URL " + p.getURL());
poi.setURL(p.getURL());
}
*/
if (p.getDescriptions().size() > 0)
{
for (Description descr: p.getDescriptions())
{
poi.addDescription(descr);
}
}
if (p.getImages().size() > 0)
{
for (String imageUrl: p.getImages())
{
poi.addImage(imageUrl);
}
}
}
}
}
return poi;
} catch (Exception e) {
System.out.println("Querying POI " + String.valueOf(poiId) + " failed");
//e.printStackTrace();
return null;
}
}
public List<POI> getClusteredPoiList(long clusterId)
{
try {
return this.searcher.search(String.format("clusterId: %d", clusterId), this.poiMapper);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
private POI getRawPoiById(long id) throws Exception {
try {
String q = String.format("DocType:\"%s\" AND id:%d", Indexer.DocTypePOI, id);
System.out.println("Querying: " + q);
return this.searcher.search(q, this.poiMapper).get(0);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
private int[] getNearestSquares(int square, int rows, int columns)
{
int[] squares = new int[8];
int lastIndex = -1;
if (square%columns != 0)
{
squares[++lastIndex] = square -1;
}
if ((square - columns) >= 0)
{
squares[++lastIndex] = square - columns;
if (square%columns != columns-1)
{
squares[++lastIndex] = square - columns + 1;
}
if (square%columns != 0)
{
squares[++lastIndex] = square - columns -1;
}
}
if ((square + columns) <= (columns-1)*(rows-1))
{
squares[++lastIndex] = square + columns;
if (square%columns != columns-1)
{
squares[++lastIndex] = square + columns + 1;
}
if (square%columns != 0)
{
squares[++lastIndex] = square + columns -1;
}
}
if (square%columns != (columns - 1))
{
squares[++lastIndex] = square + 1;
}
if (lastIndex < 7)
{
int[] sqs = new int[lastIndex+1];
for (int i = 0; i <= lastIndex; ++i)
{
sqs[i] = squares[i];
}
return sqs;
}
return squares;
}
private List<POI> getPoisFromSquare(int square) throws Exception {
return this.searcher.search(String.format("squareId: %d", square), this.poiMapper);
}
public List<POI> getNearestPois(long poiId) throws Exception {
List<POI> pois = new ArrayList<POI>();
POI poi = getRawPoiById(poiId);
if (poi.getId() != 0)
{
int[] squares = getNearestSquares(poi.getSquareId(), 20, 20); //hack, because we should take info about cols and rows from db or index
for (int i = 0; i < squares.length -1; ++i)
{
pois.addAll(getPoisFromSquare(squares[i]));
}
}
return pois;
}
}