/************************************************************************************ * Copyright (C) 2008 by Politehnica University of Bucharest and Rutgers University * All rights reserved. * Refer to LICENSE for terms and conditions of use. ***********************************************************************************/ package vnsim.map.object; /** * @author Victor-Radu */ import java.util.ArrayList; import vnsim.applications.trafficview.SimulatedCarInfo; import vnsim.core.Engine; import vnsim.map.utils.GPSutil; public class PeanoKey implements Comparable, java.io.Serializable { /** serialVersionUID */ private static final long serialVersionUID = -5883719321862303634L; protected byte[] value = new byte[19]; protected int roadIndex; protected int pointIndex; //added to optimize the search of nearby cars protected transient ArrayList cars = null; /** * @param value * @param roadIndex * @param pointIndex */ public PeanoKey(Point p){ int i; byte[] latitude = parseCoord(p.latitude, 9); byte[] longitude = parseCoord(p.longitude, 10); for (i = 0; i < 9; i++) { this.value[2 * i] = longitude[i]; this.value[2 * i + 1] = latitude[i]; } this.value[2 * i] = longitude[i]; } public PeanoKey(Point p, int roadIndex, int pointIndex) { //computes a peano key from a point, the value array is obtained //interleaving the point's latitude and longitude digits //19, 10 (longitude), 9 (latitude) byte[] latitude = parseCoord(p.latitude, 9); byte[] longitude = parseCoord(p.longitude, 10); //System.out.println(new String(longitude)); int i; this.roadIndex = roadIndex; this.pointIndex = pointIndex; for (i = 0; i < 9; i++) { this.value[2 * i] = longitude[i]; this.value[2 * i + 1] = latitude[i]; } this.value[2 * i] = longitude[i]; } public int compareTo(PeanoKey pk) { int i = 0; while (i < value.length && this.value[i] == pk.value[i]) i++; if (i < value.length) return this.value[i] - pk.value[i]; else return 0; } // Used for searching the sorted peano keys vector, for cars in a certain range // See the way the vector is sorted by interleaving digits public void setToUpperCorner(PeanoKey reference) { boolean trig = false; for (int i = 0; i < value.length; i++){ if (trig){ value[i] = 9; }else if (value[i] != reference.value[i]){ trig = true; } } } public void setToLowerCorner(PeanoKey reference) { boolean trig = false; for (int i = 0; i < value.length; i++) { if (trig) { value[i] = -9; } else if (value[i] != reference.value[i]) { trig = true; } } } public String toString() { StringBuffer sb = new StringBuffer(); sb.append("["); sb.append((char)this.value[0]); sb.append((char)this.value[1]); for (int i = 2; i < value.length; i++) sb.append((char)(Math.abs(this.value[i])+'0')); // sb.append(" - "); // sb.append(this.roadIndex); // sb.append(", "); // sb.append(this.pointIndex); sb.append("]"); return sb.toString(); } private byte[] parseCoord(double coord, int digitno) { //digitno can be 10 for longitude or 9 for latitude byte[] result = new byte[digitno]; int coef = 0; if (coord>0){ result[0] = '+'; coef = 1; }else{ result[0] = '-'; coord = - coord; coef = -1; } int c = (int)(coord * 1e6); for (int i=digitno-1; i>0; i--){ result[i] = (byte)((c%10)*coef); c /= 10; } return result; } public int getPointIndex() { return pointIndex; } public void setPointIndex(int pointIndex) { this.pointIndex = pointIndex; } public int getRoadIndex() { return roadIndex; } public void setRoadIndex(int roadIndex) { this.roadIndex = roadIndex; } public byte[] getValue() { return value; } public void setValue(byte[] value) { this.value = value; } PeanoKey maxpk = null; PeanoKey minpk = null; public void addCar(SimulatedCarInfo car) { if (cars == null) { cars = new ArrayList(); } if (maxpk == null || minpk == null) { Road r = Globals.map.roads.get(roadIndex); Point p = r.points.get(pointIndex); maxpk = GPSutil.getMaxSearchBoundPK(p, 2 * Engine.WIRELESS_RANGE); minpk = GPSutil.getMaxSearchBoundPK(p,- 2 * Engine.WIRELESS_RANGE); } cars.add(car); } public void removeCar(SimulatedCarInfo car) { if (cars == null) return; cars.remove(car); if (cars.size() == 0) cars = null; } public ArrayList getCars() { return cars; } public PeanoKey getMaxpk() { return maxpk; } public PeanoKey getMinpk() { return minpk; } public void setMaxpk(PeanoKey maxpk) { this.maxpk = maxpk; } public void setMinpk(PeanoKey minpk) { this.minpk = minpk; } }