Package de.fhpotsdam.unfolding.ui

Source Code of de.fhpotsdam.unfolding.ui.BarScaleUI

package de.fhpotsdam.unfolding.ui;

import java.util.Arrays;
import java.util.List;

import processing.core.PApplet;
import processing.core.PFont;
import de.fhpotsdam.unfolding.UnfoldingMap;
import de.fhpotsdam.unfolding.geo.Location;
import de.fhpotsdam.unfolding.utils.GeoUtils;
import de.fhpotsdam.unfolding.utils.ScreenPosition;

public class BarScaleUI {
  private static final List<Float> DISPLAY_DISTANCES = Arrays.asList(
      0.01f, 0.02f, 0.05f, 0.1f, 0.2f, 0.5f, 1f, 2f,
      5f, 10f, 20f, 50f, 100f, 200f, 500f, 1000f, 2000f, 5000f);

  private static final float MAX_DISPLAY_DISTANCE = 5000;

  private boolean autoAlignment = true;

  // If false it uses the screen center, resulting in a bar scale depending on
  // the north/south position of the map.
  boolean showDistanceAtEquator = false;

  private PApplet p;
  private UnfoldingMap map;
  public float x;
  public float y;

  // style:
  private int color;
  private int barWeight;
  private int barCapOffset;

  public BarScaleUI(PApplet p, UnfoldingMap map, float x, float y) {
    this.p = p;
    this.map = map;
    this.x = x;
    this.y = y;

    barWeight = 1;
    barCapOffset = 0;
    p.color(255);
    p.textFont(p.createFont("Sans-Serif", 10));
  }

  public BarScaleUI(PApplet p, UnfoldingMap map) {
    this(p, map, 20, map.mapDisplay.getHeight() - 20);
  }

  /**
   * Draws a bar scale at given position according to current zoom level.
   *
   * Calculates distance at equator (scale is dependent on Latitude). Uses a
   * distance to display from fixed set of distance numbers, so length of bar
   * may vary.
   */
  public void draw() {
    // Distance in km, appropriate to current zoom
    float distance = MAX_DISPLAY_DISTANCE / map.getZoom();
    distance = getClosestDistance(distance);

    Location startLocation = null;
    Location destLocation = null;
    if (showDistanceAtEquator) {
      // Get destLocation (world center, on equator, with calculated distance)
      startLocation = new Location(0, 0);
      destLocation = GeoUtils.getDestinationLocation(startLocation, 90f, distance);
    } else {
      startLocation = map.getLocation(p.width / 2, p.height / 2);
      destLocation = GeoUtils.getDestinationLocation(startLocation, 90f, distance);
    }
    // Calculate distance between both locations in screen coordinates
    ScreenPosition destPos = map.getScreenPosition(destLocation);
    ScreenPosition startPos = map.getScreenPosition(startLocation);
    float dx = destPos.x - startPos.x;

    // Display
    p.fill(color);
    if (autoAlignment && x > map.mapDisplay.getWidth() / 2) {
      dx *= -1;
      p.text(PApplet.nfs(distance, 0, 0) + " km", x + 3, y + 4);
    } else {
      p.text(PApplet.nfs(distance, 0, 0) + " km", x + dx + 3, y + 4);
    }
    p.stroke(color);
    p.strokeWeight(barWeight);
    p.line(x - .5f, y, x + .5f + dx, y);
    p.strokeWeight(1);

    int capHeightUp = (barCapOffset == 0) ? 3 : (barCapOffset > 0) ? 0 : -barCapOffset;
    int capHeightDown = (barCapOffset == 0) ? 3 : (barCapOffset < 0) ? 0 : barCapOffset;
    capHeightUp += barWeight / 2;
    capHeightDown += barWeight / 2;

    p.line(x, y - capHeightUp, x, y + capHeightDown);
    p.line(x + dx, y - capHeightUp, x + dx, y + capHeightDown);

  }

  /**
   * Set the style of the bar scale.
   *
   * @param color
   *            the color of the scale.
   * @param barWeight
   *            the weight of the scale.
   * @param barCapOffset
   *            the offset of the scale.
   * @param font
   *            the font to use for the bar scale.
   */
  public void setStyle(int color, int barWeight, int barCapOffset, PFont font) {
    this.color = color;
    this.barWeight = barWeight;
    this.barCapOffset = barCapOffset;
    p.textFont(font);
  }

  /**
   * Returns the nearest distance to display as well as to use for
   * calculation.
   *
   * @param distance
   *            The original distance
   * @return A distance from the set of {@link #DISPLAY_DISTANCES}
   */
  protected float getClosestDistance(float distance) {
    return closest(distance, DISPLAY_DISTANCES);
  }

  protected float closest(float of, List<Float> in) {
    float min = Float.MAX_VALUE;
    float closest = of;

    for (float v : in) {
      final float diff = Math.abs(v - of);

      if (diff < min) {
        min = diff;
        closest = v;
      }
    }
    return closest;
  }
}
TOP

Related Classes of de.fhpotsdam.unfolding.ui.BarScaleUI

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.