Changeset 4490 in josm


Ignore:
Timestamp:
06.10.2011 21:04:04 (8 months ago)
Author:
Don-vip
Message:

see #6886 - Allow JOSM plugin writers to create their own *Reader / *Importer, first for the upcoming PBF plugin.

Location:
trunk/src/org/openstreetmap/josm
Files:
1 added
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/data/osm/RelationMemberData.java

    r3083 r4490  
    2121        return memberId; 
    2222    } 
     23     
    2324    public String getRole() { 
    2425        return role; 
    2526    } 
     27     
    2628    public OsmPrimitiveType getMemberType() { 
    2729        return memberType; 
     
    3436    @Override 
    3537    public String toString() { 
    36         return memberType.getAPIName() + " " + memberId; 
     38        return (memberType != null ? memberType.getAPIName() : "undefined") + " " + memberId; 
    3739    } 
    3840 
     
    4042     * PrimitiveId implementation. Returns the same value as {@link #getMemberType()} 
    4143     */ 
     44    @Override 
    4245    public OsmPrimitiveType getType() { 
    4346        return memberType; 
     
    4750     * PrimitiveId implementation. Returns the same value as {@link #getMemberId()()} 
    4851     */ 
     52    @Override 
    4953    public long getUniqueId() { 
    5054        return memberId; 
    5155    } 
    5256 
     57    @Override 
    5358    public boolean isNew() { 
    5459        return memberId <= 0; 
  • trunk/src/org/openstreetmap/josm/io/OsmImporter.java

    r4393 r4490  
    4343        final DataSet dataSet = OsmReader.parseDataSet(in, NullProgressMonitor.INSTANCE); 
    4444        final OsmDataLayer layer = new OsmDataLayer(dataSet, associatedFile.getName(), associatedFile); 
     45        addDataLayer(dataSet, layer, associatedFile.getPath());  
     46    } 
     47         
     48    protected void addDataLayer(final DataSet dataSet, final OsmDataLayer layer, final String filePath) {  
    4549        // FIXME: remove UI stuff from IO subsystem 
    4650        // 
     
    5155                    JOptionPane.showMessageDialog( 
    5256                            Main.parent, 
    53                             tr("No data found in file {0}.", associatedFile.getPath()), 
     57                            tr("No data found in file {0}.", filePath), 
    5458                            tr("Open OSM file"), 
    5559                            JOptionPane.INFORMATION_MESSAGE); 
  • trunk/src/org/openstreetmap/josm/io/OsmReader.java

    r4414 r4490  
    99import java.util.ArrayList; 
    1010import java.util.Collection; 
    11 import java.util.HashMap; 
    12 import java.util.LinkedList; 
    13 import java.util.List; 
    14 import java.util.Map; 
    1511import java.util.regex.Matcher; 
    1612import java.util.regex.Pattern; 
     
    2925import org.openstreetmap.josm.data.osm.Node; 
    3026import org.openstreetmap.josm.data.osm.NodeData; 
    31 import org.openstreetmap.josm.data.osm.OsmPrimitive; 
    3227import org.openstreetmap.josm.data.osm.OsmPrimitiveType; 
    3328import org.openstreetmap.josm.data.osm.PrimitiveData; 
    34 import org.openstreetmap.josm.data.osm.PrimitiveId; 
    3529import org.openstreetmap.josm.data.osm.Relation; 
    3630import org.openstreetmap.josm.data.osm.RelationData; 
    37 import org.openstreetmap.josm.data.osm.RelationMember; 
    38 import org.openstreetmap.josm.data.osm.SimplePrimitiveId; 
     31import org.openstreetmap.josm.data.osm.RelationMemberData; 
    3932import org.openstreetmap.josm.data.osm.Tagged; 
    4033import org.openstreetmap.josm.data.osm.User; 
     
    5346 * entered, and it must point to the end of the same element, when it is exited. 
    5447 */ 
    55 public class OsmReader { 
    56  
    57     /** 
    58      * Used as a temporary storage for relation members, before they 
    59      * are resolved into pointers to real objects. 
    60      */ 
    61     private static class RelationMemberData { 
    62         public OsmPrimitiveType type; 
    63         public long id; 
    64         public String role; 
    65     } 
    66  
    67     /** 
    68      * The dataset to add parsed objects to. 
    69      */ 
    70     private DataSet ds = new DataSet(); 
     48public class OsmReader extends AbstractReader { 
    7149 
    7250    private XMLStreamReader parser; 
    73  
    74     /** the map from external ids to read OsmPrimitives. External ids are 
    75      * longs too, but in contrast to internal ids negative values are used 
    76      * to identify primitives unknown to the OSM server 
    77      */ 
    78     private Map<PrimitiveId, OsmPrimitive> externalIdMap = new HashMap<PrimitiveId, OsmPrimitive>(); 
    79  
    80     /** 
    81      * Data structure for the remaining way objects 
    82      */ 
    83     private Map<Long, Collection<Long>> ways = new HashMap<Long, Collection<Long>>(); 
    84  
    85     /** 
    86      * Data structure for relation objects 
    87      */ 
    88     private Map<Long, Collection<RelationMemberData>> relations = new HashMap<Long, Collection<RelationMemberData>>(); 
    89  
    90     private Changeset uploadChangeset; 
    9151 
    9252    /** 
     
    9656     */ 
    9757    private OsmReader() { 
    98         externalIdMap = new HashMap<PrimitiveId, OsmPrimitive>(); 
    9958    } 
    10059 
    10160    public void setParser(XMLStreamReader parser) { 
    10261        this.parser = parser; 
    103     } 
    104  
    105     /** 
    106      * Replies the parsed data set 
    107      * 
    108      * @return the parsed data set 
    109      */ 
    110     public DataSet getDataSet() { 
    111         return ds; 
    11262    } 
    11363 
     
    301251 
    302252    private RelationMemberData parseRelationMember(Relation r) throws XMLStreamException { 
    303         RelationMemberData emd = new RelationMemberData(); 
     253        String role = null; 
     254        OsmPrimitiveType type = null; 
     255        long id = 0; 
    304256        String value = parser.getAttributeValue(null, "ref"); 
    305257        if (value == null) { 
     
    307259        } 
    308260        try { 
    309             emd.id = Long.parseLong(value); 
     261            id = Long.parseLong(value); 
    310262        } catch(NumberFormatException e) { 
    311263            throwException(tr("Illegal value for attribute ''ref'' on member in relation {0}. Got {1}", Long.toString(r.getUniqueId()),value)); 
     
    313265        value = parser.getAttributeValue(null, "type"); 
    314266        if (value == null) { 
    315             throwException(tr("Missing attribute ''type'' on member {0} in relation {1}.", Long.toString(emd.id), Long.toString(r.getUniqueId()))); 
     267            throwException(tr("Missing attribute ''type'' on member {0} in relation {1}.", Long.toString(id), Long.toString(r.getUniqueId()))); 
    316268        } 
    317269        try { 
    318             emd.type = OsmPrimitiveType.fromApiTypeName(value); 
     270            type = OsmPrimitiveType.fromApiTypeName(value); 
    319271        } catch(IllegalArgumentException e) { 
    320             throwException(tr("Illegal value for attribute ''type'' on member {0} in relation {1}. Got {2}.", Long.toString(emd.id), Long.toString(r.getUniqueId()), value)); 
     272            throwException(tr("Illegal value for attribute ''type'' on member {0} in relation {1}. Got {2}.", Long.toString(id), Long.toString(r.getUniqueId()), value)); 
    321273        } 
    322274        value = parser.getAttributeValue(null, "role"); 
    323         emd.role = value; 
    324  
    325         if (emd.id == 0) { 
     275        role = value; 
     276 
     277        if (id == 0) { 
    326278            throwException(tr("Incomplete <member> specification with ref=0")); 
    327279        } 
    328280        jumpToEnd(); 
    329         return emd; 
     281        return new RelationMemberData(role, type, id); 
    330282    } 
    331283 
     
    580532 
    581533    /** 
    582      * Processes the parsed nodes after parsing. Just adds them to 
    583      * the dataset 
    584      * 
    585      */ 
    586     protected void processNodesAfterParsing() { 
    587         for (OsmPrimitive primitive: externalIdMap.values()) { 
    588             if (primitive instanceof Node) { 
    589                 this.ds.addPrimitive(primitive); 
    590             } 
    591         } 
    592     } 
    593  
    594     /** 
    595      * Processes the ways after parsing. Rebuilds the list of nodes of each way and 
    596      * adds the way to the dataset 
    597      * 
    598      * @throws IllegalDataException thrown if a data integrity problem is detected 
    599      */ 
    600     protected void processWaysAfterParsing() throws IllegalDataException{ 
    601         for (Long externalWayId: ways.keySet()) { 
    602             Way w = (Way)externalIdMap.get(new SimplePrimitiveId(externalWayId, OsmPrimitiveType.WAY)); 
    603             List<Node> wayNodes = new ArrayList<Node>(); 
    604             for (long id : ways.get(externalWayId)) { 
    605                 Node n = (Node)externalIdMap.get(new SimplePrimitiveId(id, OsmPrimitiveType.NODE)); 
    606                 if (n == null) { 
    607                     if (id <= 0) 
    608                         throw new IllegalDataException ( 
    609                                 tr("Way with external ID ''{0}'' includes missing node with external ID ''{1}''.", 
    610                                         externalWayId, 
    611                                         id)); 
    612                     // create an incomplete node if necessary 
    613                     // 
    614                     n = (Node)ds.getPrimitiveById(id,OsmPrimitiveType.NODE); 
    615                     if (n == null) { 
    616                         n = new Node(id); 
    617                         ds.addPrimitive(n); 
    618                     } 
    619                 } 
    620                 if (n.isDeleted()) { 
    621                     System.out.println(tr("Deleted node {0} is part of way {1}", id, w.getId())); 
    622                 } else { 
    623                     wayNodes.add(n); 
    624                 } 
    625             } 
    626             w.setNodes(wayNodes); 
    627             if (w.hasIncompleteNodes()) { 
    628                   System.out.println(tr("Way {0} with {1} nodes has incomplete nodes because at least one node was missing in the loaded data.", 
    629                           externalWayId, w.getNodesCount())); 
    630             } 
    631             ds.addPrimitive(w); 
    632         } 
    633     } 
    634  
    635     /** 
    636      * Completes the parsed relations with its members. 
    637      * 
    638      * @throws IllegalDataException thrown if a data integrity problem is detected, i.e. if a 
    639      * relation member refers to a local primitive which wasn't available in the data 
    640      * 
    641      */ 
    642     private void processRelationsAfterParsing() throws IllegalDataException { 
    643  
    644         // First add all relations to make sure that when relation reference other relation, the referenced will be already in dataset 
    645         for (Long externalRelationId : relations.keySet()) { 
    646             Relation relation = (Relation) externalIdMap.get( 
    647                     new SimplePrimitiveId(externalRelationId, OsmPrimitiveType.RELATION) 
    648             ); 
    649             ds.addPrimitive(relation); 
    650         } 
    651  
    652         for (Long externalRelationId : relations.keySet()) { 
    653             Relation relation = (Relation) externalIdMap.get( 
    654                     new SimplePrimitiveId(externalRelationId, OsmPrimitiveType.RELATION) 
    655             ); 
    656             List<RelationMember> relationMembers = new ArrayList<RelationMember>(); 
    657             for (RelationMemberData rm : relations.get(externalRelationId)) { 
    658                 OsmPrimitive primitive = null; 
    659  
    660                 // lookup the member from the map of already created primitives 
    661                 primitive = externalIdMap.get(new SimplePrimitiveId(rm.id, rm.type)); 
    662  
    663                 if (primitive == null) { 
    664                     if (rm.id <= 0) 
    665                         // relation member refers to a primitive with a negative id which was not 
    666                         // found in the data. This is always a data integrity problem and we abort 
    667                         // with an exception 
    668                         // 
    669                         throw new IllegalDataException( 
    670                                 tr("Relation with external id ''{0}'' refers to a missing primitive with external id ''{1}''.", 
    671                                         externalRelationId, 
    672                                         rm.id)); 
    673  
    674                     // member refers to OSM primitive which was not present in the parsed data 
    675                     // -> create a new incomplete primitive and add it to the dataset 
    676                     // 
    677                     primitive = ds.getPrimitiveById(rm.id, rm.type); 
    678                     if (primitive == null) { 
    679                         switch (rm.type) { 
    680                         case NODE: 
    681                             primitive = new Node(rm.id); break; 
    682                         case WAY: 
    683                             primitive = new Way(rm.id); break; 
    684                         case RELATION: 
    685                             primitive = new Relation(rm.id); break; 
    686                         default: throw new AssertionError(); // can't happen 
    687                         } 
    688  
    689                         ds.addPrimitive(primitive); 
    690                         externalIdMap.put(new SimplePrimitiveId(rm.id, rm.type), primitive); 
    691                     } 
    692                 } 
    693                 if (primitive.isDeleted()) { 
    694                     System.out.println(tr("Deleted member {0} is used by relation {1}", primitive.getId(), relation.getId())); 
    695                 } else { 
    696                     relationMembers.add(new RelationMember(rm.role, primitive)); 
    697                 } 
    698             } 
    699             relation.setMembers(relationMembers); 
    700         } 
    701     } 
    702  
    703     private void processChangesetAfterParsing() { 
    704         if (uploadChangeset != null) { 
    705             for (Map.Entry<String, String> e : uploadChangeset.getKeys().entrySet()) { 
    706                 ds.addChangeSetTag(e.getKey(), e.getValue()); 
    707             } 
    708         } 
    709     } 
    710  
    711     /** 
    712534     * Parse the given input source and return the dataset. 
    713535     * 
     
    736558 
    737559            progressMonitor.indeterminateSubTask(tr("Preparing data set...")); 
    738             reader.ds.beginUpdate(); 
    739             try { 
    740                 reader.processNodesAfterParsing(); 
    741                 reader.processWaysAfterParsing(); 
    742                 reader.processRelationsAfterParsing(); 
    743                 reader.processChangesetAfterParsing(); 
    744             } finally { 
    745                 reader.ds.endUpdate(); 
    746             } 
     560            reader.prepareDataSet(); 
    747561            progressMonitor.worked(1); 
    748562            return reader.getDataSet(); 
Note: See TracChangeset for help on using the changeset viewer.