Changeset 4490 in josm


Ignore:
Timestamp:
2011-10-06T21:04:04+02:00 (13 years 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.