001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.data.projection;
003
004import java.util.HashMap;
005import java.util.Map;
006
007import org.openstreetmap.josm.data.ProjectionBounds;
008import org.openstreetmap.josm.data.coor.EastNorth;
009import org.openstreetmap.josm.data.coor.ILatLon;
010import org.openstreetmap.josm.data.coor.LatLon;
011
012/**
013 * This is a projecting instance that shifts the projection by a given eastnorth offset.
014 * @author Michael Zangl
015 * @since 10805
016 */
017public class ShiftedProjecting implements Projecting {
018    private final Projecting base;
019    private final EastNorth offset;
020
021    /**
022     * Create a new {@link ShiftedProjecting}
023     * @param base The base to use
024     * @param offset The offset to move base. Subtracted when converting lat/lon->east/north.
025     */
026    public ShiftedProjecting(Projecting base, EastNorth offset) {
027        this.base = base;
028        this.offset = offset;
029    }
030
031    @Override
032    public EastNorth latlon2eastNorth(ILatLon ll) {
033        return base.latlon2eastNorth(ll).add(offset);
034    }
035
036    @Override
037    public LatLon eastNorth2latlonClamped(EastNorth en) {
038        return base.eastNorth2latlonClamped(en.subtract(offset));
039    }
040
041    @Override
042    public Projection getBaseProjection() {
043        return base.getBaseProjection();
044    }
045
046    @Override
047    public Map<ProjectionBounds, Projecting> getProjectingsForArea(ProjectionBounds area) {
048        Map<ProjectionBounds, Projecting> forArea = base
049                .getProjectingsForArea(new ProjectionBounds(area.getMin().subtract(offset), area.getMax().subtract(offset)));
050        HashMap<ProjectionBounds, Projecting> ret = new HashMap<>();
051        forArea.forEach((pb, projecting) -> ret.put(
052                new ProjectionBounds(pb.getMin().add(offset), pb.getMax().add(offset)),
053                new ShiftedProjecting(projecting, offset)));
054        return ret;
055    }
056}