/**
* ShareNav - Copyright (c) 2009 Kai Krueger apmonkey at users dot sourceforge dot net
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* See COPYING
*/
package net.sharenav.osmToShareNav;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Vector;
import net.sharenav.osmToShareNav.model.Bounds;
public class CellDB {
public class Cell {
int id;
double lat;
double lon;
int mcc;
int mnc;
int lac;
int cellid;
@Override
public String toString() {
return "Cell MCC: " + mcc + " MNC: " + mnc + " LAC: " + lac
+ " CellID: " + cellid + " (" + lat + "|" + lon + ")";
}
}
public void parseCellDB() {
HashMap<Long, ArrayList<Cell>> cells = new HashMap<Long, ArrayList<Cell>>();
int noInvalid = 0;
int noValid = 0;
int mcc = 0;
int mnc = 0;
Configuration conf = Configuration.getConfiguration();
Vector<Bounds> bounds = conf.getBounds();
/*
* Determine if we should filter the cellIDs according to a country code
* or network operator code. by specifying e.g. useCellID=234,10 the
* file will only contain cells from country code 234 (UK) and operator
* 10 (O2)
*/
String cellConf = conf.getCellOperator();
if (!cellConf.equalsIgnoreCase("true")) {
String[] cellConfSplit = cellConf.split(",");
try {
switch (cellConfSplit.length) {
case 1:
mcc = Integer.parseInt(cellConfSplit[0]);
break;
case 2:
mcc = Integer.parseInt(cellConfSplit[0].trim());
mnc = Integer.parseInt(cellConfSplit[1].trim());
break;
default:
System.out
.println("Can't interpret useCellID properties. Skipping CellIDs");
return;
}
} catch (NumberFormatException nfe) {
System.out
.println("Can't interpret useCellID properties. Skipping CellIDs");
return;
}
}
System.out.println("Scanning CellIDs in the area");
try {
BufferedReader r = new BufferedReader(new InputStreamReader(conf
.getCellStream()));
if (r == null) {
System.out.println("WARNING: could not find cellID file, NOT including cell ids");
return;
}
while (true) {
String line = null;
try {
line = r.readLine();
if (line == null) {
break;
}
} catch (EOFException eof) {
break;
}
String[] cellString = line.split(",");
if (cellString == null || cellString.length != 12) {
System.out.println("Invalid line in cellID file "
+ cellString);
}
try {
Cell c = new Cell();
c.id = Integer.parseInt(cellString[0]);
c.lat = Double.parseDouble(cellString[1]);
c.lon = Double.parseDouble(cellString[2]);
c.mcc = Integer.parseInt(cellString[3]);
c.mnc = Integer.parseInt(cellString[4]);
c.lac = Integer.parseInt(cellString[5]);
c.cellid = Integer.parseInt(cellString[6]);
Integer.parseInt(cellString[8]); // NoSample
boolean isIn = false;
if (bounds != null && bounds.size() != 0) {
for (Bounds bound : bounds) {
if (bound.isIn(c.lat, c.lon)) {
isIn = true;
continue;
}
}
} else {
isIn = true;
}
if (!isIn) {
continue;
}
if ((c.mcc > 65000) || (c.mnc > 65000)) {
noInvalid++;
continue;
}
if (((mcc != 0) && (mcc != c.mcc))
|| ((mnc != 0) && (mnc != c.mnc))) {
// This cell is not for our operator
continue;
}
if ((c.lac < 0) || (c.cellid < 0)) {
noInvalid++;
continue;
}
long key = (c.mcc << 48) + (c.mnc << 32) + c.lac;
ArrayList<Cell> lacCells = cells.get(key);
if (lacCells == null) {
lacCells = new ArrayList<Cell>();
cells.put(new Long(key), lacCells);
}
lacCells.add(c);
noValid++;
} catch (NumberFormatException nfe) {
}
}
System.out.println("Found " + noValid
+ " cellIDs in this area and ignored " + noInvalid);
File f;
// File f = new File(conf.getTempDir() + "/cellids/");
// f.mkdir();
/**
* Write out cellIDs into files based on MCC, MNC and LAC.
* Given that OpenCellID.org isn't complete, there are still
* quite a few LACs for which there is only a single cell in the
* db. In order to reduce the number of small files, we combine
* all LACs with less than 20 cells into a big operator file.
* If CellIDnoLOC option is set, write all cell id data
* into the file with no LAC in the name, for the benefit
* of users of Nokia and LG phones which can't get the LAC code.
*/
for (ArrayList<Cell> lacCells : cells.values()) {
Cell c = lacCells.get(0);
DataOutputStream dos = null;
if (conf.getCellIDnoLAC() || lacCells.size() < 20) {
String fname = conf.getTempDir() + "/c" + c.mcc + c.mnc
+ ".id";
if (conf.sourceIsApk) {
fname = conf.getTempDir() +
"/assets" + "/c" + c.mcc + c.mnc
+ ".id";
}
f = new File(fname);
if (!f.exists()) {
f.createNewFile();
}
dos = new DataOutputStream(new FileOutputStream(f, true));
for (Cell c2 : lacCells) {
dos.writeInt(c2.lac);
dos.writeInt(c2.cellid);
dos.writeFloat((float) c2.lat);
dos.writeFloat((float) c2.lon);
}
dos.close();
}
if (lacCells.size() >= 20) {
String fname = conf.getTempDir() + "/c" + c.mcc + c.mnc
+ c.lac + ".id";
if (conf.sourceIsApk) {
fname = conf.getTempDir() +
"/assets" + "/c" + c.mcc + c.mnc
+ c.lac + ".id";
}
f = new File(fname);
f.createNewFile();
dos = new DataOutputStream(new FileOutputStream(f));
for (Cell c2 : lacCells) {
dos.writeInt(c2.lac);
dos.writeInt(c2.cellid);
dos.writeFloat((float) c2.lat);
dos.writeFloat((float) c2.lon);
}
dos.close();
}
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
System.out.println("WARNING: Could not find CellID file, NOT including cell ids");
e.printStackTrace();
}
}
}