/** * This file is part of OSM2ShareNav * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as published by * the Free Software Foundation. * * Copyright (C) 2007 Harald Mueller * Copyright (C) 2008 Kai Krueger * */ package net.sharenav.osmToShareNav; import java.io.DataOutputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import net.sharenav.osmToShareNav.model.Bounds; import net.sharenav.osmToShareNav.model.Entity; import net.sharenav.osmToShareNav.model.Node; import net.sharenav.osmToShareNav.model.Way; import net.sharenav.osmToShareNav.model.name.Name; import net.sharenav.osmToShareNav.model.name.Names; import net.sharenav.osmToShareNav.model.name.WayRedirect; import net.sharenav.osmToShareNav.model.url.Url; import net.sharenav.osmToShareNav.model.url.Urls; import net.sharenav.osmToShareNav.tools.FileTools; /** * @author hmueller * */ public class SearchList { Names names; Urls urls; WayRedirect wayRedirect; public static final int INDEX_NAME = 0; public static final int INDEX_WORD = 1; public static final int INDEX_WHOLEWORD = 2; public static final int INDEX_HOUSENUMBER = 3; public static final int INDEX_BIGNAME = 4; public static final int FLAG_NODE = 0x80; public static final int FLAG_URL = 0x40; public static final int FLAG_PHONE = 0x20; public SearchList(Names names, Urls urls, WayRedirect wayRedirect) { super(); this.names = names; this.urls = urls; this.wayRedirect = wayRedirect; } public void createSearchList(String path, int listType){ try { FileOutputStream fo = null; DataOutputStream ds = null; String lastStr = null; String lastFid = ""; int curPos = 0; FileTools.createPath(new File(path + "/search")); for (Name mapName : ((listType == INDEX_NAME || listType == INDEX_BIGNAME) ? names.getCanons() : (listType == INDEX_WORD ? names.getWordCanons() : (listType == INDEX_WHOLEWORD ? names.getWholeWordCanons() : names.getHouseNumberCanons())))) { String string=mapName.getCanonFileName(mapName.getCanonFileId()); int eq=names.getEqualCount(string,lastStr); if (! lastFid.equals(mapName.getCanonFileId())) { if (ds != null) { ds.close(); } lastFid = mapName.getCanonFileId(); String fileName = path + (listType == INDEX_BIGNAME ? "/search/n" : (listType == INDEX_NAME ? "/search/s" : (listType == INDEX_WORD ? "/search/w" : (listType == INDEX_WHOLEWORD ? "/search/ww" : "/search/h")))) + lastFid + ".d"; //System.out.println("open " + fileName); fo = new FileOutputStream(fileName); ds = new DataOutputStream(fo); curPos = 0; eq = 0; lastStr = null; } String wrString = string.substring(eq); /** * Encoding of delta plus flags in bits: * 10000000 Sign bit * 01100000 long * 01000000 int * 00100000 short * 00000000 byte * 000xxxxx delta */ int delta = eq-curPos; if (Math.abs(delta) > 30) { System.out.println("Error: Overflow in Search cannon: " + mapName.getName()); } if (delta <0){ delta = -delta; delta += 0x80; } long l=0; if (wrString.length() > 0) l = Long.parseLong(wrString); if (l < Byte.MAX_VALUE){ // System.out.println("byte " + (delta) + " " + (byte) delta + " '" +string.substring(eq)+"' '"+mapName); ds.writeByte(delta); ds.writeByte((int) l); } else if (l < Short.MAX_VALUE){ // System.out.println("short " + (delta) + " " + (byte) delta + " '" +string.substring(eq)+"' '"+mapName); ds.writeByte(delta | 0x20); ds.writeShort((int) l); } else if (l < Integer.MAX_VALUE){ // System.out.println("int " + (delta) + " " + (byte) delta + " '" +string.substring(eq)+"' '"+mapName); ds.writeByte(delta | 0x40); ds.writeInt((int) l); } else { // System.out.println("long " + (delta) + " " + (byte) delta + " '" +string.substring(eq)+"' '"+mapName); ds.writeByte(delta| 0x60); ds.writeLong(l); } int nameIdx = mapName.getIndex(); int primaryNameIdx = nameIdx; if (nameIdx >= Short.MAX_VALUE) { ds.writeInt(nameIdx | 0x80000000); } else { ds.writeShort(nameIdx); } for (Entity e : mapName.getEntitys()){ int isInFlags = 0; Node center=null; String url = null; String phone = null; String name = null; long idtowrite = 0; if (e instanceof Node) { idtowrite = ((Node) e).id; } if (e instanceof Way) { idtowrite = ((Way) e).id; } if (listType != INDEX_NAME && Configuration.getConfiguration().useHouseNumbers) { // write way id for matching housenumber to streetname //System.out.println ("listType == 3, testing node " + n); //System.out.println ("type was: " + n.getType(Configuration.getConfiguration())); String wayid = e.getAttribute("__wayid"); if (wayid != null) { long way = Long.parseLong(wayid); //System.out.println ("Found housenumber node wayid:" + wayid + "(" + way + ")" ); idtowrite = way; } } if (e instanceof Node) { Node n = (Node) e; url = n.getUrl(); phone = n.getPhone(); name = n.getName(); if (Configuration.getConfiguration().map66search) { isInFlags |= FLAG_NODE; } // polish.api.bigstyles if (Configuration.getConfiguration().bigStyles) { ds.writeShort(n.getType(Configuration.getConfiguration())); } else { if (Configuration.getConfiguration().map66search) { ds.writeByte(n.getType(Configuration.getConfiguration())); } else { ds.writeByte(-1*n.getType(Configuration.getConfiguration())); } } center=n; //System.out.println("entryType " + n.getNameType() + " idx=" + mapName.getIndex()); } if (e instanceof Way) { Way w = (Way) e; url = w.getUrl(); phone = w.getPhone(); name = w.getName(); // //ds.writeByte(w.getNameType()); // polish.api.bigstyles if (Configuration.getConfiguration().bigStyles) { ds.writeShort(w.getType(Configuration.getConfiguration())); } else { ds.writeByte(w.getType(Configuration.getConfiguration())); } // System.out.println("entryType " + w.getNameType() + " idx=" + mapName.getIndex()); center=w.getMidPoint(); } int urlIdx = urls.getUrlIdx(url); int phoneIdx = urls.getUrlIdx(phone); if (urlIdx == -1) { urlIdx = 0; } if (phoneIdx == -1) { phoneIdx = 0; } if (Configuration.getConfiguration().map66search) { if (urlIdx != 0 && Configuration.getConfiguration().useUrlTags) { isInFlags |= FLAG_URL; } if (phoneIdx != 0 && Configuration.getConfiguration().usePhoneTags) { isInFlags |= FLAG_PHONE; } } // write id for housenumber or multi-word matching if (listType != INDEX_NAME) { Long idLong = new Long(idtowrite); // check if this is redirected to another way segment with the same name // due to space & search result conservation //System.out.println("Checking redirect for id " + idtowrite); Long targetLong = wayRedirect.get(idLong); if (targetLong != null) { long target = wayRedirect.get(idLong).longValue(); //System.out.println("Doing redirect from id " + idtowrite + " to " + target); if (target != (long) 0) { idtowrite = target; } } ds.writeLong(idtowrite); } ArrayList<Entity> isIn=new ArrayList<Entity>(); Entity nb=e.nearBy; while (nb != null && !isIn.contains(nb)){ if (nb.getName() != null) isIn.add(nb); nb=nb.nearBy; } int isInSize = isIn.size(); if (Configuration.getConfiguration().map66search) { isInSize |= isInFlags; } ds.writeByte(isInSize & 0xff); for (Entity e1 : isIn){ int isinIdx = names.getNameIdx(e1.getName()); if (isinIdx < 0) { System.out.println("Invalid isin (" + e1 + ") for Entety " + e + " with Name \"" + e1.getName() + "\""); } if (isinIdx >= Short.MAX_VALUE) { ds.writeInt(isinIdx | 0x80000000); } else { ds.writeShort(isinIdx); } } if (center == null){ System.out.println("no center for searchList for "+e); center=new Node(0f,0f,-1); } ds.writeFloat(MyMath.degToRad(center.lat)); ds.writeFloat(MyMath.degToRad(center.lon)); int entityNameIdx = names.getNameIdx(name); // System.out.println("in entity, name: " + name); // System.out.println("in entity, entityNameIdx: " + entityNameIdx); if (entityNameIdx != -1) { nameIdx = entityNameIdx; } else { nameIdx = primaryNameIdx; } if (nameIdx >= Short.MAX_VALUE) { ds.writeInt(nameIdx | 0x80000000); } else { ds.writeShort(nameIdx); } if (Configuration.getConfiguration().useUrlTags) { if (!Configuration.getConfiguration().map66search || urlIdx != 0) { if (urlIdx >= Short.MAX_VALUE) { // FIXME a flag somewhere to save space? ds.writeInt(urlIdx | 0x80000000); } else { ds.writeShort(urlIdx); } } } if (Configuration.getConfiguration().usePhoneTags) { if (!Configuration.getConfiguration().map66search || phoneIdx != 0) { if (phoneIdx >= Short.MAX_VALUE) {// FIXME a flag somewhere to save space? ds.writeInt(phoneIdx | 0x80000000); } else { ds.writeShort(phoneIdx); } } } } // polish.api.bigstyles if (Configuration.getConfiguration().bigStyles) { ds.writeShort(0); } else { ds.writeByte(0); } // ds.writeUTF(string.substring(eq)); curPos=eq; lastStr=string; } if (ds != null) ds.close(); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void createNameList(String path) { // names1 = getNames1(); try { FileOutputStream fo = null; DataOutputStream ds = null; FileOutputStream foi = new FileOutputStream(path + "/dat/names-idx.dat"); DataOutputStream dsi = new DataOutputStream(foi); String lastStr = null; fo = new FileOutputStream(path + "/dat/names-0.dat"); ds = new DataOutputStream(fo); int curPos = 0; int idx = 0; short fnr = 1; short fcount = 0; for (Name mapName : names.getNames()) { String string = mapName.getName(); int eq = names.getEqualCount(string, lastStr); if (ds.size() > Configuration.getConfiguration().maxTileSize) { dsi.writeInt(idx); if (ds != null) { ds.close(); } fo = new FileOutputStream(path + "/dat/names-" + fnr + ".dat"); ds = new DataOutputStream(fo); // System.out.println("wrote names " + fnr + " with "+ fcount + " names"); fnr++; curPos = 0; eq = 0; fcount = 0; lastStr = null; } ds.writeByte(eq - curPos); ds.writeUTF(string.substring(eq)); // ds.writeShort(getWayNameIndex(mapName.getIs_in(), null)); // System.out.println("" + (eq-curPos) + "'" +string.substring(eq) + "' '" + string); curPos = eq; lastStr = string; idx++; fcount++; // ds.writeUTF(string); } dsi.writeInt(idx); ds.close(); dsi.close(); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }