/* * Copyright 2004-2010 Information & Software Engineering Group (188/1) * Institute of Software Technology and Interactive Systems * Vienna University of Technology, Austria * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.ifs.tuwien.ac.at/dm/somtoolbox/license.html * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package at.tuwien.ifs.somtoolbox.input; import java.io.BufferedReader; import java.io.IOException; import java.util.ArrayList; import java.util.Date; import java.util.Hashtable; import java.util.Vector; import at.tuwien.ifs.somtoolbox.structures.ComponentLine3D; import at.tuwien.ifs.somtoolbox.util.FileUtils; import at.tuwien.ifs.somtoolbox.util.Point3d; /** * Load the input format produced by the Second Life Analytics Suite. * * @author Robert Neumayer * @version $Id: SecondLifeInputFileReader.java 3888 2010-11-02 17:42:53Z frank $ */ public class SecondLifeInputFileReader { private String uid, region, pos_x, pos_y, pos_z, avatar_name, total_number, time, avatar_key, avatar_info; private int numberOfLines; private long[] uids; private String[] regions; private Point3d[] positions; // TODO index this differently private String[] avatarNames; private long[] totalNumbers; private Date[] times; private String[] avatarKeys; private Hashtable<String, Vector<Point3d>> avatarPositions; private void init(String secondLifeCoordinateFile) throws IOException { BufferedReader br = FileUtils.openFile("SecondLife Coordinate File", secondLifeCoordinateFile); br.readLine(); // skip header this.numberOfLines = 0; String line = null; while ((line = br.readLine()) != null) { this.numberOfLines++; } br.close(); this.uids = new long[this.numberOfLines]; this.regions = new String[this.numberOfLines]; this.positions = new Point3d[this.numberOfLines]; this.avatarNames = new String[this.numberOfLines]; this.totalNumbers = new long[this.numberOfLines]; this.times = new Date[this.numberOfLines]; this.avatarKeys = new String[this.numberOfLines]; avatarPositions = new Hashtable<String, Vector<Point3d>>(); } public SecondLifeInputFileReader(String secondLifeCoordinateFile) throws IOException { this.init(secondLifeCoordinateFile); BufferedReader br = FileUtils.openFile("SecondLife Coordinate File", secondLifeCoordinateFile); String line = null; String headerLine = br.readLine(); String[] elements = headerLine.split(";"); uid = elements[0]; region = elements[1]; pos_x = elements[2]; pos_y = elements[3]; pos_z = elements[4]; avatar_name = elements[5]; total_number = elements[6]; time = elements[7]; avatar_key = elements[8]; avatar_info = elements[9]; String previousName = "init"; for (int index = 0; (line = br.readLine()) != null; index++) { if (index == 0) { previousName = elements[5]; } elements = line.split(";"); uids[index] = Long.parseLong(elements[0]); regions[index] = elements[1]; // System.out.println(index + " | " + uids[index] + new Point3d(Double.parseDouble(elements[2]), // Double.parseDouble(elements[3]), // Double.parseDouble(elements[4]))); positions[index] = new Point3d(Double.parseDouble(elements[2]), Double.parseDouble(elements[3]), Double.parseDouble(elements[4])); // System.out.println("added: " + positions[index]); avatarNames[index] = elements[5]; if (previousName.equals(elements[5])) { if (avatarPositions.get(elements[5]) != null) { Vector<Point3d> pos = avatarPositions.get(elements[5]); pos.add(positions[index]); avatarPositions.put(elements[5], pos); } } else { Vector<Point3d> v = new Vector<Point3d>(); v.add(positions[index]); avatarPositions.put(elements[5], v); } previousName = elements[5]; totalNumbers[index] = Long.parseLong(elements[6]); // TODO figure out something for the timestamps // times = new Date(elements[7]); avatarKeys[index] = elements[8]; // avatarnfo = elements[9]; } initMinAndMaxValues(); } public String[] getAvatarKeys() { return avatarKeys; } public void setAvatarKeys(String[] avatarKeys) { this.avatarKeys = avatarKeys; } public String[] getAvatarNames() { return avatarNames; } public void setAvatarNames(String[] avatarNames) { this.avatarNames = avatarNames; } public Point3d[] getPositions() { return positions; } public static double[][][] point2DoubleArray(Point3d[][] pointArray) { double[][][] data = new double[pointArray.length][pointArray[0].length][]; for (int i = 0; i < pointArray.length; i++) { data[i] = point2DoubleArray(pointArray[i]).clone(); } return data; } public static double[][] point2DoubleArray(Point3d[] pointArray) { double[][] data = new double[pointArray.length][3]; for (int i = 0; i < pointArray.length; i++) { data[i] = new double[] { pointArray[i].x, pointArray[i].y, pointArray[i].z }; } return data; } public static Point3d[][] double2PointArray(double[][][] doubleArray) { Point3d[][] pointArray = new Point3d[doubleArray.length][doubleArray[0].length]; for (int i = 0; i < doubleArray.length; i++) { for (int j = 0; j < pointArray[0].length; j++) { pointArray[i][j] = new Point3d(doubleArray[i][j][0], doubleArray[i][j][1], doubleArray[i][j][2]); } } return pointArray; } public static ArrayList<ComponentLine3D> double2ComponentLineArray(double[][][] doubleArray) { ArrayList<ComponentLine3D> res = new ArrayList<ComponentLine3D>(); for (int i = 0; i < doubleArray.length; i++) { Point3d[] pointArray = new Point3d[doubleArray[i].length]; for (int j = 0; j < pointArray.length; j++) { pointArray[j] = new Point3d(doubleArray[i][j][0], doubleArray[i][j][1], doubleArray[i][j][2]); } res.add(new ComponentLine3D(pointArray, i)); } return res; } double[] minValues, maxValues; private void initMinAndMaxValues() { double[][] data = SecondLifeInputFileReader.point2DoubleArray(positions); int numberOfAttributes = data[0].length; minValues = new double[numberOfAttributes]; maxValues = new double[numberOfAttributes]; // for each attribute for (int j = 0; j < numberOfAttributes; j++) { // in each instance (i.e. each single value now :-)) minValues[j] = Double.MAX_VALUE; maxValues[j] = Double.MIN_VALUE; for (double[] element : data) { if (element[j] < minValues[j]) { minValues[j] = element[j]; } if (element[j] > maxValues[j]) { maxValues[j] = element[j]; } } } } public void setPositions(Point3d[] positions) { this.positions = positions; } public String[] getRegions() { return regions; } public void setRegions(String[] regions) { this.regions = regions; } public long[] getTotalNumbers() { return totalNumbers; } public void setTotalNumbers(long[] totalNumbers) { this.totalNumbers = totalNumbers; } public long[] getUids() { return uids; } public void setUids(long[] uids) { this.uids = uids; } public String[] getDistinctAvatarNames() { Object[] distinctAvatarNamesAsObjects = avatarPositions.keySet().toArray(); String[] distinctAvatarNames = new String[distinctAvatarNamesAsObjects.length]; for (int i = 0; i < distinctAvatarNames.length; i++) { distinctAvatarNames[i] = distinctAvatarNamesAsObjects[i].toString(); } return distinctAvatarNames; } public double[][] getAvatarPositions(String avatarName) { Vector<Point3d> names = avatarPositions.get(avatarName); Point3d oldPoint = null; int numberOfEqualPoints = 0; for (int i = 0; i < names.size(); i++) { // FIXME think abou this // if(i != 0 && oldPoint.equals(names.elementAt(i))){ // numberOfEqualPoints++; // if(numberOfEqualPoints > 10){ // names.remove(i); // i--; // } // } // oldPoint = names.elementAt(i); } double[][] positions = new double[names.size()][3]; for (int i = 0; i < names.size(); i++) { // System.out.println("vector: " + i + " / " + names.elementAt(i)); positions[i][0] = names.elementAt(i).x; positions[i][1] = names.elementAt(i).y; positions[i][2] = names.elementAt(i).z; } return positions; } public double[] getMaxValues() { return maxValues; } public double[] getMinValues() { return minValues; } }