summaryrefslogtreecommitdiff
path: root/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/CustomVectorSource.java
blob: 11ed3111b7633bb8cd95627da0a4843608e23a5d (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
package com.mapbox.mapboxsdk.style.sources;

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

import com.mapbox.mapboxsdk.geometry.LatLngBounds;
import com.mapbox.mapboxsdk.style.layers.Filter;
import com.mapbox.services.commons.geojson.Feature;
import com.mapbox.services.commons.geojson.FeatureCollection;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

class TileID {
  public int z;
  public int x;
  public int y;
  public TileID(int _z, int _x, int _y) {
    z = _z;
    x = _x;
    y = _y;
  }
}

class TileRequest implements Runnable {
  private TileID id;
  private TileProvider provider;
  private WeakReference<CustomVectorSource> sourceRef;
  public TileRequest(TileID _id, TileProvider p, CustomVectorSource _source) {
    id = _id;
    provider = p;
    sourceRef = new WeakReference<>(_source);
  }

  public void run() {
    FeatureCollection data = provider.getFeaturesForBounds(LatLngBounds.from(id.z, id.x, id.y), id.z);
    CustomVectorSource source = sourceRef.get();
    if(source != null) {
      source.setTileData(id, data);
    }
  }
}

/**
 * Custom Vector Source, allows using FeatureCollections.
 *
 */
@UiThread
public class CustomVectorSource extends Source {
  private BlockingQueue requestQueue;
  private ThreadPoolExecutor executor;
  private TileProvider provider;

  /**
   * Internal use
   *
   * @param nativePtr - pointer to native peer
   */
  public CustomVectorSource(long nativePtr) {
    super(nativePtr);
  }

  /**
   * Create a CustomVectorSource
   *
   * @param id the source id
   */
  public CustomVectorSource(String id, TileProvider provider_) {
    requestQueue = new ArrayBlockingQueue(80);
    executor = new ThreadPoolExecutor(10, 10, 60, TimeUnit.SECONDS, requestQueue);

    provider = provider_;
    initialize(this, id, new GeoJsonOptions());
  }

  /**
   * Create a CustomVectorSource with non-default GeoJsonOptions.
   *
   * @param id      the source id
   * @param options options
   */
  public CustomVectorSource(String id, TileProvider provider_, GeoJsonOptions options) {
    provider = provider_;
    initialize(this, id, options);
  }

  public void setTileData(TileID tileId, FeatureCollection data) {
    setTileData(tileId.z, tileId.x, tileId.y, data);
  }

  /**
   * Queries the source for features.
   *
   * @param filter an optional filter statement to filter the returned Features
   * @return the features
   */
  @NonNull
  public List<Feature> querySourceFeatures(@Nullable Filter.Statement filter) {
    Feature[] features = querySourceFeatures(filter != null ? filter.toArray() : null);
    return features != null ? Arrays.asList(features) : new ArrayList<Feature>();
  }

  protected native void initialize(CustomVectorSource self, String sourceId, Object options);

  private native Feature[] querySourceFeatures(Object[] filter);

  private native void setTileData(int z, int x, int y, FeatureCollection data);

  @WorkerThread
  public void fetchTile(int z, int x, int y) {
    TileRequest request = new TileRequest(new TileID(z, x, y), provider, this);
    long active = executor.getActiveCount();
    long complete = executor.getCompletedTaskCount();
    executor.execute(request);
//    setTileData(z, x, y, data);
    System.out.println("Active=" + active);
    System.out.println("Completed=" + complete);
  }

  @WorkerThread
  public void cancelTile(int z, int x, int y) {
  }

  @Override
  protected native void finalize() throws Throwable;
}