Commit 1805e61f authored by David Johnson's avatar David Johnson

More changes to handle new wifi stuff, including support for zooming on

maps, changing building floors, etc.  Also revamped the applet to work
with all the new stuff.
parent ed47be9c
This diff is collapsed.
This diff is collapsed.
/*
* Dataset.java
*
* Created on July 7, 2006, 2:53 PM
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/
import java.util.*;
/**
*
* @author david
*/
public class Dataset {
public String name;
public String building;
public int[] floor;
public int[] scale;
public float[] scaleFactor;
public String image_path;
public float[] ppm;
public String positionFile;
public String dataFile;
public MapDataModel model;
public Hashtable bgImages;
public GenericWirelessData data;
public NodePosition positions;
public Dataset(String name,String positionFile,String dataFile,
String building,int floor,String image_path,float ppm) {
this.name = name;
this.building = building;
this.floor = new int[1];
this.floor[0] = floor;
this.image_path = image_path;
this.ppm = new float[1];
this.ppm[0] = ppm;
this.scale = new int[1];
this.scale[0] = 1;
this.scaleFactor = new float[1];
this.scaleFactor[0] = 1;
this.positionFile = positionFile;
this.dataFile = dataFile;
this.bgImages = new Hashtable();
}
public Dataset() {
this.name = null;
this.building = null;
this.floor = null;
this.image_path = null;
this.scale = null;
this.scaleFactor = null;
this.ppm = null;
this.positionFile = null;
this.dataFile = null;
this.bgImages = new Hashtable();
}
// We only don't take the building argument because I postulate that
// it will never be the case that we have statistics from between
// buildings. For me, one building per dataset is good enough for our
// needs into the foreseeable future... just like 64k. :-)
public java.awt.Image getImage(int floor,int scale) {
System.err.println("getting image for building="+this.building+",floor="+floor+",scale="+scale);
String tag = "" + floor + "-" + scale;
return (java.awt.Image)this.bgImages.get(tag);
}
public void addImage(java.awt.Image img,int floor,int scale) {
System.err.println("adding image for building="+this.building+",floor="+floor+",scale="+scale);
String tag = "" + floor + "-" + scale;
this.bgImages.put(tag,img);
}
public float getScaleFactor(int scale) {
if (this.scale != null) {
int i;
for (i = 0; i < this.scale.length; ++i) {
if (this.scale[i] == scale) {
break;
}
}
if (i != this.scale.length) {
return this.scaleFactor[i];
}
}
return 1.0f;
}
public void addFloor(int f) {
int[] tmp;
if (this.floor == null) {
tmp = new int[1];
tmp[1] = f;
this.floor = tmp;
}
else {
// check and see if it's already in the array:
for (int i = 0; i < this.floor.length; ++i) {
if (this.floor[i] == f) {
return;
}
}
tmp = new int[this.floor.length+1];
System.arraycopy(this.floor,0,tmp,0,this.floor.length);
tmp[this.floor.length] = f;
this.floor = tmp;
}
}
public void addScale(int f) {
int[] tmp;
if (this.scale == null) {
tmp = new int[1];
tmp[1] = f;
this.scale = tmp;
}
else {
tmp = new int[this.scale.length+1];
System.arraycopy(this.scale,0,tmp,0,this.scale.length);
tmp[this.scale.length] = f;
this.scale = tmp;
}
}
}
...@@ -32,7 +32,7 @@ public class GenericLinkStats { ...@@ -32,7 +32,7 @@ public class GenericLinkStats {
public void addStat(String statName,Object stat) { public void addStat(String statName,Object stat) {
stats.put(statName,stat); stats.put(statName,stat);
System.out.println("GLS: added "+recvNode+" <- "+sendNode+", "+statName+"="+stat); //System.out.println("GLS: added "+recvNode+" <- "+sendNode+", "+statName+"="+stat);
} }
public void addMetaStat(String statName,String metaName,Object stat) { public void addMetaStat(String statName,String metaName,Object stat) {
...@@ -61,7 +61,7 @@ public class GenericLinkStats { ...@@ -61,7 +61,7 @@ public class GenericLinkStats {
float myTicks = 100/(max-min); float myTicks = 100/(max-min);
float myPercent = (myValue - min)*myTicks; float myPercent = (myValue - min)*myTicks;
System.out.println("GPOPR: statName="+statName+"min="+min+",max="+max+",myValue="+myValue+",myTicks="+myTicks+"myPercent="+myPercent); //System.out.println("GPOPR: statName="+statName+"min="+min+",max="+max+",myValue="+myValue+",myTicks="+myTicks+"myPercent="+myPercent);
return new Float(myPercent); return new Float(myPercent);
} }
......
...@@ -411,7 +411,10 @@ public class GenericStats implements GenericWirelessData { ...@@ -411,7 +411,10 @@ public class GenericStats implements GenericWirelessData {
// so at least grabbing it as a string will work. // so at least grabbing it as a string will work.
obj = sdm.group(1); obj = sdm.group(1);
// try to take as float if possible... // try to take as float if possible...
obj = new Float(Float.parseFloat(sdm.group(2))); float tf = Float.parseFloat(sdm.group(2));
int bf = (int)(tf*100.0);
tf = ((float)bf)/100.0f;
obj = new Float(tf);
} }
catch (Exception ex) { catch (Exception ex) {
; ;
...@@ -484,7 +487,10 @@ public class GenericStats implements GenericWirelessData { ...@@ -484,7 +487,10 @@ public class GenericStats implements GenericWirelessData {
// so at least grabbing it as a string will work. // so at least grabbing it as a string will work.
obj = dm.group(1); obj = dm.group(1);
// try to take as float if possible... // try to take as float if possible...
obj = new Float(Float.parseFloat(dm.group(2))); float tf = Float.parseFloat(dm.group(2));
int bf = (int)(tf*100.0);
tf = ((float)bf)/100.0f;
obj = new Float(tf);
} }
catch (Exception ex) { catch (Exception ex) {
; ;
...@@ -539,7 +545,7 @@ public class GenericStats implements GenericWirelessData { ...@@ -539,7 +545,7 @@ public class GenericStats implements GenericWirelessData {
throw new IOException("file read failed"); throw new IOException("file read failed");
} }
System.out.println("GenericStats parsed "+linecount+" lines."); System.err.println("GenericStats parsed "+linecount+" lines.");
GenericStats retval = new GenericStats(indices,indexValues, GenericStats retval = new GenericStats(indices,indexValues,
nodes,properties, nodes,properties,
...@@ -589,7 +595,7 @@ public class GenericStats implements GenericWirelessData { ...@@ -589,7 +595,7 @@ public class GenericStats implements GenericWirelessData {
allStats.add(gls); allStats.add(gls);
//} //}
System.out.println("GS.addReceiverStats: added '"+gls.toString()+"'!"); //System.out.println("GS.addReceiverStats: added '"+gls.toString()+"'!");
} }
public GenericLinkStats getStats(String recvNode,String sendNode) { public GenericLinkStats getStats(String recvNode,String sendNode) {
......
...@@ -49,14 +49,22 @@ public class MapDataModel { ...@@ -49,14 +49,22 @@ public class MapDataModel {
private Hashtable options; private Hashtable options;
private int currentFloor;
private int currentScale;
private int minScale;
private int maxScale;
private Dataset dataset;
/** Creates a new instance of MapDataModel */ /** Creates a new instance of MapDataModel */
private MapDataModel() { private MapDataModel() {
this(null,null); this(new Dataset());
} }
public MapDataModel(GenericWirelessData data,NodePosition positions) { public MapDataModel(Dataset ds) {
this.data = data; this.dataset = ds;
this.positions = positions; this.data = ds.data;
this.positions = ds.positions;
selectionList = new Vector(); selectionList = new Vector();
threshold = new Float(0); threshold = new Float(0);
neighborCount = 3; neighborCount = 3;
...@@ -79,6 +87,32 @@ public class MapDataModel { ...@@ -79,6 +87,32 @@ public class MapDataModel {
limit = LIMIT_NONE; limit = LIMIT_NONE;
this.options = new Hashtable(); this.options = new Hashtable();
options.put(OPTION_NO_ZERO_LINKS,OPTION_SET); options.put(OPTION_NO_ZERO_LINKS,OPTION_SET);
// find min/max scale items:
int min = 65535;
this.minScale = -1;
for (int i = 0; i < ds.scale.length; ++i) {
if (ds.scale[i] < min) {
min = ds.scale[i];
this.minScale = min;
}
}
int max = -65535;
this.maxScale = -1;
for (int i = 0; i < ds.scale.length; ++i) {
if (ds.scale[i] > max) {
max = ds.scale[i];
this.maxScale = max;
}
}
this.currentScale = this.minScale;
System.err.println("model set minScale="+minScale+",maxScale"+maxScale+",currentScale="+currentScale);
System.err.println("model set min="+min+",max"+max);
// now set floor:
// just take the first one :-)
this.currentFloor = ds.floor[0];
System.err.println("model set currentFloor="+currentFloor);
} }
public Float getCurrentPropertyDelta() { public Float getCurrentPropertyDelta() {
...@@ -328,6 +362,10 @@ public class MapDataModel { ...@@ -328,6 +362,10 @@ public class MapDataModel {
return positions.getPoint(node); return positions.getPoint(node);
} }
public Dataset getDataset() {
return this.dataset;
}
public void addChangeListener(ChangeListener listener) { public void addChangeListener(ChangeListener listener) {
if (listener != null && !changeListeners.contains(listener)) { if (listener != null && !changeListeners.contains(listener)) {
changeListeners.add(listener); changeListeners.add(listener);
...@@ -383,6 +421,36 @@ public class MapDataModel { ...@@ -383,6 +421,36 @@ public class MapDataModel {
} }
} }
public void setFloor(int floor) {
this.currentFloor = floor;
notifyChangeListeners();
}
public void setScale(int scale) {
this.currentScale = scale;
notifyChangeListeners();
}
public int getFloor() {
return this.currentFloor;
}
public int getScale() {
return this.currentScale;
}
public int getMinScale() {
return this.minScale;
}
public int getMaxScale() {
return this.maxScale;
}
public float getScaleFactor() {
return this.dataset.getScaleFactor(this.currentScale);
}
private void notifyChangeListeners() { private void notifyChangeListeners() {
for (Enumeration e1 = changeListeners.elements(); e1.hasMoreElements(); ) { for (Enumeration e1 = changeListeners.elements(); e1.hasMoreElements(); ) {
((ChangeListener)e1.nextElement()).stateChanged(new ChangeEvent(this)); ((ChangeListener)e1.nextElement()).stateChanged(new ChangeEvent(this));
......
...@@ -47,7 +47,7 @@ ...@@ -47,7 +47,7 @@
</Property> </Property>
</Properties> </Properties>
<AuxValues> <AuxValues>
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new ControlPanel(datasets,mapImages,nodeMapPanel);"/> <AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new ControlPanel(datasets,nodeMapPanel);"/>
</AuxValues> </AuxValues>
<Constraints> <Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
......
...@@ -12,61 +12,54 @@ import java.util.*; ...@@ -12,61 +12,54 @@ import java.util.*;
public class MoteLinkViewer extends javax.swing.JFrame { public class MoteLinkViewer extends javax.swing.JFrame {
private Image bgImage;
private java.awt.image.ImageObserver io;
private Hashtable datasets; private Hashtable datasets;
private Hashtable mapImages;
public MoteLinkViewer() { public MoteLinkViewer(Dataset[] sets) {
this.datasets = new Hashtable(); this.datasets = new Hashtable();
this.mapImages = new Hashtable();
io = new java.awt.Component() { for (int i = 0; i < sets.length; ++i) {
public boolean updateImage(Image img, int infoflags, int x, int y, int width, int height) { java.awt.image.ImageObserver io;
System.out.println("w = "+width+",h = "+height); java.awt.Image bgImage;
return true; io = new java.awt.Component() {
public boolean updateImage(Image img, int infoflags, int x, int y, int width, int height) {
System.out.println("w = "+width+",h = "+height);
return true;
}
};
sets[i].addFloor(0);
sets[i].addScale(1);
Image ti = Toolkit.getDefaultToolkit().getImage(sets[i].image_path);
sets[i].addImage(ti,0,1);
try {
MediaTracker tracker = new MediaTracker(this);
tracker.addImage(ti, 0);
tracker.waitForID(0);
//System.out.println("width = "+bgImage.getWidth(io));
}
catch (InterruptedException ex) {
ex.printStackTrace();
} }
};
bgImage = Toolkit.getDefaultToolkit().getImage("/home/david/from_cvs/wireless-stats/floormap.jpg");
mapImages.put("Floor4/WSN",bgImage);
try {
MediaTracker tracker = new MediaTracker(this);
tracker.addImage(bgImage, 0);
tracker.waitForID(0);
//System.out.println("width = "+bgImage.getWidth(io));
}
catch (InterruptedException ex) {
ex.printStackTrace();
}
// in the applet, we'll read in the possible datasets and
GenericWirelessData defaultData = null;
NodePosition defaultPositions = null;
MapDataModel defaultModel = null;
String defaultDatasetName = "Floor4/WSN";
try {
defaultData = GenericStats.parseDumpFile("/home/david/from_cvs/wireless-stats/nn_client.log");
defaultPositions = NodePositions.parseFile("/home/david/from_cvs/wireless-stats/mote_positions");
defaultModel = new MapDataModel(defaultData,defaultPositions); // in the applet, we'll read in the possible datasets and
datasets.put(defaultDatasetName,defaultModel); try {
} sets[i].data = GenericStats.parseDumpFile(sets[i].dataFile);
catch (Exception e) { sets[i].positions = NodePositions.parseFile(sets[i].positionFile);
e.printStackTrace();
System.exit(-2); sets[i].model = new MapDataModel(sets[i]);
datasets.put(sets[i].name,sets[i]);
}
catch (Exception e) {
e.printStackTrace();
System.exit(-2);
}
} }
initComponents(); initComponents();
;
} }
// <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
...@@ -78,7 +71,7 @@ public class MoteLinkViewer extends javax.swing.JFrame { ...@@ -78,7 +71,7 @@ public class MoteLinkViewer extends javax.swing.JFrame {
//nodeMapPanel.setBackgroundImage(bgImage); //nodeMapPanel.setBackgroundImage(bgImage);
//nodeMapPanel.setPositions(positions); //nodeMapPanel.setPositions(positions);
//nodeMapPanel.setILEStats(model); //nodeMapPanel.setILEStats(model);
controlPanel = new ControlPanel(datasets,mapImages,nodeMapPanel); controlPanel = new ControlPanel(datasets,nodeMapPanel);
getContentPane().setLayout(new java.awt.GridBagLayout()); getContentPane().setLayout(new java.awt.GridBagLayout());
...@@ -100,13 +93,39 @@ public class MoteLinkViewer extends javax.swing.JFrame { ...@@ -100,13 +93,39 @@ public class MoteLinkViewer extends javax.swing.JFrame {
getContentPane().add(controlPanel, gridBagConstraints); getContentPane().add(controlPanel, gridBagConstraints);
pack(); pack();
} }// </editor-fold>//GEN-END:initComponents
// </editor-fold>//GEN-END:initComponents
public static void main(final String args[]) { public static void main(final String args[]) {
int floor;
float ppm;
String name,positionFile,dataFile,image_path,building;
Vector dsaV = new Vector();
for (int i = 0; i < args.length; ++i) {
String[] aa = args[i].split(",");
if (aa.length == 7) {
name = aa[0];
positionFile = aa[1];
dataFile = aa[2];
building = aa[3];
floor = Integer.parseInt(aa[4]);
image_path = aa[5];
ppm = Float.parseFloat(aa[6]);
dsaV.add(new Dataset(name,positionFile,dataFile,building,floor,image_path,ppm));
}
}
final Dataset[] dsa = new Dataset[dsaV.size()];
int i = 0;
for (Enumeration e1 = dsaV.elements(); e1.hasMoreElements(); ) {
dsa[i++] = (Dataset)e1.nextElement();
}
java.awt.EventQueue.invokeLater(new Runnable() { java.awt.EventQueue.invokeLater(new Runnable() {
public void run() { public void run() {
new MoteLinkViewer().setVisible(true); new MoteLinkViewer(dsa).setVisible(true);
} }
}); });
} }
......
...@@ -17,6 +17,7 @@ public class NodeMapPanel extends javax.swing.JPanel implements ChangeListener { ...@@ -17,6 +17,7 @@ public class NodeMapPanel extends javax.swing.JPanel implements ChangeListener {
private Vector widgets; private Vector widgets;
private MapDataModel model; private MapDataModel model;
private ControlPanel controlPanel; private ControlPanel controlPanel;
private float scaleFactor;
/** /**
* Creates new form NodeMapPanel * Creates new form NodeMapPanel
...@@ -37,37 +38,6 @@ public class NodeMapPanel extends javax.swing.JPanel implements ChangeListener { ...@@ -37,37 +38,6 @@ public class NodeMapPanel extends javax.swing.JPanel implements ChangeListener {
initComponents(); initComponents();
//setOpaque(true); //setOpaque(true);
// NodeWidget nw1,nw2;
// nw1 = new NodeWidget("mote101",50,50);
// nw2 = new NodeWidget("mote102",100,150);
// widgets.add(nw1);
// widgets.add(nw2);
// widgets.add(new LinkWidget(nw1,nw2,0.75f,0.25f));
//
// nw1 = new NodeWidget("mote103",400,250);
// nw2 = new NodeWidget("mote104",200,50);
// widgets.add(nw1);
// widgets.add(nw2);
// widgets.add(new LinkWidget(nw1,nw2,0.20f,0.60f));
//
// nw1 = new NodeWidget("mote110",100,300);
// nw2 = new NodeWidget("mote111", 300, 100);
// widgets.add(nw1);
// widgets.add(nw2);
// widgets.add(new LinkWidget(nw1,nw2,0.25f,0.75f));
//
// nw1 = new NodeWidget("mote105",300,350);
// nw2 = new NodeWidget("mote106",100,480);
// widgets.add(nw1);
// widgets.add(nw2);
// widgets.add(new LinkWidget(nw1,nw2,0.85f,0.10f));
//
// widgets.add(new NodeWidget("mote107",100,100));
// widgets.add(new NodeWidget("mote108",300,200));
// widgets.add(new LinkWidget(null,100,100,300,200,12));
} }
public void setModel(MapDataModel model) { public void setModel(MapDataModel model) {
...@@ -104,6 +74,8 @@ public class NodeMapPanel extends javax.swing.JPanel implements ChangeListener { ...@@ -104,6 +74,8 @@ public class NodeMapPanel extends javax.swing.JPanel implements ChangeListener {
// return; // return;
// } // }
this.scaleFactor = this.model.getScaleFactor();
this.widgets.clear(); this.widgets.clear();
this.nodeWidgets.clear(); this.nodeWidgets.clear();
this.linkWidgets.clear(); this.linkWidgets.clear();
...@@ -111,9 +83,11 @@ public class NodeMapPanel extends javax.swing.JPanel implements ChangeListener { ...@@ -111,9 +83,11 @@ public class NodeMapPanel extends javax.swing.JPanel implements ChangeListener {
String[] nodes = model.getNodes(); String[] nodes = model.getNodes();
if (nodes != null) { if (nodes != null) {
for (int i = 0; i < nodes.length; ++i) { for (int i = 0; i < nodes.length; ++i) {
//System.out.println("nodes["+i+"] = '"+nodes[i]+"'"); System.out.println("nodes["+i+"] = '"+nodes[i]+"'");
Point posit = model.getPosition(nodes[i]); Point posit = model.getPosition(nodes[i]);
NodeWidget nw = new NodeWidget(nodes[i],posit.x,posit.y); NodeWidget nw = new NodeWidget(nodes[i],
(int)(posit.x*this.scaleFactor),
(int)(posit.y*this.scaleFactor));
this.widgets.add(nw); this.widgets.add(nw);
this.nodeWidgets.put(nodes[i],nw);