Package org.mapfish.print.attribute.map

Source Code of org.mapfish.print.attribute.map.Constants

/*
* Copyright (C) 2014  Camptocamp
*
* This file is part of MapFish Print
*
* MapFish Print is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* MapFish Print is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with MapFish Print.  If not, see <http://www.gnu.org/licenses/>.
*/

package org.mapfish.print.attribute.map;

import org.mapfish.print.map.Scale;

/**
* Enumerates the different strategies for finding the closest zoom-level/scale.
*
* @author Jesse on 3/31/14.
*/
public enum ZoomLevelSnapStrategy {
    /**
     * Find the closest zoom level.  If the targetScale is directly between two zoomLevels then the smaller/higher resolution scale
     * will be chosen.
     */
    CLOSEST_LOWER_SCALE_ON_TIE {
        @Override
        protected SearchResult search(final Scale scale, final double tolerance, final ZoomLevels zoomLevels) {
            double targetScale = scale.getDenominator();

            int pos = zoomLevels.size() - 1;
            double distance = Math.abs(zoomLevels.get(pos) - targetScale);

            for (int i = zoomLevels.size() - 2; i >= 0; --i) {
                double cur = zoomLevels.get(i);

                double newDistance = Math.abs(targetScale - cur);
                if (newDistance < distance) {
                    distance = newDistance;
                    pos = i;
                    if (distance < Constants.DISTANCE_TREATED_AS_EQUAL) {
                        break;
                    }
                }
            }
            return new SearchResult(pos, zoomLevels);
        }
    },
    /**
     * Find the closest zoom level.  If the targetScale is directly between two zoomLevels then the larger/lower resolution scale
     * will be chosen.
     */
    CLOSEST_HIGHER_SCALE_ON_TIE {
        @Override
        protected SearchResult search(final Scale scale, final double tolerance, final ZoomLevels zoomLevels) {
            double targetScale = scale.getDenominator();
            int pos = zoomLevels.size() - 1;
            double distance = Math.abs(zoomLevels.get(pos) - targetScale);

            for (int i = 1; i < zoomLevels.size(); i++) {
                double cur = zoomLevels.get(i);

                double newDistance = Math.abs(targetScale - cur);
                if (newDistance < distance) {
                    distance = newDistance;
                    pos = i;
                    if (distance < Constants.DISTANCE_TREATED_AS_EQUAL) {
                        break;
                    }
                }
            }
            return new SearchResult(pos, zoomLevels);
        }
    },
    /**
     * Always choose the zoom-level that is just higher than the target value.
     */
    HIGHER_SCALE {
        @Override
        protected SearchResult search(final Scale scale, final double tolerance, final ZoomLevels zoomLevels) {
            double targetScale = scale.getDenominator();

            int pos = 0;
            for (int i = 1; i < zoomLevels.size(); i++) {
                double cur = zoomLevels.get(i);

                final double cutOff = targetScale * (1 - tolerance);
                if (cur >= cutOff) {
                    pos = i;
                    if (cur == targetScale) {
                        break;
                    }
                }
            }

            return new SearchResult(pos, zoomLevels);
        }
    },
    /**
     * Always choose the zoom-level that is just lower than the target value.
     */
    LOWER_SCALE {
        @Override
        protected SearchResult search(final Scale scale, final double tolerance, final ZoomLevels zoomLevels) {
            double targetScale = scale.getDenominator();

            int pos = zoomLevels.size() - 1;
            for (int i = zoomLevels.size() - 1; i >= 0; --i) {
                double cur = zoomLevels.get(i);

                if (cur <= targetScale * (1 + tolerance)) {
                    pos = i;
                    if (cur == targetScale) {
                        break;
                    }
                }
            }

            return new SearchResult(pos, zoomLevels);
        }
    };

    /**
     * Search the provided zoomLevels for the scale that is the closest according to the current strategy.
     *
     * @param targetScale the reference scale
     * @param tolerance    the amount from one of the zoomLevels to still be considered <em>at</em> the scale.
     *                     This is important for all strategies other than CLOSEST in order to prevent the scale from jumping
     *                     to a different version even when it is very close to one of the zoomLevels.
     * @param zoomLevels   the allowed zoomLevels
     */
    protected abstract SearchResult search(Scale targetScale, double tolerance, ZoomLevels zoomLevels);

    /**
     * The results of a search.
     */
    public static final class SearchResult {
        private final int zoomLevel;
        private final ZoomLevels zoomLevels;

        SearchResult(final int zoomLevel, final ZoomLevels zoomLevels) {
            this.zoomLevel = zoomLevel;
            this.zoomLevels = zoomLevels;
        }

        public int getZoomLevel() {
            return this.zoomLevel;
        }

        public ZoomLevels getZoomLevels() {
            return this.zoomLevels;
        }

        public Scale getScale() {
            return new Scale(this.zoomLevels.get(this.zoomLevel));
        }

        // CHECKSTYLE:OFF

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;

            SearchResult that = (SearchResult) o;

            if (zoomLevel != that.zoomLevel) return false;
            if (!zoomLevels.equals(that.zoomLevels)) return false;

            return true;
        }

        @Override
        public int hashCode() {
            int result = zoomLevel;
            result = 31 * result + zoomLevels.hashCode();
            return result;
        }

        @Override
        public String toString() {
            return "SearchResult{" +
                   "zoomLevel=" + zoomLevel +
                   ", scale=" + zoomLevels.get(zoomLevel) +
                   ", zoomLevels=" + zoomLevels +
                   '}';
        }

// CHECKSTYLE:ON

    }

    private static class Constants {
        private static final double DISTANCE_TREATED_AS_EQUAL = 0.00000000001;
    }
}
TOP

Related Classes of org.mapfish.print.attribute.map.Constants

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.