Ticket #6886: patch.diff

File patch.diff, 59.1 KB (added by Don-vip, 13 years ago)
  • src/org/openstreetmap/josm/actions/ExtensionFileFilter.java

     
    4040        String[] importerNames = {
    4141                "org.openstreetmap.josm.io.OsmImporter",
    4242                "org.openstreetmap.josm.io.OsmGzipImporter",
     43                "org.openstreetmap.josm.io.PbfImporter",
    4344                "org.openstreetmap.josm.io.GpxImporter",
    4445                "org.openstreetmap.josm.io.NMEAImporter",
    4546                "org.openstreetmap.josm.io.OsmBzip2Importer",
  • src/org/openstreetmap/josm/data/coor/LatLon.java

     
    6363    public static boolean isValidLon(double lon) {
    6464        return lon >= -180d && lon <= 180d;
    6565    }
     66   
     67    /**
     68     * Replies true if lat is in the range [-90,90] and lon is in the range [-180,180]
     69     *
     70     * @return true if lat is in the range [-90,90] and lon is in the range [-180,180]
     71     */
     72    public boolean isValid() {
     73        return isValidLat(lat()) && isValidLon(lon());
     74    }
    6675
    6776    /**
    6877     * Replies the coordinate in degrees/minutes/seconds format
  • src/org/openstreetmap/josm/data/osm/AbstractPrimitive.java

     
    8686     * 0 if it wasn't uploaded to a changeset yet of if the changeset
    8787     * id isn't known.
    8888     */
    89     protected int changesetId;
     89    protected long changesetId;
    9090
    9191    protected int timestamp;
    9292
     
    233233     * @return the id of the changeset this primitive was last uploaded to.
    234234     */
    235235    @Override
    236     public int getChangesetId() {
     236    public long getChangesetId() {
    237237        return changesetId;
    238238    }
    239239
     
    246246     * @throws IllegalArgumentException thrown if id < 0
    247247     */
    248248    @Override
    249     public void setChangesetId(int changesetId) throws IllegalStateException, IllegalArgumentException {
     249    public void setChangesetId(long changesetId) throws IllegalStateException, IllegalArgumentException {
    250250        if (this.changesetId == changesetId)
    251251            return;
    252252        if (changesetId < 0)
     
    254254        if (isNew() && changesetId > 0)
    255255            throw new IllegalStateException(tr("Cannot assign a changesetId > 0 to a new primitive. Value of changesetId is {0}", changesetId));
    256256
    257         int old = this.changesetId;
     257        long old = this.changesetId;
    258258        this.changesetId = changesetId;
    259259    }
    260260
  • src/org/openstreetmap/josm/data/osm/Changeset.java

     
    1717 */
    1818public final class Changeset implements Tagged {
    1919    /** the changeset id */
    20     private int id;
     20    private long id;
    2121    /** the user who owns the changeset */
    2222    private User user;
    2323    /** date this changeset was created at */
     
    5252     *
    5353     * @param id the id
    5454     */
    55     public Changeset(int id) {
     55    public Changeset(long id) {
    5656        this.id = id;
    5757        this.incomplete = id > 0;
    5858        this.tags = new HashMap<String, String>();
     
    8383    }
    8484
    8585    public int compareTo(Changeset other) {
    86         return Integer.valueOf(getId()).compareTo(other.getId());
     86        return Long.valueOf(getId()).compareTo(other.getId());
    8787    }
    8888
    8989    public String getName() {
     
    9595        return formatter.format(this);
    9696    }
    9797
    98     public int getId() {
     98    public long getId() {
    9999        return id;
    100100    }
    101101
    102     public void setId(int id) {
     102    public void setId(long id) {
    103103        this.id = id;
    104104    }
    105105
     
    228228            return false;
    229229        return true;
    230230    }
    231 
     231   
     232    /* (non-Javadoc)
     233     * @see java.lang.Object#hashCode()
     234     */
    232235    @Override
    233236    public int hashCode() {
    234         if (id > 0)
    235             return id;
    236         else
     237        if (id > 0) {
     238            final int prime = 31;
     239            int result = 1;
     240            result = prime * result + (int) (id ^ (id >>> 32));
     241            return result;
     242        } else {
    237243            return super.hashCode();
     244        }
    238245    }
    239246
    240247    @Override
  • src/org/openstreetmap/josm/data/osm/ChangesetCache.java

     
    4646    }
    4747
    4848    /** the cached changesets */
    49     private final Map<Integer, Changeset> cache  = new HashMap<Integer, Changeset>();
     49    private final Map<Long, Changeset> cache  = new HashMap<Long, Changeset>();
    5050
    5151    private final CopyOnWriteArrayList<ChangesetCacheListener> listeners =
    5252        new CopyOnWriteArrayList<ChangesetCacheListener>();
     
    106106        fireChangesetCacheEvent(e);
    107107    }
    108108
    109     public boolean contains(int id) {
     109    public boolean contains(long id) {
    110110        if (id <=0) return false;
    111111        return cache.get(id) != null;
    112112    }
     
    117117        return contains(cs.getId());
    118118    }
    119119
    120     public Changeset get(int id) {
     120    public Changeset get(long id) {
    121121        return cache.get(id);
    122122    }
    123123
     
    125125        return new HashSet<Changeset>(cache.values());
    126126    }
    127127
    128     protected void remove(int id, DefaultChangesetCacheEvent e) {
     128    protected void remove(long id, DefaultChangesetCacheEvent e) {
    129129        if (id <= 0) return;
    130130        Changeset cs = cache.get(id);
    131131        if (cs == null) return;
     
    133133        e.rememberRemovedChangeset(cs);
    134134    }
    135135
    136     public void remove(int id) {
     136    public void remove(long id) {
    137137        DefaultChangesetCacheEvent e = new DefaultChangesetCacheEvent(this);
    138138        remove(id, e);
    139139        if (! e.isEmpty()) {
  • src/org/openstreetmap/josm/data/osm/DataSet.java

     
    10581058        fireEvent(new WayNodesChangedEvent(this, way));
    10591059    }
    10601060
    1061     void fireChangesetIdChanged(OsmPrimitive primitive, int oldChangesetId, int newChangesetId) {
     1061    void fireChangesetIdChanged(OsmPrimitive primitive, long oldChangesetId, long newChangesetId) {
    10621062        fireEvent(new ChangesetIdChangedEvent(this, Collections.singletonList(primitive), oldChangesetId, newChangesetId));
    10631063    }
    10641064
  • src/org/openstreetmap/josm/data/osm/IPrimitive.java

     
    2727    Date getTimestamp();
    2828    void setTimestamp(Date timestamp);
    2929    boolean isTimestampEmpty();
    30     int getChangesetId();
    31     void setChangesetId(int changesetId);
     30    long getChangesetId();
     31    void setChangesetId(long changesetId);
    3232
    3333    void visit(PrimitiveVisitor visitor);
    3434    String getName();
  • src/org/openstreetmap/josm/data/osm/OsmPrimitive.java

     
    384384    }
    385385
    386386    @Override
    387     public void setChangesetId(int changesetId) throws IllegalStateException, IllegalArgumentException {
     387    public void setChangesetId(long changesetId) throws IllegalStateException, IllegalArgumentException {
    388388        boolean locked = writeLock();
    389389        try {
    390             int old = this.changesetId;
     390            long old = this.changesetId;
    391391            super.setChangesetId(changesetId);
    392392            if (dataSet != null) {
    393393                dataSet.fireChangesetIdChanged(this, old, changesetId);
  • src/org/openstreetmap/josm/data/osm/event/ChangesetIdChangedEvent.java

     
    99public class ChangesetIdChangedEvent extends AbstractDatasetChangedEvent {
    1010
    1111    private final List<OsmPrimitive> primitives;
    12     private final int oldChangesetId;
    13     private final int newChangesetId;
     12    private final long oldChangesetId;
     13    private final long newChangesetId;
    1414
    15     public ChangesetIdChangedEvent(DataSet dataSet, List<OsmPrimitive> primitives, int oldChangesetId, int newChangesetId) {
     15    public ChangesetIdChangedEvent(DataSet dataSet, List<OsmPrimitive> primitives, long oldChangesetId, long newChangesetId) {
    1616        super(dataSet);
    1717        this.primitives = primitives;
    1818        this.oldChangesetId = oldChangesetId;
     
    3434        return DatasetEventType.CHANGESET_ID_CHANGED;
    3535    }
    3636
    37     public int getOldChangesetId() {
     37    public long getOldChangesetId() {
    3838        return oldChangesetId;
    3939    }
    4040
    41     public int getNewChangesetId() {
     41    public long getNewChangesetId() {
    4242        return newChangesetId;
    4343    }
    4444
  • src/org/openstreetmap/josm/gui/dialogs/ChangesetDialog.java

     
    256256        public void mouseClicked(MouseEvent e) {
    257257            if (!SwingUtilities.isLeftMouseButton(e) || e.getClickCount() < 2)
    258258                return;
    259             Set<Integer> sel = getCurrentChangesetListModel().getSelectedChangesetIds();
     259            Set<Long> sel = getCurrentChangesetListModel().getSelectedChangesetIds();
    260260            if (sel.isEmpty())
    261261                return;
    262262            if (Main.main.getCurrentDataSet() == null)
     
    292292            updateEnabledState();
    293293        }
    294294
    295         public void selectObjectsByChangesetIds(DataSet ds, Set<Integer> ids) {
     295        public void selectObjectsByChangesetIds(DataSet ds, Set<Long> ids) {
    296296            if (ds == null || ids == null)
    297297                return;
    298298            Set<OsmPrimitive> sel = new HashSet<OsmPrimitive>();
     
    308308            if (Main.main.getEditLayer() == null)
    309309                return;
    310310            ChangesetListModel model = getCurrentChangesetListModel();
    311             Set<Integer> sel = model.getSelectedChangesetIds();
     311            Set<Long> sel = model.getSelectedChangesetIds();
    312312            if (sel.isEmpty())
    313313                return;
    314314
     
    344344
    345345        public void actionPerformed(ActionEvent arg0) {
    346346            ChangesetListModel model = getCurrentChangesetListModel();
    347             Set<Integer> sel = model.getSelectedChangesetIds();
     347            Set<Long> sel = model.getSelectedChangesetIds();
    348348            if (sel.isEmpty())
    349349                return;
    350350            ChangesetHeaderDownloadTask task = new ChangesetHeaderDownloadTask(sel);
     
    448448            putValue(SMALL_ICON, ImageProvider.get("dialogs/changeset", "changesetmanager"));
    449449        }
    450450
    451         protected void launchChangesetManager(Collection<Integer> toSelect) {
     451        protected void launchChangesetManager(Collection<Long> toSelect) {
    452452            ChangesetCacheManager cm = ChangesetCacheManager.getInstance();
    453453            if (cm.isVisible()) {
    454454                cm.setExtendedState(Frame.NORMAL);
     
    464464
    465465        public void actionPerformed(ActionEvent arg0) {
    466466            ChangesetListModel model = getCurrentChangesetListModel();
    467             Set<Integer> sel = model.getSelectedChangesetIds();
    468             final Set<Integer> toDownload = new HashSet<Integer>();
     467            Set<Long> sel = model.getSelectedChangesetIds();
     468            final Set<Long> toDownload = new HashSet<Long>();
    469469            ChangesetCache cc = ChangesetCache.getInstance();
    470             for (int id: sel) {
     470            for (long id: sel) {
    471471                if (!cc.contains(id)) {
    472472                    toDownload.add(id);
    473473                }
  • src/org/openstreetmap/josm/gui/dialogs/InspectPrimitiveDialog.java

     
    221221            add(tr("Edited by: "), o.getUser() == null ? tr("<new object>")
    222222                    : getNameAndId(o.getUser().getName(), o.getUser().getId()));
    223223            add(tr("Version: "), Integer.toString(o.getVersion()));
    224             add(tr("In changeset: "), Integer.toString(o.getChangesetId()));
     224            add(tr("In changeset: "), Long.toString(o.getChangesetId()));
    225225        }
    226226
    227227        void addAttributes(OsmPrimitive o) {
  • src/org/openstreetmap/josm/gui/dialogs/changeset/ChangesetCacheManager.java

     
    606606     *
    607607     * @param ids the collection of ids. If null, the selection is cleared.
    608608     */
    609     public void setSelectedChangesetsById(Collection<Integer> ids) {
     609    public void setSelectedChangesetsById(Collection<Long> ids) {
    610610        if (ids == null) {
    611611            setSelectedChangesets(null);
    612612            return;
    613613        }
    614614        Set<Changeset> toSelect = new HashSet<Changeset>();
    615615        ChangesetCache cc = ChangesetCache.getInstance();
    616         for (int id: ids) {
     616        for (long id: ids) {
    617617            if (cc.contains(id)) {
    618618                toSelect.add(cc.get(id));
    619619            }
  • src/org/openstreetmap/josm/gui/dialogs/changeset/ChangesetCacheManagerModel.java

     
    8989     *
    9090     * @return a set of ids of the selected changesets
    9191     */
    92     public Set<Integer> getSelectedChangesetIds() {
    93         Set<Integer> ret = new HashSet<Integer>();
     92    public Set<Long> getSelectedChangesetIds() {
     93        Set<Long> ret = new HashSet<Long>();
    9494        for (Changeset cs: getSelectedChangesets()) {
    9595            ret.add(cs.getId());
    9696        }
  • src/org/openstreetmap/josm/gui/dialogs/changeset/ChangesetCacheTableCellRenderer.java

     
    4141    }
    4242
    4343    protected void renderId(Changeset cs) {
    44         setText(Integer.toString(cs.getId()));
     44        setText(Long.toString(cs.getId()));
    4545        setToolTipText("");
    4646    }
    4747
  • src/org/openstreetmap/josm/gui/dialogs/changeset/ChangesetContentDownloadTask.java

     
    3131public class ChangesetContentDownloadTask extends PleaseWaitRunnable implements ChangesetDownloadTask{
    3232
    3333    /** the list of changeset ids to download */
    34     private final List<Integer> toDownload = new ArrayList<Integer>();
     34    private final List<Long> toDownload = new ArrayList<Long>();
    3535    /** true if the task was canceled */
    3636    private boolean canceled;
    3737    /** keeps the last exception thrown in the task, if any */
     
    4646     *
    4747     * @param ids the collection of ids. May be null.
    4848     */
    49     protected void init(Collection<Integer> ids) {
     49    protected void init(Collection<Long> ids) {
    5050        if (ids == null) {
    5151            ids = Collections.emptyList();
    5252        }
    53         for (Integer id: ids) {
     53        for (Long id: ids) {
    5454            if (id == null || id <= 0) {
    5555                continue;
    5656            }
     
    6565     * @param changesetId the changeset id. >0 required.
    6666     * @throws IllegalArgumentException thrown if changesetId <= 0
    6767     */
    68     public ChangesetContentDownloadTask(int changesetId) throws IllegalArgumentException{
     68    public ChangesetContentDownloadTask(long changesetId) throws IllegalArgumentException{
    6969        super(tr("Downloading changeset content"), false /* don't ignore exceptions */);
    7070        if (changesetId <= 0)
    7171            throw new IllegalArgumentException(MessageFormat.format("Expected integer value > 0 for parameter ''{0}'', got ''{1}''", "changesetId", changesetId));
     
    7878     *
    7979     * @param changesetIds the changeset ids. Empty collection assumed, if null.
    8080     */
    81     public ChangesetContentDownloadTask(Collection<Integer> changesetIds) {
     81    public ChangesetContentDownloadTask(Collection<Long> changesetIds) {
    8282        super(tr("Downloading changeset content"), false /* don't ignore exceptions */);
    8383        init(changesetIds);
    8484    }
     
    9191     * @throws IllegalArgumentException thrown if changesetId <= 0
    9292     * @throws IllegalArgumentException thrown if parent is null
    9393     */
    94     public ChangesetContentDownloadTask(Component parent, int changesetId) throws IllegalArgumentException{
     94    public ChangesetContentDownloadTask(Component parent, long changesetId) throws IllegalArgumentException{
    9595        super(parent, tr("Downloading changeset content"), false /* don't ignore exceptions */);
    9696        if (changesetId <= 0)
    9797            throw new IllegalArgumentException(MessageFormat.format("Expected integer value > 0 for parameter ''{0}'', got ''{1}''", "changesetId", changesetId));
     
    106106     * @param changesetIds the changeset ids. Empty collection assumed, if null.
    107107     * @throws IllegalArgumentException thrown if parent is null
    108108     */
    109     public ChangesetContentDownloadTask(Component parent, Collection<Integer> changesetIds) throws IllegalArgumentException {
     109    public ChangesetContentDownloadTask(Component parent, Collection<Long> changesetIds) throws IllegalArgumentException {
    110110        super(parent, tr("Downloading changeset content"), false /* don't ignore exceptions */);
    111111        init(changesetIds);
    112112    }
     
    119119     * @return true if the local {@see ChangesetCache} already includes the changeset with
    120120     * id <code>changesetId</code>
    121121     */
    122     protected boolean isAvailableLocally(int changesetId) {
     122    protected boolean isAvailableLocally(long changesetId) {
    123123        return ChangesetCache.getInstance().get(changesetId) != null;
    124124    }
    125125
     
    130130     * @param changesetId the changeset id
    131131     * @throws OsmTransferException thrown if something went wrong
    132132     */
    133     protected void downloadChangeset(int changesetId) throws OsmTransferException {
     133    protected void downloadChangeset(long changesetId) throws OsmTransferException {
    134134        synchronized(this) {
    135135            reader = new OsmServerChangesetReader();
    136136        }
     
    164164        try {
    165165            getProgressMonitor().setTicksCount(toDownload.size());
    166166            int i=0;
    167             for (int id: toDownload) {
     167            for (long id: toDownload) {
    168168                i++;
    169169                if (!isAvailableLocally(id)) {
    170170                    getProgressMonitor().setCustomText(tr("({0}/{1}) Downloading changeset {2}...", i, toDownload.size(), id));
  • src/org/openstreetmap/josm/gui/dialogs/changeset/ChangesetDetailPanel.java

     
    206206    protected void updateView(Changeset cs) {
    207207        String msg;
    208208        if (cs == null) return;
    209         tfID.setText(Integer.toString(cs.getId()));
     209        tfID.setText(Long.toString(cs.getId()));
    210210        String comment = cs.get("comment");
    211211        taComment.setText(comment == null ? "" : comment);
    212212
  • src/org/openstreetmap/josm/gui/dialogs/changeset/ChangesetHeaderDownloadTask.java

     
    6464            changesets = Collections.emptyList();
    6565        }
    6666
    67         HashSet<Integer> ids = new HashSet<Integer>();
     67        HashSet<Long> ids = new HashSet<Long>();
    6868        for (Changeset cs: changesets) {
    6969            if (cs == null || cs.isNew()) {
    7070                continue;
     
    7878
    7979    }
    8080
    81     private Set<Integer> idsToDownload;
     81    private Set<Long> idsToDownload;
    8282    private OsmServerChangesetReader reader;
    8383    private boolean canceled;
    8484    private Exception lastException;
    8585    private Set<Changeset> downloadedChangesets;
    8686
    87     protected void init(Collection<Integer> ids) {
     87    protected void init(Collection<Long> ids) {
    8888        if (ids == null) {
    8989            ids = Collections.emptyList();
    9090        }
    91         idsToDownload = new HashSet<Integer>();
     91        idsToDownload = new HashSet<Long>();
    9292        if (ids == null ||  ids.isEmpty())
    9393            return;
    94         for (int id: ids) {
     94        for (long id: ids) {
    9595            if (id <= 0) {
    9696                continue;
    9797            }
     
    107107     *
    108108     * @param ids the collection of ids. Empty collection assumed if null.
    109109     */
    110     public ChangesetHeaderDownloadTask(Collection<Integer> ids) {
     110    public ChangesetHeaderDownloadTask(Collection<Long> ids) {
    111111        // parent for dialog is Main.parent
    112112        super(tr("Download changesets"), false /* don't ignore exceptions */);
    113113        init(ids);
     
    123123     * @param ids the collection of ids. Empty collection assumed if null.
    124124     * @throws IllegalArgumentException thrown if dialogParent is null
    125125     */
    126     public ChangesetHeaderDownloadTask(Component dialogParent, Collection<Integer> ids) throws IllegalArgumentException{
     126    public ChangesetHeaderDownloadTask(Component dialogParent, Collection<Long> ids) throws IllegalArgumentException{
    127127        super(dialogParent,tr("Download changesets"), false /* don't ignore exceptions */);
    128128        init(ids);
    129129    }
  • src/org/openstreetmap/josm/gui/dialogs/changeset/ChangesetListModel.java

     
    3939        return ret;
    4040    }
    4141
    42     public Set<Integer> getSelectedChangesetIds() {
    43         Set<Integer> ret = new HashSet<Integer>();
     42    public Set<Long> getSelectedChangesetIds() {
     43        Set<Long> ret = new HashSet<Long>();
    4444        for (int i=0; i < getSize(); i++) {
    4545            if (selectionModel.isSelectedIndex(i)) {
    4646                ret.add(data.get(i).getId());
  • src/org/openstreetmap/josm/gui/dialogs/changeset/SingleChangesetDownloadPanel.java

     
    8383        public void actionPerformed(ActionEvent arg0) {
    8484            if (!isEnabled())
    8585                return;
    86             int id = getChangesetId();
     86            long id = getChangesetId();
    8787            if (id == 0) return;
    8888            ChangesetContentDownloadTask task =  new ChangesetContentDownloadTask(
    8989                    SingleChangesetDownloadPanel.this,
  • src/org/openstreetmap/josm/io/AbstractReader.java

     
     1// License: GPL. For details, see LICENSE file.
     2package org.openstreetmap.josm.io;
     3
     4import static org.openstreetmap.josm.tools.I18n.tr;
     5
     6import java.util.ArrayList;
     7import java.util.Collection;
     8import java.util.HashMap;
     9import java.util.List;
     10import java.util.Map;
     11
     12import org.openstreetmap.josm.data.osm.Changeset;
     13import org.openstreetmap.josm.data.osm.DataSet;
     14import org.openstreetmap.josm.data.osm.Node;
     15import org.openstreetmap.josm.data.osm.OsmPrimitive;
     16import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
     17import org.openstreetmap.josm.data.osm.PrimitiveId;
     18import org.openstreetmap.josm.data.osm.Relation;
     19import org.openstreetmap.josm.data.osm.RelationMember;
     20import org.openstreetmap.josm.data.osm.SimplePrimitiveId;
     21import org.openstreetmap.josm.data.osm.Way;
     22
     23/**
     24 * Base class for OsmReader (XML file format) and PbfReader (Protobuf file format)
     25 * @author Vincent
     26 *
     27 */
     28public abstract class AbstractReader {
     29   
     30    /**
     31     * Used as a temporary storage for relation members, before they
     32     * are resolved into pointers to real objects.
     33     */
     34    protected static class RelationMemberData {
     35        public OsmPrimitiveType type;
     36        public long id;
     37        public String role;
     38    }
     39
     40    /**
     41     * The dataset to add parsed objects to.
     42     */
     43    protected final DataSet ds = new DataSet();
     44
     45    protected Changeset uploadChangeset;
     46
     47    /** the map from external ids to read OsmPrimitives. External ids are
     48     * longs too, but in contrast to internal ids negative values are used
     49     * to identify primitives unknown to the OSM server
     50     */
     51    protected Map<PrimitiveId, OsmPrimitive> externalIdMap = new HashMap<PrimitiveId, OsmPrimitive>();
     52
     53    /**
     54     * Data structure for the remaining way objects
     55     */
     56    protected Map<Long, Collection<Long>> ways = new HashMap<Long, Collection<Long>>();
     57
     58    /**
     59     * Data structure for relation objects
     60     */
     61    protected Map<Long, Collection<RelationMemberData>> relations = new HashMap<Long, Collection<RelationMemberData>>();
     62
     63    /**
     64     * Replies the parsed data set
     65     *
     66     * @return the parsed data set
     67     */
     68    public DataSet getDataSet() {
     69        return ds;
     70    }
     71   
     72    /**
     73     * Processes the parsed nodes after parsing. Just adds them to
     74     * the dataset
     75     *
     76     */
     77    private void processNodesAfterParsing() {
     78        for (OsmPrimitive primitive: externalIdMap.values()) {
     79            if (primitive instanceof Node) {
     80                this.ds.addPrimitive(primitive);
     81            }
     82        }
     83    }
     84
     85    /**
     86     * Processes the ways after parsing. Rebuilds the list of nodes of each way and
     87     * adds the way to the dataset
     88     *
     89     * @throws IllegalDataException thrown if a data integrity problem is detected
     90     */
     91    private void processWaysAfterParsing() throws IllegalDataException{
     92        for (Long externalWayId: ways.keySet()) {
     93            Way w = (Way)externalIdMap.get(new SimplePrimitiveId(externalWayId, OsmPrimitiveType.WAY));
     94            List<Node> wayNodes = new ArrayList<Node>();
     95            for (long id : ways.get(externalWayId)) {
     96                Node n = (Node)externalIdMap.get(new SimplePrimitiveId(id, OsmPrimitiveType.NODE));
     97                if (n == null) {
     98                    if (id <= 0)
     99                        throw new IllegalDataException (
     100                                tr("Way with external ID ''{0}'' includes missing node with external ID ''{1}''.",
     101                                        externalWayId,
     102                                        id));
     103                    // create an incomplete node if necessary
     104                    //
     105                    n = (Node)ds.getPrimitiveById(id,OsmPrimitiveType.NODE);
     106                    if (n == null) {
     107                        n = new Node(id);
     108                        ds.addPrimitive(n);
     109                    }
     110                }
     111                if (n.isDeleted()) {
     112                    System.out.println(tr("Deleted node {0} is part of way {1}", id, w.getId()));
     113                } else {
     114                    wayNodes.add(n);
     115                }
     116            }
     117            w.setNodes(wayNodes);
     118            if (w.hasIncompleteNodes()) {
     119                  System.out.println(tr("Way {0} with {1} nodes has incomplete nodes because at least one node was missing in the loaded data.",
     120                          externalWayId, w.getNodesCount()));
     121            }
     122            ds.addPrimitive(w);
     123        }
     124    }
     125
     126    /**
     127     * Completes the parsed relations with its members.
     128     *
     129     * @throws IllegalDataException thrown if a data integrity problem is detected, i.e. if a
     130     * relation member refers to a local primitive which wasn't available in the data
     131     *
     132     */
     133    private void processRelationsAfterParsing() throws IllegalDataException {
     134
     135        // First add all relations to make sure that when relation reference other relation, the referenced will be already in dataset
     136        for (Long externalRelationId : relations.keySet()) {
     137            Relation relation = (Relation) externalIdMap.get(
     138                    new SimplePrimitiveId(externalRelationId, OsmPrimitiveType.RELATION)
     139            );
     140            ds.addPrimitive(relation);
     141        }
     142
     143        for (Long externalRelationId : relations.keySet()) {
     144            Relation relation = (Relation) externalIdMap.get(
     145                    new SimplePrimitiveId(externalRelationId, OsmPrimitiveType.RELATION)
     146            );
     147            List<RelationMember> relationMembers = new ArrayList<RelationMember>();
     148            for (RelationMemberData rm : relations.get(externalRelationId)) {
     149                OsmPrimitive primitive = null;
     150
     151                // lookup the member from the map of already created primitives
     152                primitive = externalIdMap.get(new SimplePrimitiveId(rm.id, rm.type));
     153
     154                if (primitive == null) {
     155                    if (rm.id <= 0)
     156                        // relation member refers to a primitive with a negative id which was not
     157                        // found in the data. This is always a data integrity problem and we abort
     158                        // with an exception
     159                        //
     160                        throw new IllegalDataException(
     161                                tr("Relation with external id ''{0}'' refers to a missing primitive with external id ''{1}''.",
     162                                        externalRelationId,
     163                                        rm.id));
     164
     165                    // member refers to OSM primitive which was not present in the parsed data
     166                    // -> create a new incomplete primitive and add it to the dataset
     167                    //
     168                    primitive = ds.getPrimitiveById(rm.id, rm.type);
     169                    if (primitive == null) {
     170                        switch (rm.type) {
     171                        case NODE:
     172                            primitive = new Node(rm.id); break;
     173                        case WAY:
     174                            primitive = new Way(rm.id); break;
     175                        case RELATION:
     176                            primitive = new Relation(rm.id); break;
     177                        default: throw new AssertionError(); // can't happen
     178                        }
     179
     180                        ds.addPrimitive(primitive);
     181                        externalIdMap.put(new SimplePrimitiveId(rm.id, rm.type), primitive);
     182                    }
     183                }
     184                if (primitive.isDeleted()) {
     185                    System.out.println(tr("Deleted member {0} is used by relation {1}", primitive.getId(), relation.getId()));
     186                } else {
     187                    relationMembers.add(new RelationMember(rm.role, primitive));
     188                }
     189            }
     190            relation.setMembers(relationMembers);
     191        }
     192    }
     193
     194    private void processChangesetAfterParsing() {
     195        if (uploadChangeset != null) {
     196            for (Map.Entry<String, String> e : uploadChangeset.getKeys().entrySet()) {
     197                ds.addChangeSetTag(e.getKey(), e.getValue());
     198            }
     199        }
     200    }
     201   
     202    protected final void prepareDataSet() throws IllegalDataException {
     203        try {
     204            ds.beginUpdate();
     205            processNodesAfterParsing();
     206            processWaysAfterParsing();
     207            processRelationsAfterParsing();
     208            processChangesetAfterParsing();
     209        } finally {
     210            ds.endUpdate();
     211        }
     212    }
     213}
  • src/org/openstreetmap/josm/io/AllFormatsImporter.java

     
    1212 */
    1313public class AllFormatsImporter extends FileImporter {
    1414    public AllFormatsImporter() {
    15         super(new ExtensionFileFilter("osm,xml,osm.gz,osm.bz2,osm.bz,gpx,gpx.gz,nmea,nme,nma,log,txt,wms,jpg", "", tr("All Formats")
     15        super(new ExtensionFileFilter("osm,xml,osm.gz,osm.bz2,osm.bz,osm.pbf,gpx,gpx.gz,nmea,nme,nma,log,txt,wms,jpg", "", tr("All Formats")
    1616                    + " (*.gpx *.osm *.nmea *.jpg ...)"));
    1717    }
    1818    @Override public boolean acceptFile(File pathname) {
  • src/org/openstreetmap/josm/io/OsmImporter.java

     
    4242    protected void importData(InputStream in, final File associatedFile) throws IllegalDataException {
    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        //
    4751        Runnable uiStuff = new Runnable() {
     
    5054                if (dataSet.allPrimitives().isEmpty()) {
    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);
    5660                }
  • src/org/openstreetmap/josm/io/OsmReader.java

     
    88import java.text.MessageFormat;
    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;
    1713
     14import javax.xml.stream.Location;
    1815import javax.xml.stream.XMLInputFactory;
    19 import javax.xml.stream.XMLStreamReader;
    2016import javax.xml.stream.XMLStreamConstants;
    2117import javax.xml.stream.XMLStreamException;
    22 import javax.xml.stream.Location;
     18import javax.xml.stream.XMLStreamReader;
    2319
    2420import org.openstreetmap.josm.data.Bounds;
    2521import org.openstreetmap.josm.data.coor.LatLon;
     
    2824import org.openstreetmap.josm.data.osm.DataSource;
    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;
    3931import org.openstreetmap.josm.data.osm.Tagged;
    4032import org.openstreetmap.josm.data.osm.User;
    4133import org.openstreetmap.josm.data.osm.Way;
     
    5244 * The XMLStreamReader cursor points to the start of the element, when the method is
    5345 * entered, and it must point to the end of the same element, when it is exited.
    5446 */
    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();
     47public class OsmReader extends AbstractReader {
    7148
    7249    private XMLStreamReader parser;
    7350
    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;
    91 
    92     /**
    93      * constructor (for private use only)
    94      *
    95      * @see #parseDataSet(InputStream, DataSet, ProgressMonitor)
    96      */
    97     private OsmReader() {
    98         externalIdMap = new HashMap<PrimitiveId, OsmPrimitive>();
    99     }
    100 
    10151    public void setParser(XMLStreamReader parser) {
    10252        this.parser = parser;
    10353    }
    10454
    105     /**
    106      * Replies the parsed data set
    107      *
    108      * @return the parsed data set
    109      */
    110     public DataSet getDataSet() {
    111         return ds;
    112     }
    113 
    11455    protected void throwException(String msg) throws XMLStreamException {
    11556        throw new OsmParsingException(msg, parser.getLocation());
    11657    }
     
    13677        parser.close();
    13778    }
    13879
     80    @SuppressWarnings("null")
    13981    private void parseOsm() throws XMLStreamException {
    14082        String v = parser.getAttributeValue(null, "version");
    14183        if (v == null) {
     
    351293        }
    352294    }
    353295
     296    @SuppressWarnings("null")
    354297    private void parseTag(Tagged t) throws XMLStreamException {
    355298        String key = parser.getAttributeValue(null, "k");
    356299        String value = parser.getAttributeValue(null, "v");
     
    579522    }
    580523
    581524    /**
    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     /**
    712525     * Parse the given input source and return the dataset.
    713526     *
    714527     * @param source the source input stream. Must not be null.
     
    735548            progressMonitor.worked(1);
    736549
    737550            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             }
     551            reader.prepareDataSet();
    747552            progressMonitor.worked(1);
    748553            return reader.getDataSet();
    749554        } catch(IllegalDataException e) {
  • src/org/openstreetmap/josm/io/OsmServerChangesetReader.java

     
    120120     * @throws OsmTransferException thrown if something goes wrong
    121121     * @throws IllegalArgumentException if id <= 0
    122122     */
    123     public List<Changeset> readChangesets(Collection<Integer> ids, ProgressMonitor monitor) throws OsmTransferException {
     123    public List<Changeset> readChangesets(Collection<Long> ids, ProgressMonitor monitor) throws OsmTransferException {
    124124        if (ids == null)
    125125            return Collections.emptyList();
    126126        if (monitor == null) {
     
    131131            monitor.setTicksCount(ids.size());
    132132            List<Changeset> ret = new ArrayList<Changeset>();
    133133            int i=0;
    134             for (Iterator<Integer> it = ids.iterator(); it.hasNext(); ) {
    135                 int id = it.next();
     134            for (Iterator<Long> it = ids.iterator(); it.hasNext(); ) {
     135                long id = it.next();
    136136                if (id <= 0) {
    137137                    continue;
    138138                }
     
    169169     * @throws IllegalArgumentException thrown if id <= 0
    170170     * @throws OsmTransferException thrown if something went wrong
    171171     */
    172     public ChangesetDataSet downloadChangeset(int id, ProgressMonitor monitor) throws IllegalArgumentException, OsmTransferException {
     172    public ChangesetDataSet downloadChangeset(long id, ProgressMonitor monitor) throws IllegalArgumentException, OsmTransferException {
    173173        if (id <= 0)
    174174            throw new IllegalArgumentException(MessageFormat.format("Expected value of type integer > 0 for parameter ''{0}'', got {1}", "id", id));
    175175        if (monitor == null) {
  • src/org/openstreetmap/josm/io/PbfImporter.java

     
     1// License: GPL. For details, see LICENSE file.
     2package org.openstreetmap.josm.io;
     3
     4import static org.openstreetmap.josm.tools.I18n.tr;
     5
     6import java.io.File;
     7import java.io.InputStream;
     8
     9import org.openstreetmap.josm.actions.ExtensionFileFilter;
     10import org.openstreetmap.josm.data.osm.DataSet;
     11import org.openstreetmap.josm.gui.layer.OsmDataLayer;
     12import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
     13
     14/**
     15 * @author Vincent
     16 *
     17 */
     18public class PbfImporter extends OsmImporter {
     19   
     20    public PbfImporter() {
     21        super(new ExtensionFileFilter("osm.pbf", "osm.pbf", tr("OSM Server Files PBF compressed") + " (*.osm.pbf)"));
     22    }
     23
     24    /* (non-Javadoc)
     25     * @see org.openstreetmap.josm.io.OsmImporter#importData(java.io.InputStream, java.io.File)
     26     */
     27    @Override
     28    protected void importData(InputStream in, File associatedFile) throws IllegalDataException {
     29        final DataSet dataSet = PbfReader.parseDataSet(in, NullProgressMonitor.INSTANCE);
     30        final OsmDataLayer layer = new OsmDataLayer(dataSet, associatedFile.getName(), associatedFile);
     31        addDataLayer(dataSet, layer, associatedFile.getPath());
     32    }
     33}
  • src/org/openstreetmap/josm/io/PbfReader.java

     
     1// License: GPL. For details, see LICENSE file.
     2package org.openstreetmap.josm.io;
     3
     4import static org.openstreetmap.josm.tools.I18n.tr;
     5
     6import java.io.IOException;
     7import java.io.InputStream;
     8import java.util.ArrayList;
     9import java.util.Collection;
     10import java.util.Date;
     11import java.util.HashMap;
     12import java.util.List;
     13import java.util.Map;
     14
     15import org.openstreetmap.josm.data.coor.LatLon;
     16import org.openstreetmap.josm.data.osm.DataSet;
     17import org.openstreetmap.josm.data.osm.Node;
     18import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
     19import org.openstreetmap.josm.data.osm.Relation;
     20import org.openstreetmap.josm.data.osm.User;
     21import org.openstreetmap.josm.data.osm.Way;
     22import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
     23import org.openstreetmap.josm.gui.progress.ProgressMonitor;
     24import org.openstreetmap.josm.tools.CheckParameterUtil;
     25
     26import crosby.binary.BinaryParser;
     27import crosby.binary.Osmformat;
     28import crosby.binary.Osmformat.DenseNodes;
     29import crosby.binary.Osmformat.HeaderBlock;
     30import crosby.binary.file.BlockInputStream;
     31
     32/**
     33 * @author Vincent
     34 *
     35 */
     36public class PbfReader extends AbstractReader {
     37   
     38    protected class PbfParser extends BinaryParser {
     39
     40        @Override
     41        protected void parse(HeaderBlock header) {
     42        }
     43
     44        @Override
     45        protected void parseDense(DenseNodes nodes) {
     46            int keyindex = 0;
     47            // Almost all data is DELTA coded
     48            long previousId = 0;
     49            long previousLat = 0;
     50            long previousLon = 0;
     51            long previousChangesetId = 0;
     52            int previousUid = 0;
     53            int previousSuid = 0;
     54            long previousTimestamp = 0;
     55            for (int i = 0; i < nodes.getIdCount(); i++) {
     56                // Id (delta) and version (normal)
     57                Node node = new Node(previousId+=nodes.getId(i), nodes.getDenseinfo().getVersion(i));
     58                // Lat/Lon (delta)
     59                node.setCoor(new LatLon(parseLat(previousLat+=nodes.getLat(i)), parseLon(previousLon+=nodes.getLon(i))));
     60                // Changeset (delta)
     61                node.setChangesetId(previousChangesetId+=nodes.getDenseinfo().getChangeset(i));
     62                // User (delta)
     63                node.setUser(User.createOsmUser(previousUid+=nodes.getDenseinfo().getUid(i), getStringById(previousSuid+=nodes.getDenseinfo().getUserSid(i))));
     64                // Timestamp (delta)
     65                node.setTimestamp(new Date(previousTimestamp+=nodes.getDenseinfo().getTimestamp(i)));
     66                // A single table contains all keys/values of all nodes.
     67                // Each node's tags are encoded in alternating <key_id> <value_id>.
     68                // A single stringid of 0 delimit when the tags of a node ends and the tags of the next node begin.
     69                Map<String, String> keys = new HashMap<String, String>();
     70                while (keyindex < nodes.getKeysValsCount()) {
     71                    int key_id = nodes.getKeysVals(keyindex++);
     72                    if (key_id == 0) {
     73                        break; // End of current node's tags
     74                    } else {
     75                        int value_id = nodes.getKeysVals(keyindex++);
     76                        keys.put(getStringById(key_id), getStringById(value_id));
     77                    }
     78                }
     79                node.setKeys(keys);
     80                externalIdMap.put(node.getPrimitiveId(), node);
     81            }
     82        }
     83
     84        @Override
     85        protected void parseNodes(List<Osmformat.Node> osmNodes) {
     86            for (Osmformat.Node n : osmNodes) {
     87                Node node = new Node(n.getId(), n.getInfo().getVersion());
     88                node.setCoor(new LatLon(parseLat(n.getLat()), parseLon(n.getLon())));
     89                node.setChangesetId(n.getInfo().getChangeset());
     90                node.setUser(User.createOsmUser(n.getInfo().getUid(), getStringById(n.getInfo().getUserSid())));
     91                node.setTimestamp(new Date(n.getInfo().getTimestamp()));
     92                Map<String, String> keys = new HashMap<String, String>();
     93                for (int i=0; i<n.getKeysCount(); i++) {
     94                    keys.put(getStringById(n.getKeys(i)), getStringById(n.getVals(i)));
     95                }
     96                node.setKeys(keys);
     97                externalIdMap.put(node.getPrimitiveId(), node);
     98            }
     99        }
     100       
     101        @Override
     102        protected void parseWays(List<Osmformat.Way> osmWays) {
     103            for (Osmformat.Way w : osmWays) {
     104                Way way = new Way(w.getId(), w.getInfo().getVersion());
     105                way.setChangesetId(w.getInfo().getChangeset());
     106                way.setUser(User.createOsmUser(w.getInfo().getUid(), getStringById(w.getInfo().getUserSid())));
     107                way.setTimestamp(new Date(w.getInfo().getTimestamp()));
     108                Map<String, String> keys = new HashMap<String, String>();
     109                for (int i=0; i<w.getKeysCount(); i++) {
     110                    keys.put(getStringById(w.getKeys(i)), getStringById(w.getVals(i)));
     111                }
     112                way.setKeys(keys);
     113                long previousId = 0; // Node ids are delta coded
     114                Collection<Long> nodeIds = new ArrayList<Long>();
     115                for (Long id : w.getRefsList()) {
     116                    nodeIds.add(previousId+=id);
     117                }
     118                ways.put(way.getUniqueId(), nodeIds);
     119                externalIdMap.put(way.getPrimitiveId(), way);
     120            }
     121        }
     122       
     123        @Override
     124        protected void parseRelations(List<Osmformat.Relation> osmRels) {
     125            for (Osmformat.Relation r : osmRels) {
     126                Relation rel = new Relation(r.getId(), r.getInfo().getVersion());
     127                rel.setChangesetId(r.getInfo().getChangeset());
     128                rel.setUser(User.createOsmUser(r.getInfo().getUid(), getStringById(r.getInfo().getUserSid())));
     129                rel.setTimestamp(new Date(r.getInfo().getTimestamp()));
     130                Map<String, String> keys = new HashMap<String, String>();
     131                for (int i=0; i<r.getKeysCount(); i++) {
     132                    keys.put(getStringById(r.getKeys(i)), getStringById(r.getVals(i)));
     133                }
     134                rel.setKeys(keys);
     135                long previousId = 0; // Member ids are delta coded
     136                Collection<RelationMemberData> members = new ArrayList<RelationMemberData>();
     137                for (int i = 0; i<r.getMemidsCount(); i++) {
     138                    RelationMemberData rmd = new RelationMemberData();
     139                    rmd.id = previousId+=r.getMemids(i);
     140                    rmd.role = getStringById(r.getRolesSid(i));
     141                    switch (r.getTypes(i)) {
     142                        case NODE:
     143                            rmd.type = OsmPrimitiveType.NODE;
     144                            break;
     145                        case WAY:
     146                            rmd.type = OsmPrimitiveType.WAY;
     147                            break;
     148                        case RELATION:
     149                            rmd.type = OsmPrimitiveType.RELATION;
     150                            break;
     151                    }
     152                    members.add(rmd);
     153                }
     154                relations.put(rel.getUniqueId(), members);
     155                externalIdMap.put(rel.getPrimitiveId(), rel);
     156            }
     157        }
     158
     159        @Override
     160        public void complete() {
     161        }
     162    }
     163
     164    private PbfParser parser = new PbfParser();
     165   
     166    /**
     167     * Parse the given input source and return the dataset.
     168     *
     169     * @param source the source input stream. Must not be null.
     170     * @param progressMonitor  the progress monitor. If null, {@see NullProgressMonitor#INSTANCE} is assumed
     171     *
     172     * @return the dataset with the parsed data
     173     * @throws IllegalDataException thrown if the an error was found while parsing the data from the source
     174     * @throws IllegalArgumentException thrown if source is null
     175     */
     176    public static DataSet parseDataSet(InputStream source, ProgressMonitor progressMonitor) throws IllegalDataException {
     177        if (progressMonitor == null) {
     178            progressMonitor = NullProgressMonitor.INSTANCE;
     179        }
     180        CheckParameterUtil.ensureParameterNotNull(source, "source");
     181
     182        PbfReader reader = new PbfReader();
     183       
     184        try {
     185            progressMonitor.beginTask(tr("Prepare OSM data...", 2));
     186            progressMonitor.indeterminateSubTask(tr("Reading OSM data..."));
     187
     188            reader.parse(source);
     189            progressMonitor.worked(1);
     190
     191            progressMonitor.indeterminateSubTask(tr("Preparing data set..."));
     192            reader.prepareDataSet();
     193            progressMonitor.worked(1);
     194            return reader.getDataSet();
     195        } catch (IllegalDataException e) {
     196            throw e;
     197        } catch (Exception e) {
     198            throw new IllegalDataException(e);
     199        } finally {
     200            progressMonitor.finishTask();
     201        }
     202    }
     203
     204    public void parse(InputStream source) throws IOException {
     205        new BlockInputStream(source, parser).process();
     206    }
     207}