summaryrefslogtreecommitdiff
path: root/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/functions/Function.java
blob: e7bb52ebb3822d8077e8feb3ce1dd71c74cc4f6b (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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
package com.mapbox.mapboxsdk.style.functions;

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

import com.mapbox.mapboxsdk.style.functions.stops.CategoricalStops;
import com.mapbox.mapboxsdk.style.functions.stops.ExponentialStops;
import com.mapbox.mapboxsdk.style.functions.stops.IdentityStops;
import com.mapbox.mapboxsdk.style.functions.stops.IntervalStops;
import com.mapbox.mapboxsdk.style.functions.stops.Stop;
import com.mapbox.mapboxsdk.style.functions.stops.Stops;

import java.util.Map;

import timber.log.Timber;

/**
 * Functions are used to change properties in relation to the state of the map.
 * <p>
 * The value for any layout or paint property may be specified as a function. Functions allow you to
 * make the appearance of a map feature change with the current zoom level and/or the feature's properties.
 *
 * @param <I> the function's input type
 * @param <O> the target property's value type. Make sure it matches.
 * @see <a href="https://www.mapbox.com/mapbox-gl-style-spec/#types-function">The style specification</a>
 */
public class Function<I, O> {

  static final String PROPERTY_KEY = "property";
  static final String DEFAULT_VALUE_KEY = "default";

  /**
   * Create an exponential {@link CameraFunction}
   * <p>
   * 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 <Z>   the zoom level type (Float, Integer)
   * @param <O>   the property type
   * @param stops the stops implementation that define the function. @see {@link Stops#exponential(Stop[])}
   * @return the {@link CameraFunction}
   * @see CameraFunction
   * @see ExponentialStops
   * @see Stops#exponential(Stop[])
   * @see Stops#exponential(Stop[])
   * @see Stop#stop
   */
  public static <Z extends Number, O> CameraFunction<Z, O> zoom(@NonNull ExponentialStops<Z, O> stops) {
    return new CameraFunction<>(stops);
  }

  /**
   * Create an interval {@link CameraFunction}
   * <p>
   * 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 <Z>   the zoom level type (Float, Integer)
   * @param <O>   the property type
   * @param stops the stops implementation that define the function. @see {@link Stops#interval(Stop[])}
   * @return the {@link CameraFunction}
   * @see CameraFunction
   * @see IntervalStops
   * @see Stops#interval(Stop[])
   * @see Stop#stop
   */
  public static <Z extends Number, O> CameraFunction<Z, O> zoom(@NonNull IntervalStops<Z, O> stops) {
    return new CameraFunction<>(stops);
  }

  /**
   * Create an exponential {@link SourceFunction}
   * <p>
   * Source functions allow the appearance of a map feature to change with
   * its properties. Source functions can be used to visually differentiate
   * types of features within the same layer or create data visualizations.
   * Each stop is an array with two elements, the first is a property input
   * value and the second is a function output value. Note that support for
   * property functions is not available across all properties and platforms
   * at this time.
   *
   * @param property the feature property name
   * @param stops    the stops
   * @param <I>      the function input type
   * @param <O>      the function output type
   * @return the {@link SourceFunction}
   * @see SourceFunction
   * @see ExponentialStops
   * @see Stops#exponential(Stop[])
   * @see Stop#stop
   */
  public static <I, O> SourceFunction<I, O> property(@NonNull String property, @NonNull ExponentialStops<I, O> stops) {
    return new SourceFunction<>(property, stops);
  }

  /**
   * Create an identity {@link SourceFunction}
   * <p>
   * Source functions allow the appearance of a map feature to change with
   * its properties. Source functions can be used to visually differentiate
   * types of features within the same layer or create data visualizations.
   * Each stop is an array with two elements, the first is a property input
   * value and the second is a function output value. Note that support for
   * property functions is not available across all properties and platforms
   * at this time.
   *
   * @param property the feature property name
   * @param stops    the stops
   * @param <T>      the function input/output type
   * @return the {@link SourceFunction}
   * @see SourceFunction
   * @see IdentityStops
   * @see Stops#identity()
   * @see Stop#stop
   */
  public static <T> SourceFunction<T, T> property(@NonNull String property, @NonNull IdentityStops<T> stops) {
    return new SourceFunction<>(property, stops);
  }

  /**
   * Create an interval {@link SourceFunction}
   * <p>
   * Source functions allow the appearance of a map feature to change with
   * its properties. Source functions can be used to visually differentiate
   * types of features within the same layer or create data visualizations.
   * Each stop is an array with two elements, the first is a property input
   * value and the second is a function output value. Note that support for
   * property functions is not available across all properties and platforms
   * at this time.
   *
   * @param property the feature property name
   * @param stops    the stops
   * @param <I>      the function input type
   * @param <O>      the function output type
   * @return the {@link SourceFunction}
   * @see SourceFunction
   * @see IntervalStops
   * @see Stops#interval(Stop[])
   * @see Stop#stop
   */
  public static <I, O> SourceFunction<I, O> property(@NonNull String property, @NonNull IntervalStops<I, O> stops) {
    return new SourceFunction<>(property, stops);
  }

  /**
   * Create an categorical {@link SourceFunction}
   * <p>
   * Source functions allow the appearance of a map feature to change with
   * its properties. Source functions can be used to visually differentiate
   * types of features within the same layer or create data visualizations.
   * Each stop is an array with two elements, the first is a property input
   * value and the second is a function output value. Note that support for
   * property functions is not available across all properties and platforms
   * at this time.
   *
   * @param property the feature property name
   * @param stops    the stops
   * @param <I>      the function input type
   * @param <O>      the function output type
   * @return the {@link SourceFunction}
   * @see SourceFunction
   * @see CategoricalStops
   * @see Stops#categorical(Stop[])
   * @see Stop#stop
   */
  public static <I, O> SourceFunction<I, O> property(@NonNull String property, @NonNull CategoricalStops<I, O> stops) {
    return new SourceFunction<>(property, stops);
  }

  /**
   * Create a composite, categorical function.
   * <p>
   * Composite functions allow the appearance of a map feature to change with both its
   * properties and zoom. Each stop is an array with two elements, the first is an object
   * with a property input value and a zoom, and the second is a function output value. Note
   * that support for property functions is not yet complete.
   *
   * @param property the feature property name for the source part of the function
   * @param stops    the stops
   * @param <Z>      the zoom function input type (Float usually)
   * @param <I>      the function input type for the source part of the function
   * @param <O>      the function output type
   * @return the {@link CompositeFunction}
   * @see CompositeFunction
   * @see CategoricalStops
   * @see Stops#categorical(Stop[])
   * @see Stop#stop
   */
  public static <Z extends Number, I, O> CompositeFunction<Z, I, O> composite(
    @NonNull String property,
    @NonNull CategoricalStops<Stop.CompositeValue<Z, I>, O> stops) {

    return new CompositeFunction<>(property, stops);
  }

  /**
   * Create a composite, exponential function.
   * <p>
   * Composite functions allow the appearance of a map feature to change with both its
   * properties and zoom. Each stop is an array with two elements, the first is an object
   * with a property input value and a zoom, and the second is a function output value. Note
   * that support for property functions is not yet complete.
   *
   * @param property the feature property name for the source part of the function
   * @param stops    the stops
   * @param <Z>      the zoom function input type (Float usually)
   * @param <I>      the function input type for the source part of the function
   * @param <O>      the function output type
   * @return the {@link CompositeFunction}
   * @see CompositeFunction
   * @see ExponentialStops
   * @see Stops#exponential(Stop[])
   * @see Stop#stop
   */
  public static <Z extends Number, I, O> CompositeFunction<Z, I, O> composite(
    @NonNull String property,
    @NonNull ExponentialStops<Stop.CompositeValue<Z, I>, O> stops) {

    return new CompositeFunction<>(property, stops);
  }

  /**
   * Create a composite, interval function.
   * <p>
   * Composite functions allow the appearance of a map feature to change with both its
   * properties and zoom. Each stop is an array with two elements, the first is an object
   * with a property input value and a zoom, and the second is a function output value. Note
   * that support for property functions is not yet complete.
   *
   * @param property the feature property name for the source part of the function
   * @param stops    the stops
   * @param <Z>      the zoom function input type (Float usually)
   * @param <I>      the function input type for the source part of the function
   * @param <O>      the function output type
   * @return the {@link CompositeFunction}
   * @see CompositeFunction
   * @see IntervalStops
   * @see Stops#interval(Stop[])
   * @see Stop#stop
   */
  public static <Z extends Number, I, O> CompositeFunction<Z, I, O> composite(
    @NonNull String property,
    @NonNull IntervalStops<Stop.CompositeValue<Z, I>, O> stops) {

    return new CompositeFunction<>(property, stops);
  }

  // Class definition //

  private final Stops<I, O> stops;

  /**
   * JNI Cosntructor for implementation classes
   *
   * @param stops the stops
   */
  Function(@NonNull Stops<I, O> stops) {
    this.stops = stops;
  }

  /**
   * @return the stops in this function
   */
  public Stops getStops() {
    return stops;
  }

  /**
   * Convenience method
   *
   * @param <S> the Stops implementation type
   * @return the Stops implementation or null when the wrong type is specified
   */
  @Nullable
  public <S extends Stops> S getStopsAs() {
    try {
      // noinspection unchecked
      return (S) stops;
    } catch (ClassCastException exception) {
      Timber.e(exception, "Stops: %s is a different type: ", stops.getClass());
      return null;
    }
  }

  /**
   * INTERNAL USAGE ONLY
   *
   * @return a value object representation for core conversion
   */
  public Map<String, Object> toValueObject() {
    return stops.toValueObject();
  }

  @Override
  public String toString() {
    return String.format("%s: %s", getClass().getSimpleName(), stops);
  }
}