Skip to content

Commit a9e536d

Browse files
committed
feat: cluster support for reporting cluster bbox
1 parent 5e36f77 commit a9e536d

File tree

8 files changed

+147
-263
lines changed

8 files changed

+147
-263
lines changed

plugin/platforms/android/java/com/akylas/carto/additions/AKClusterElementBuilder.java

Lines changed: 52 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@
99
import android.util.Log;
1010

1111
// import com.carto.layers.VectorLayer;
12+
import com.carto.core.VariantArrayBuilder;
1213
import com.carto.core.MapPos;
14+
import com.carto.core.MapBounds;
1315
import com.carto.vectorelements.VectorElement;
1416
import com.carto.vectorelements.VectorElementVector;
1517
import com.carto.layers.ClusterElementBuilder;
@@ -19,12 +21,16 @@
1921
import com.carto.styles.PointStyle;
2022
import com.carto.vectorelements.Marker;
2123
import com.carto.vectorelements.Point;
24+
import com.carto.vectorelements.VectorElement;
2225
import com.carto.utils.BitmapUtils;
2326
import com.carto.styles.StyleBuilder;
2427
import com.carto.styles.PointStyleBuilder;
2528
import com.carto.styles.MarkerStyleBuilder;
2629
import com.carto.graphics.Bitmap;
2730
import android.graphics.Typeface;
31+
import com.carto.geometry.PointGeometryVector;
32+
import com.carto.geometry.PointGeometry;
33+
import com.carto.geometry.MultiPointGeometry;
2834

