Sunday, May 1, 2011

Parsing data from txt file in J2ME

Basically I'm creating an indoor navigation system in J2ME. I've put the location details in a .txt file i.e.

  • Locations names and their coordinates.
  • Edges with respective start node and end node as well as the weight (length of the node).

    I put both details in the same file so users dont have to download multiple files to get their map working (it could become time consuming and seem complex). So what i did is to seperate the deferent details by typing out location Names and coordinates first, After that I seperated that section from the next section which is the edges by drawing a line with multiple underscores.

    Now the problem I'm having is parsing the different details into seperate arrays by setting up a command (while manually tokenizing the input stream) to check wether the the next token is an underscore.

  • If it is, (in pseudocode terms), move to the next line in the stream, create a new array and fill it up with the next set of details.

    I found a some explanation/code HERE that does something similar but still parses into one array, although it manually tokenizes the input. Any ideas on what to do? Thanks

    Text File Explanation
    The text has the following format...

    <--1stSection-->
     /**
      * Section one has the following format
      * xCoordinate;yCoordinate;LocationName
      */

    12;13;New York City
    40;12;Washington D.C.
    ...e.t.c

    _________________________  <--(underscore divider)

    <--2ndSection-->
     /**
      * Its actually an adjacency list but indirectly provides "edge" details.
      * Its in this form
      * StartNode/MainReferencePoint;Endnode1;distance2endNode1;Endnode2;distance2endNode2;...e.t.c
      */

    philadelphia;Washington D.C.;7;New York City;2
    New York City;Florida;24;Illinois;71
    ...e.t.c

    From stackoverflow
    • package filereader;
      
      import java.io.IOException;
      import java.io.InputStream;
      import java.util.Hashtable;
      import java.util.Vector;
      
      public class FileReader {
          String locationSection;
          String edgeSection;
          Vector locations;
          Vector edges;
      
          public FileReader(String fileName) {
           // read the contents into the string
           InputStream is = getClass().getResourceAsStream(fileName);
           StringBuffer sb = new StringBuffer();
           int ch;
           try {
            while ((ch = is.read()) != -1) {
             sb.append((char) ch);
            }
           } catch (IOException e2) {
            e2.printStackTrace();
           }
           try {
            is.close();
           } catch (IOException e) {
            e.printStackTrace();
           }
           String text = sb.toString();
      
           // separate locations and edges
           String separator = "_________________________";
      
           // read location section, without last end-of-line char
           int endLocationSection = text.indexOf(separator) - 1;
           locationSection = text.substring(0, endLocationSection);
      
           // read edges section, without end-of-line char after separator
           int startEdgeSection = endLocationSection + separator.length() + 3;
           edgeSection = text.substring(startEdgeSection, text.length());
      
           // parse locations and edges
           locations = getLocationsVector(locationSection);
           edges = getEdgesVector(edgeSection);
          }
      
          // parse locations section
          public Vector getLocationsVector(String section) {
           Vector result = new Vector();
           int startLine = 0;
           int endLine = section.indexOf('\n');
           while (endLine != -1) {
            String line = section.substring(startLine, endLine);
            result.addElement(parseLocationsLine(line, ';'));
            startLine = endLine + 1;
            if (endLine == section.length() - 1)
             break;
            endLine = section.indexOf('\n', startLine);
            // if no new line found, read to the end of string
            endLine = (-1 == endLine) ? section.length() - 1 : endLine;
           }
           return result;
          }
      
          // parse edges section
          public Vector getEdgesVector(String section) {
           Vector result = new Vector();
           int startLine = 0;
           int endLine = section.indexOf('\n');
           while (endLine != -1) {
            String line = section.substring(startLine, endLine - 1);
            result.addElement(parseEdgesLine(line, ';'));
            startLine = endLine + 1;
            if (endLine == section.length() + 1)
             break;
            endLine = section.indexOf('\n', startLine);
            // if no new line found, read to the end of string
            endLine = (-1 == endLine) ? section.length() + 1 : endLine;
           }
           return result;
          }
      
          // parse locations line
          public Hashtable parseLocationsLine(String value, char splitBy) {
           Hashtable result = new Hashtable();
           int xCEnd = value.indexOf(splitBy);
           int yCEnd = value.indexOf(splitBy, xCEnd + 1);
           result.put("x", value.substring(0, xCEnd));
           result.put("y", value.substring(xCEnd + 1, yCEnd));
           result.put("location", value.substring(yCEnd + 1, 
            value.length() - 1));
           return result;
          }
      
          // parse edges line
          public Hashtable parseEdgesLine(String value, char splitBy) {
           Hashtable result = new Hashtable();
           int snEnd = value.indexOf(splitBy);
           result.put("startnode", value.substring(0, snEnd));
           int n = 1;
           int start = snEnd + 1;
           int enEnd = value.indexOf(splitBy, snEnd + 1);
           int dstEnd = value.indexOf(splitBy, enEnd + 1);
           while (enEnd != -1 && dstEnd != -1) {
            result.put("endnode" + String.valueOf(n), 
              value.substring(start, enEnd));
            result.put("distance" + String.valueOf(n), value.substring(
              enEnd + 1, dstEnd));
            start = dstEnd + 1;
            enEnd = value.indexOf(splitBy, start);
            if (dstEnd == value.length())
             break;
            dstEnd = value.indexOf(splitBy, enEnd + 1);
            // if last endnode-distance pair, read to the end of line
            dstEnd = (-1 == dstEnd) ? value.length() : dstEnd;
            n++;
           }
           return result;
          }
      
          // getters for locations and edges
          public Vector getLocations() {
           return locations;
          }
      
          public Vector getEdges() {
           return edges;
          }
      
      }
      

      and somewhere in application screen:

      fr = new FileReader("/map.txt");
      Vector vct1 = fr.getLocations();
      for (int i = 0; i < vct1.size(); i++) {
       Hashtable location = (Hashtable) vct1.elementAt(i);
       Enumeration en = location.keys();
       String fv = "";
       while (en.hasMoreElements()) {
        String key = (String) en.nextElement();
        String value = (String)location.get(key);
        fv = fv + value + "-";
       }
       this.add(new LabelField(fv));  
      
      }
      Vector vct2 = fr.getEdges();
      for (int i = 0; i < vct2.size(); i++) {
       Hashtable location = (Hashtable) vct2.elementAt(i);
       Enumeration en = location.keys();
       String fv = "";
       while (en.hasMoreElements()) {
        String key = (String) en.nextElement();
        String value = (String)location.get(key);
        fv = fv + value + "-";
       }
       this.add(new LabelField(fv));  
      
      }
      

      it will be easy to get values from hashtable by keys:
      (String)location.get("x")
      (String)location.get("y")
      (String)location.get("location")
      (String)edge.get("startnode")
      (String)edge.get("endnode1")
      (String)edge.get("distance1")
      (String)edge.get("endnode2")
      (String)edge.get("distance2")
      ...

    0 comments:

    Post a Comment

    Note: Only a member of this blog may post a comment.