views:

550

answers:

2

I am really struggling with parsing a text file. I have a text file which is in the following format

ID
Float Float 
Float Float
....   // variable number of floats
END
ID
Float Float 
Float Float
....   
END

etc However the ID can represent one of two values, 0 which means it is a new field, or -1 which means it is related to the last new field. The number of times a related field can repeat it self is unlimited. Which is where the problem is occurring.

As I have a method in a library which takes an ArrayList of the new Floats, then an ArrayList of an ArrayList of the related floats.

When I try and code the logic for this I just keep getting deeper and deeper embedded while loops.

I would really appreciate any suggestions as to how I should go about this. Thanks in advance.

Here is the code I have so far.

BufferedReader br = new BufferedReader(new FileReader(buildingsFile));

        String[] line = br.readLine().trim().split("    ");
        boolean original = true;

        while(true)
        {
            if(line[0].equals("END"))
                break;

            startCoordinate = new Coordinate(Double.parseDouble(line[0]), Double.parseDouble(line[1]));

            while(true)
            {
                line = br.readLine().trim().split("    ");

                if(!line[0].equals("END") && original == true)
                    polypoints.add(new Coordinate(Double.parseDouble(line[0]), Double.parseDouble(line[1])));
                else if(!line[0].equals("END") && original == false)
                    cutout.add(new Coordinate(Double.parseDouble(line[0]), Double.parseDouble(line[1])));
                else if(line[0].equals("END") && original == false)
                {
                    cutouts.add(cutout);
                    cutout.clear();
                }
                else if(line[0].equals("-99999"))
                    original = false;
                else if(line[0].equals("0"))
                    break;
            }

            buildingDB.addBuilding(mapName, startCoord, polypoints, cutouts);
        }

New Code

        int i = 0;

        BufferedReader br = new BufferedReader(new FileReader(buildingsFile));

        String[] line;

        while(true)
        {
            line = br.readLine().trim().split("    ");

            if(line[0].equals("END"))
                break;

            polygons.add(new Polygon(line));

            while(true)
            {
                line = br.readLine().trim().split("    ");

                if(line[0].equals("END"))
                    break;
                polygons.get(i).addCoord(new Coordinate(Double.parseDouble(line[0]), Double.parseDouble(line[1])));
            }



            i++;
        }
        System.out.println(polygons.size());


        int j = 0;
        for(i = 0; i< polygons.size(); i++)
        {
            Building newBuilding = new Building();

            if(polygons.get(i).isNew == true)
            {
                newBuilding = new Building();
                newBuilding.startCoord = new Coordinate(polygons.get(i).x, polygons.get(i).y);
            }

            while(polygons.get(i).isNew == false)
                newBuilding.cutouts.add(polygons.get(i).coords);

            buildings.add(newBuilding);
        }

        for(i = 0; i<buildings.size(); i++)
        {
            System.out.println(i);
            buildingDB.addBuilding(mapName, buildings.get(i).startCoord, buildings.get(i).polypoint, buildings.get(i).cutouts);
        }
A: 

I assume that a "field" means an ID and a variable number of coordinates (pairs of floats), that, judging from your code, represents a polygon in fact.

I would first load all the polygons, each into a separate Polygon object:

class Polygon {
    boolean isNew;
    List<Coordinate> coordinates;
}

and store the polygons in another list. Then in a 2nd pass go through all the polygons to group them according to their IDs into something like

class Building {
    Polygon polygon;
    List<Polygon> cutouts;
}

I think this would be fairly simple to code.

OTOH if you have a huge amount of data in the file, and/or you prefer processing the read data little by little, you could simply read a polygon and all its associated cutouts, until you find the next polygon (ID of 0), at which point you could simply pass the stuff read so far to the building DB and start reading the next polygon.

Péter Török
Thanks ill try the first method you suggested, i have adapted the one i posted but it has taken 10 minutes to get to the 35th building and seems to have stopped there.
John
I have implemented this, however java is now reporting that I have run out of space on the heap which is rather unusual, any ideas?
John
@John-- hmmmm. How big is the file you are trying to read? Approx. how many polygons there are in it? Could you post your updated code?
Péter Török
There are 135 polygons in the file, some having over 50 points. Ill upload my current code now.
John
@John-- You don't seem to initialize Polygon.isNew anywhere. And this while loop never terminates: while(polygons.get(i).isNew == false) newBuilding.cutouts.add(polygons.get(i).coords);
Péter Török
in the polygon class I set them to be false by default, and the constructor tests the first line to see if it is a cutout setting it to true. The first two while loops which get the list of polygons works rather quickly, its just when adding them to the buildings/adding to the database that I get the memory problems.
John
Thanks hadnt noticed the infinite while loop() just getting a few null pointer exceptions now which should be easy enough to remove
John
Great, you are progressing :-)
Péter Török
A: 

Maybe you should use map for new floats and related floats..if got your question it should help..example:

HashMap hm = new HashMap();
hm.put("Rohit", new Double(3434.34));
shake
u would use floats in map..:)
shake