2935
import java.util.HashMap;
3036
import java.util.Map;
@@ -48,6 +54,7 @@ public void setInterface(Interface inter) {
4854
private com.carto.graphics.Color textColor = null;
4955
private int markerSize = 20;
5056
private float textSize = 12;
57+
private boolean setBbox = false;
5158
private Typeface typeface = null;
5259

5360
private String shape = "marker";
@@ -81,6 +88,9 @@ public void setTextSize(float value) {
8188
public void setTextColor(com.carto.graphics.Color value) {
8289
textColor = value;
8390
}
91+
public void setBbox(boolean value) {
92+
setBbox = value;
93+
}
8494

8595
@Override
8696
public VectorElement buildClusterElement(final MapPos pos, final VectorElementVector elements) {
@@ -96,7 +106,6 @@ public VectorElement buildClusterElement(final MapPos pos, final VectorElementVe
96106
SynchronousHandler.postAndWait(mainHandler, new Runnable() {
97107
@Override
98108
public void run() {
99-
// Log.d("AKCartoAdditions", "buildClusterElement runnable");
100109
if (inter != null) {
101110
arr[0] = inter.buildClusterElement(pos, elements);
102111
} else {
@@ -112,64 +121,31 @@ public void run() {
112121
return super.buildClusterElement(pos, elements);
113122
}
114123
}
115-
// Log.d("AKCartoAdditions", "buildClusterElement4: done");
116-
// Runnable r = new Runnable() {
117-
// @Override
118-
// public void run() {
119-
// Log.d("AKCartoAdditions", "buildClusterElement runnable1 " );
120-
// synchronized (this) {
121-
// try {
122-
// Log.d("AKCartoAdditions", "buildClusterElement runnable2 " );
123-
// arr[0] = AKClusterElementBuilder.this.buildCluster(pos, nElements);
124-
// } catch (Exception e) {
125-
// // if (discardUncaughtJsExceptions) {
126-
// Log.e("AKCartoAdditions", "Error off currentThread for callJSMethodNative: "
127-
// + e.getMessage());
128-
// e.printStackTrace();
129-
// // } else {
130-
// throw e;
131-
// // }
132-
// } finally {
133-
// Log.d("AKCartoAdditions", "buildClusterElement runnable done " );
134-
// arr[1] = Boolean.TRUE;
135-
// this.notify();
136-
// }
137-
// }
138-
// }
139-
// };
140-
// boolean success = mainHandler.post(r);
141-
// Log.d("AKCartoAdditions", "buildClusterElement2: " + (success ? "1" : "0"));
142-
143-
// if (success) {
144-
// synchronized (r) {
145-
// try {
146-
// if (arr[1] == null) {
147-
// Log.d("AKCartoAdditions", "buildClusterElement3: waiting");
148-
// r.wait();
149-
// }
150-
// } catch (InterruptedException e) {
151-
// Log.e("AKCartoAdditions", "InterruptedException: " + e.getMessage());
152-
// }
153-
// }
154-
// }
155-
// Log.d("AKCartoAdditions", "buildClusterElement4: done");
156-
157124
}
158125

159126
public VectorElement nativeBuildClusterElement(MapPos pos, VectorElementVector elements) {
160127

161128
// Try to reuse existing marker styles
162-
Style style = markerStyles.get((int) elements.size());
163-
164-
if (elements.size() == 1) {
165-
style = ((Marker) elements.get(0)).getStyle();
129+
int nbElements = (int) elements.size();
130+
Style style = markerStyles.get(nbElements);
131+
if (nbElements == 1) {
132+
if (elements.get(0) instanceof Marker) {
133+
style = ((Marker) elements.get(0)).getStyle();
134+
} else if (elements.get(0) instanceof Point) {
135+
style = ((Point) elements.get(0)).getStyle();
136+
}
166137
}
167138

168139
if (style == null) {
169140
StyleBuilder styleBuilder = null;
170141
Bitmap cBitmap = null;
171-
if (markerBitmap != null) {
172-
android.graphics.Bitmap canvasBitmap = markerBitmap.copy(android.graphics.Bitmap.Config.ARGB_8888, true);
142+
if (markerBitmap != null || textColor != null) {
143+
android.graphics.Bitmap canvasBitmap;
144+
if (markerBitmap != null) {
145+
canvasBitmap = markerBitmap.copy(android.graphics.Bitmap.Config.ARGB_8888, true);
146+
} else {
147+
canvasBitmap = android.graphics.Bitmap.createBitmap(markerSize, markerSize, android.graphics.Bitmap.Config.ARGB_8888);
148+
}
173149
android.graphics.Canvas canvas = new android.graphics.Canvas(canvasBitmap);
174150

175151
Paint paint = AKClusterElementBuilder.paint;
@@ -180,7 +156,7 @@ public VectorElement nativeBuildClusterElement(MapPos pos, VectorElementVector e
180156
paint.setTypeface(typeface);
181157
}
182158
Typeface typeface = paint.getTypeface();
183-
String text = Integer.toString((int) elements.size());
159+
String text = Integer.toString(nbElements);
184160
Rect bounds = AKClusterElementBuilder.tempRect;
185161
paint.getTextBounds(text, 0, text.length(), bounds);
186162

@@ -190,8 +166,8 @@ public VectorElement nativeBuildClusterElement(MapPos pos, VectorElementVector e
190166
paint.setColor(Color.WHITE);
191167
}
192168

193-
float x = markerBitmap.getWidth() / 2;
194-
float y = markerBitmap.getHeight() / 2 + bounds.height()/2;
169+
float x = canvasBitmap.getWidth() / 2;
170+
float y = canvasBitmap.getHeight() / 2 + bounds.height()/2;
195171

196172
canvas.drawText(text, x, y, paint);
197173
cBitmap = BitmapUtils.createBitmapFromAndroidBitmap(canvasBitmap);
@@ -205,7 +181,7 @@ public VectorElement nativeBuildClusterElement(MapPos pos, VectorElementVector e
205181
} else {
206182
styleBuilder = new MarkerStyleBuilder();
207183
((MarkerStyleBuilder)styleBuilder).setSize(markerSize);
208-
((MarkerStyleBuilder)styleBuilder).setPlacementPriority((int) elements.size());
184+
((MarkerStyleBuilder)styleBuilder).setPlacementPriority(nbElements);
209185
if (cBitmap != null) {
210186
((MarkerStyleBuilder)styleBuilder).setBitmap(cBitmap);
211187

@@ -221,16 +197,35 @@ public VectorElement nativeBuildClusterElement(MapPos pos, VectorElementVector e
221197
} else if (styleBuilder instanceof MarkerStyleBuilder) {
222198
style = ((MarkerStyleBuilder)styleBuilder).buildStyle();
223199
}
224-
markerStyles.put((int) elements.size(), style);
200+
markerStyles.put(nbElements, style);
225201
}
226202

227203
// Create marker for the cluster
204+
VectorElement marker = null;
228205
if (style instanceof PointStyle) {
229-
return new Point(pos, (PointStyle)style);
206+
marker = new Point(pos, (PointStyle)style);
230207
}
231208
if (style instanceof MarkerStyle) {
232-
return new Marker(pos, (MarkerStyle)style);
209+
marker = new Marker(pos, (MarkerStyle)style);
210+
}
211+
if (marker != null) {
212+
marker.setMetaDataElement("elements", new com.carto.core.Variant((long)nbElements));
213+
if (setBbox) {
214+
PointGeometryVector vector = new PointGeometryVector();
215+
for (int i = 0; i<nbElements; i++) {
216+
vector.add((PointGeometry)elements.get(i).getGeometry());
217+
}
218+
MapBounds mapBounds = new MultiPointGeometry(vector).getBounds();
219+
VariantArrayBuilder builder = new VariantArrayBuilder();
220+
builder.addDouble(mapBounds.getMin().getX());
221+
builder.addDouble(mapBounds.getMin().getY());
222+
builder.addDouble(mapBounds.getMax().getX());
223+
builder.addDouble(mapBounds.getMax().getY());
224+
marker.setMetaDataElement("bbox", builder.buildVariant());
225+
}
226+
233227
}
234-
return null;
228+
229+
return marker;
235230
}
236231
}

plugin/platforms/ios/src/AkClusterElementBuilder.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@
88
- (void) setTextSize: (NSUInteger)value;
99
- (void) setShape: (NSString *)value;
1010
- (void) setFont: (UIFont *)value;
11-
11+
- (void) setBbox: (BOOL)value;
1212

1313
@end

0 commit comments

Comments
 (0)