Ignore:
Timestamp:
2007-09-05T23:55:17+02:00 (18 years ago)
Author:
frederik
Message:

initial changeset for 0.5 functionality. this version works with 0.5 as specified but there are some minor bugs to be fixed.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • applications/editors/josm/core_0.5/src/org/openstreetmap/josm/io/OsmReader.java

    r4437 r4464  
    2121import org.openstreetmap.josm.data.osm.DataSet;
    2222import org.openstreetmap.josm.data.osm.DataSource;
     23import org.openstreetmap.josm.data.osm.Relation;
     24import org.openstreetmap.josm.data.osm.RelationMember;
    2325import org.openstreetmap.josm.data.osm.Node;
    2426import org.openstreetmap.josm.data.osm.OsmPrimitive;
    25 import org.openstreetmap.josm.data.osm.Segment;
    2627import org.openstreetmap.josm.data.osm.User;
    2728import org.openstreetmap.josm.data.osm.Way;
     
    4142 * all nodes are read and stored. Other information than nodes are stored in a raw list
    4243 *
    43  * The second phase reads from the raw list all segments and create Segment objects.
    44  *
    45  * The third phase read all ways out of the remaining objects in the raw list.
     44 * The second phase read all ways out of the remaining objects in the raw list.
    4645 *
    4746 * @author Imi
     
    8887
    8988        /**
    90          * Data structure for the remaining segment objects
    91          * Maps the raw attributes to key/value pairs.
    92          */
    93         private Map<OsmPrimitiveData, long[]> segs = new HashMap<OsmPrimitiveData, long[]>();
     89         * Used as a temporary storage for relation members, before they
     90         * are resolved into pointers to real objects.
     91         */
     92        private static class RelationMemberData {
     93                public String type;
     94                public long id;
     95                public RelationMember relationMember;
     96        }
    9497
    9598        /**
     
    97100         */
    98101        private Map<OsmPrimitiveData, Collection<Long>> ways = new HashMap<OsmPrimitiveData, Collection<Long>>();
     102
     103        /**
     104         * Data structure for relation objects
     105         */
     106        private Map<OsmPrimitiveData, Collection<RelationMemberData>> relations = new HashMap<OsmPrimitiveData, Collection<RelationMemberData>>();
    99107
    100108        /**
     
    129137                                                ds.dataSources.add(src);
    130138                                        }
     139                                       
     140                                // ---- PARSING NODES AND WAYS ----
     141                                       
    131142                                } else if (qName.equals("node")) {
    132143                                        current = new Node(new LatLon(getDouble(atts, "lat"), getDouble(atts, "lon")));
    133144                                        readCommon(atts, current);
    134145                                        nodes.put(current.id, (Node)current);
    135                                 } else if (qName.equals("segment")) {
    136                                         current = new OsmPrimitiveData();
    137                                         readCommon(atts, current);
    138                                         segs.put((OsmPrimitiveData)current, new long[]{getLong(atts, "from"), getLong(atts, "to")});
    139146                                } else if (qName.equals("way")) {
    140147                                        current = new OsmPrimitiveData();
    141148                                        readCommon(atts, current);
    142149                                        ways.put((OsmPrimitiveData)current, new LinkedList<Long>());
    143                                 } else if (qName.equals("seg")) {
     150                                } else if (qName.equals("nd")) {
    144151                                        Collection<Long> list = ways.get(current);
    145152                                        if (list == null)
    146                                                 throw new SAXException(tr("Found <seg> tag on non-way."));
    147                                         long id = getLong(atts, "id");
     153                                                throw new SAXException(tr("Found <nd> element in non-way."));
     154                                        long id = getLong(atts, "ref");
    148155                                        if (id == 0)
    149                                                 throw new SAXException(tr("Incomplete segment with id=0"));
     156                                                throw new SAXException(tr("<nd> has zero ref"));
    150157                                        list.add(id);
    151                                 } else if (qName.equals("tag"))
     158
     159                                // ---- PARSING ENTITIES ----                   
     160
     161                                } else if (qName.equals("relation")) {
     162                                        current = new OsmPrimitiveData();
     163                                        readCommon(atts, current);
     164                                        relations.put((OsmPrimitiveData)current, new LinkedList<RelationMemberData>());
     165                                } else if (qName.equals("member")) {
     166                                        Collection<RelationMemberData> list = relations.get(current);
     167                                        if (list == null)
     168                                                throw new SAXException(tr("Found <member> tag on non-relation."));
     169                                        RelationMemberData emd = new RelationMemberData();
     170                                        emd.relationMember = new RelationMember();
     171                                        emd.id = getLong(atts, "ref");
     172                                        emd.type=atts.getValue("type");
     173                                        emd.relationMember.role = atts.getValue("role");
     174                                       
     175                                        if (emd.id == 0)
     176                                                throw new SAXException(tr("Incomplete <member> specification with ref=0"));
     177                                       
     178                                        list.add(emd);
     179                                       
     180                                // ---- PARSING TAGS (applicable to all objects) ----
     181                                       
     182                                } else if (qName.equals("tag")) {
    152183                                        current.put(atts.getValue("k"), atts.getValue("v"));
     184                                }
    153185                        } catch (NumberFormatException x) {
    154186                                x.printStackTrace(); // SAXException does not chain correctly
     
    170202        public OsmReader() {
    171203                // first add the main server version
    172                 allowedVersions.add(Main.pref.get("osm-server.version", "0.4"));
     204                allowedVersions.add(Main.pref.get("osm-server.version", "0.5"));
    173205                // now also add all compatible versions
    174206                String[] additionalVersions =
    175                         Main.pref.get("osm-server.additional-versions", "0.3").split("/,/");
     207                        Main.pref.get("osm-server.additional-versions", "").split("/,/");
     208                if (additionalVersions.length == 1 && additionalVersions[0].length() == 0)
     209                        additionalVersions = new String[] {};
    176210                allowedVersions.addAll(Arrays.asList(additionalVersions));     
    177211        }
     
    221255                        throw new SAXException(tr("Missing required attribute \"{0}\".",value));
    222256                return Long.parseLong(s);
    223         }
    224 
    225         private void createSegments() {
    226                 for (Entry<OsmPrimitiveData, long[]> e : segs.entrySet()) {
    227                         Node from = findNode(e.getValue()[0]);
    228                         Node to = findNode(e.getValue()[1]);
    229                         if (from == null || to == null)
    230                                 continue; //TODO: implement support for incomplete nodes.
    231                         Segment s = new Segment(from, to);
    232                         e.getKey().copyTo(s);
    233                         segments.put(s.id, s);
    234                         adder.visit(s);
    235                 }
    236257        }
    237258
     
    250271    }
    251272
    252         private Segment findSegment(long id) {
    253                 Segment s = segments.get(id);
    254                 if (s != null)
    255                         return s;
    256                 for (Segment seg : references.segments)
    257                         if (seg.id == id)
    258                                 return seg;
    259                 // TODO: This has to be changed to support multiple layers.
    260                 for (Segment seg : Main.ds.segments)
    261                         if (seg.id == id)
    262                                 return new Segment(seg);
    263                 return null;
    264         }
    265 
    266273        private void createWays() {
    267274                for (Entry<OsmPrimitiveData, Collection<Long>> e : ways.entrySet()) {
    268275                        Way w = new Way();
     276                        boolean failed = false;
    269277                        for (long id : e.getValue()) {
    270                                 Segment s = findSegment(id);
    271                                 if (s == null) {
    272                                         s = new Segment(id); // incomplete line segment
    273                                         adder.visit(s);
     278                                Node n = findNode(id);
     279                                if (n == null) {
     280                                        failed = true;
     281                                        break;
    274282                                }
    275                                 w.segments.add(s);
     283                                w.nodes.add(n);
    276284                        }
     285                        if (failed) continue;
    277286                        e.getKey().copyTo(w);
    278287                        adder.visit(w);
     
    281290
    282291        /**
    283          * All read segments after phase 2.
    284          */
    285         private Map<Long, Segment> segments = new HashMap<Long, Segment>();
     292         * Return the Way object with the given id, or null if it doesn't
     293         * exist yet. This method only looks at ways stored in the data set.
     294         *
     295         * @param id
     296         * @return way object or null
     297         */
     298        private Way findWay(long id) {
     299                for (Way wy : ds.ways)
     300                        if (wy.id == id)
     301                                return wy;
     302                for (Way wy : Main.ds.ways)
     303                        if (wy.id == id)
     304                                return wy;
     305                return null;
     306        }
     307
     308        /**
     309         * Return the Relation object with the given id, or null if it doesn't
     310         * exist yet. This method only looks at relations stored in the data set.
     311         *
     312         * @param id
     313         * @return relation object or null
     314         */
     315        private Relation findRelation(long id) {
     316                for (Relation e : ds.relations)
     317                        if (e.id == id)
     318                                return e;
     319                for (Relation e : Main.ds.relations)
     320                        if (e.id == id)
     321                                return e;
     322                return null;
     323        }
     324
     325        /**
     326         * Create relations. This is slightly different than n/s/w because
     327         * unlike other objects, relations may reference other relations; it
     328         * is not guaranteed that a referenced relation will have been created
     329         * before it is referenced. So we have to create all relations first,
     330         * and populate them later.
     331         */
     332        private void createRelations() {
     333               
     334                // pass 1 - create all relations
     335                for (Entry<OsmPrimitiveData, Collection<RelationMemberData>> e : relations.entrySet()) {
     336                        Relation en = new Relation();
     337                        e.getKey().copyTo(en);
     338                        adder.visit(en);
     339                }
     340
     341                // pass 2 - sort out members
     342                for (Entry<OsmPrimitiveData, Collection<RelationMemberData>> e : relations.entrySet()) {
     343                        Relation en = findRelation(e.getKey().id);
     344                        if (en == null) throw new Error("Failed to create relation " + e.getKey().id);
     345                       
     346                        for (RelationMemberData emd : e.getValue()) {
     347                                RelationMember em = emd.relationMember;
     348                                if (emd.type.equals("node")) {
     349                                        em.member = findNode(emd.id);
     350                                        if (em.member == null) {
     351                                                em.member = new Node(emd.id);
     352                                                adder.visit((Node)em.member);
     353                                        }
     354                                } else if (emd.type.equals("way")) {
     355                                        em.member = findWay(emd.id);
     356                                        if (em.member == null) {
     357                                                em.member = new Way(emd.id);
     358                                                adder.visit((Way)em.member);
     359                                        }
     360                                } else if (emd.type.equals("relation")) {
     361                                        em.member = findRelation(emd.id);
     362                                        if (em.member == null) {
     363                                                em.member = new Relation(emd.id);
     364                                                adder.visit((Relation)em.member);
     365                                        }
     366                                } else {
     367                                        // this is an error.
     368                                }
     369                                en.members.add(em);
     370                        }
     371                }
     372        }
    286373
    287374        /**
     
    295382                osm.references = ref == null ? new DataSet() : ref;
    296383
    297                 // phase 1: Parse nodes and read in raw segments and ways
     384                // phase 1: Parse nodes and read in raw ways
    298385                osm.new Parser().parse(new InputStreamReader(source, "UTF-8"));
    299386                if (pleaseWaitDlg != null) {
     
    305392
    306393                try {
    307                         osm.createSegments();
    308394                        osm.createWays();
     395                        osm.createRelations();
    309396                } catch (NumberFormatException e) {
    310397                        e.printStackTrace();
Note: See TracChangeset for help on using the changeset viewer.