summaryrefslogtreecommitdiff
path: root/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/Function.java
blob: 900fe10476b0c01be8a2b4de4c05c6a21c507cce (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
package com.mapbox.mapboxsdk.style.layers;

import android.support.annotation.FloatRange;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.Size;

import java.util.HashMap;
import java.util.Map;

/**
 * Functions are used to change properties in relation to the state of the map.
 * <p>
 * Currently, only zoom functions are supported.
 * </p>
 *
 * @param <T> the target property's value type. Make sure it matches.
 * @see <a href="https://www.mapbox.com/mapbox-gl-style-spec/#types-function">The online documentation</a>
 */
public class Function<T> {

  /**
   * A stop represents a certain point in the range of this function
   *
   * @param <I> input
   * @param <O> output
   */
  public static class Stop<I, O> {
    public final I in;
    public final O out;

    Stop(I in, O out) {
      this.in = in;
      this.out = out;
    }

    /**
     * @return an array representation of the Stop
     */
    Object[] toValueObject() {
      return new Object[] {in, out};
    }

    @Override
    public String toString() {
      return String.format("[%s, %s]", in, out);
    }
  }

  /**
   * Zoom functions allow the appearance of a map feature to change with map’s zoom.
   * Zoom functions can be used to create the illusion of depth and control data density.
   * Each stop is an array with two elements, the first is a zoom and the second is a function output value.
   *
   * @param stops the stops that define the function
   * @param <T>   the property type
   * @return the {@link Function}
   */
  @SafeVarargs
  public static <T> Function<T> zoom(@NonNull @Size(min = 1) Stop<Float, T>... stops) {
    return new Function<T>(stops);
  }


  /**
   * Zoom functions allow the appearance of a map feature to change with map’s zoom.
   * Zoom functions can be used to create the illusion of depth and control data density.
   * Each stop is an array with two elements, the first is a zoom and the second is a function output value.
   *
   * @param stops the stops that define the function
   * @param base  the exponential base of the interpolation curve - Default 1
   * @param <T>   the property type
   * @return the {@link Function}
   */
  @SafeVarargs
  public static <T> Function<T> zoom(
    @FloatRange(from = 0, to = 1, fromInclusive = false, toInclusive = false) float base,
    @NonNull @Size(min = 1) Stop<Float, T>... stops) {
    return new Function<T>(stops)
      .withBase(base);
  }

  /**
   * Creates a stop to use in a {@link Function}
   *
   * @param in     the input for the stop
   * @param output the output for the stop
   * @param <T>    the output property type
   * @return the {@link Stop}
   */
  public static <T> Stop<Float, T> stop(float in, Property<T> output) {
    return new Stop<>(in, output.value);
  }

  private final Stop<Float, T>[] stops;
  private Float base;

  Function(@NonNull @Size(min = 1) Stop<Float, T>[] stops) {
    this.stops = stops;
  }

  Function<T> withBase(float base) {
    this.base = base;
    return this;
  }

  /**
   * @return the base
   */
  @Nullable
  public Float getBase() {
    return base;
  }

  /**
   * @return the stops in this function
   */
  public Stop<Float, T>[] getStops() {
    return stops;
  }

  Map<String, Object> toValueObject() {
    Object[] stopsValue = new Object[stops.length];

    for (int i = 0; i < stopsValue.length; i++) {
      Stop stop = stops[i];
      stopsValue[i] = stop.toValueObject();
    }

    Map<String, Object> value = new HashMap<>();
    if (base != null) {
      value.put("base", base);
    }
    value.put("stops", stopsValue);
    return value;
  }
}