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.LatLon;
010
011/**
012 * This is a projecting instance that shifts the projection by a given eastnorth offset.
013 * @author Michael Zangl
014 * @since 10805
015 */
016public class ShiftedProjecting implements Projecting {
017    private final Projecting base;
018    private final EastNorth offset;
019
020    /**
021     * Create a new {@link ShiftedProjecting}
022     * @param base The base to use
023     * @param offset The offset to move base. Subtracted when converting lat/lon->east/north.
024     */
025    public ShiftedProjecting(Projecting base, EastNorth offset) {
026        this.base = base;
027        this.offset = offset;
028    }
029
030    @Override
031    public EastNorth latlon2eastNorth(LatLon ll) {
032        return base.latlon2eastNorth(ll).add(offset);
033    }
034
035    @Override
036    public LatLon eastNorth2latlonClamped(EastNorth en) {
037        return base.eastNorth2latlonClamped(en.subtract(offset));
038    }
039
040    @Override
041    public Projection getBaseProjection() {
042        return base.getBaseProjection();
043    }
044
045    @Override
046    public Map<ProjectionBounds, Projecting> getProjectingsForArea(ProjectionBounds area) {
047        Map<ProjectionBounds, Projecting> forArea = base
048                .getProjectingsForArea(new ProjectionBounds(area.getMin().subtract(offset), area.getMax().subtract(offset)));
049        HashMap<ProjectionBounds, Projecting> ret = new HashMap<>();
050        forArea.forEach((pb, projecting) -> ret.put(
051                new ProjectionBounds(pb.getMin().add(offset), pb.getMax().add(offset)),
052                new ShiftedProjecting(projecting, offset)));
053        return ret;
054    }
055}