Skip to content

Commit 5a01e93

Browse files
committed
fix: fully working clusters
# Conflicts: # src/index.common.ts # src/index.ios.ts
1 parent 1d32b5e commit 5a01e93

File tree

13 files changed

+229
-44
lines changed

13 files changed

+229
-44
lines changed

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

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import android.graphics.BitmapFactory;
66
import android.graphics.Paint;
77
import android.graphics.Color;
8+
import android.graphics.Rect;
89
import android.util.Log;
910

1011
// import com.carto.layers.VectorLayer;
@@ -23,12 +24,14 @@
2324
import com.carto.styles.PointStyleBuilder;
2425
import com.carto.styles.MarkerStyleBuilder;
2526
import com.carto.graphics.Bitmap;
27+
import android.graphics.Typeface;
2628

2729
import java.util.HashMap;
2830
import java.util.Map;
2931

3032
public class AKClusterElementBuilder extends ClusterElementBuilder {
31-
33+
static final Rect tempRect = new Rect();
34+
static final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
3235
public interface Interface {
3336
VectorElement buildClusterElement(MapPos pos, VectorElementVector nElements);
3437
}
@@ -45,6 +48,7 @@ public void setInterface(Interface inter) {
4548
private com.carto.graphics.Color textColor = null;
4649
private int markerSize = 20;
4750
private float textSize = 12;
51+
private Typeface typeface = null;
4852

4953
private String shape = "marker";
5054
private final String TAG = "AKClusterElementBuilder";
@@ -68,10 +72,13 @@ public void setShape(String value) {
6872
shape = value;
6973
}
7074

75+
public void setFont(Typeface value) {
76+
typeface = value;
77+
}
7178
public void setTextSize(float value) {
7279
textSize = value;
7380
}
74-
public void setTextColor(Color value) {
81+
public void setTextColor(com.carto.graphics.Color value) {
7582
textColor = value;
7683
}
7784

@@ -165,20 +172,28 @@ public VectorElement nativeBuildClusterElement(MapPos pos, VectorElementVector e
165172
android.graphics.Bitmap canvasBitmap = markerBitmap.copy(android.graphics.Bitmap.Config.ARGB_8888, true);
166173
android.graphics.Canvas canvas = new android.graphics.Canvas(canvasBitmap);
167174

168-
android.graphics.Paint paint = new android.graphics.Paint(android.graphics.Paint.ANTI_ALIAS_FLAG);
175+
Paint paint = AKClusterElementBuilder.paint;
169176

170177
paint.setTextAlign(Paint.Align.CENTER);
171178
paint.setTextSize(textSize);
179+
if (typeface != null) {
180+
paint.setTypeface(typeface);
181+
}
182+
Typeface typeface = paint.getTypeface();
183+
String text = Integer.toString((int) elements.size());
184+
Rect bounds = AKClusterElementBuilder.tempRect;
185+
paint.getTextBounds(text, 0, text.length(), bounds);
186+
172187
if (textColor != null) {
173188
paint.setColor(textColor.getARGB());
174189
} else {
175190
paint.setColor(Color.WHITE);
176191
}
177192

178193
float x = markerBitmap.getWidth() / 2;
179-
float y = markerBitmap.getHeight() / 2 - textSize/2;
194+
float y = markerBitmap.getHeight() / 2 + bounds.height()/2;
180195

181-
canvas.drawText(Integer.toString((int) elements.size()), x, y, paint);
196+
canvas.drawText(text, x, y, paint);
182197
cBitmap = BitmapUtils.createBitmapFromAndroidBitmap(canvasBitmap);
183198
}
184199
if (shape.equals("point")) {

plugin/platforms/ios/src/AkClusterElementBuilder.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
- (void) setSize: (NSUInteger)value;
88
- (void) setTextSize: (NSUInteger)value;
99
- (void) setShape: (NSString *)value;
10+
- (void) setFont: (UIFont *)value;
1011

1112

1213
@end

plugin/platforms/ios/src/AkClusterElementBuilder.mm

Lines changed: 40 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@ @interface AkClusterElementBuilder ()
55

66
@property NSMutableDictionary* markerStyles;
77
@property (nonatomic) UIImage *markerImage;
8-
@property (nonatomic) UIColor *markerColor;
8+
@property (nonatomic) NTColor *markerColor;
99
@property (nonatomic) UIColor *textColor;
1010
@property (nonatomic) NSUInteger markerSize;
1111
@property (nonatomic) NSUInteger textSize;
1212
@property (nonatomic) NSString* shape;
13+
@property (nonatomic) UIFont* font;
1314

1415
@end
1516
@implementation AkClusterElementBuilder : NTClusterElementBuilder
@@ -25,21 +26,25 @@ -(id)init {
2526
- (void) setBitmap: (UIImage *)value {
2627
self.markerImage = value;
2728
}
28-
- (void) setColor: (UIColor *)value{
29+
- (void) setColor: (NTColor *)value{
2930
self.markerColor = value;
3031
}
31-
- (void) setTextColor: (UIColor *)value{
32-
self.textColor = value;
33-
}
32+
// - (void) setTextColor: (UIColor *)value{
33+
// self.textColor = value;
34+
// }
3435
- (void) setSize: (NSUInteger)value{
3536
self.markerSize = value;
3637
}
37-
- (void) setTextSize: (NSUInteger)value{
38-
self.textSize = value;
39-
}
40-
- (void) setShape: (NSString *)value {
41-
self.shape = value;
42-
}
38+
// - (void) setTextSize: (NSUInteger)value{
39+
// self.textSize = value;
40+
// }
41+
// - (void) setShape: (NSString *)value {
42+
// self.shape = value;
43+
// }
44+
45+
// - (void) setFont: (UIFont *)value {
46+
// self.font = value;
47+
// }
4348

4449

4550

@@ -63,20 +68,34 @@ -(NTVectorElement*)buildClusterElement:(NTMapPos *)mapPos elements:(NTVectorElem
6368
self.markerImage = [UIImage imageNamed:@"marker_black.png"];
6469
}
6570

66-
UIGraphicsBeginImageContext(self.markerImage.size);
71+
CGSize size = self.markerImage.size;
72+
UIGraphicsBeginImageContext(size);
6773
[self.markerImage drawAtPoint:CGPointMake(0, 0)];
74+
6875

69-
CGRect rect = CGRectMake(0, 15, self.markerImage.size.width, self.markerImage.size.height);
70-
if(self.textColor) {
71-
[self.textColor set];
72-
} else {
73-
[[UIColor whiteColor] set];
74-
}
7576

7677
NSMutableParagraphStyle* style = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
7778
[style setAlignment:NSTextAlignmentCenter];
7879

79-
NSDictionary* attr = [NSDictionary dictionaryWithObject:style forKey:NSParagraphStyleAttributeName];
80+
NSMutableDictionary* attr = [NSMutableDictionary dictionaryWithObject:style forKey:NSParagraphStyleAttributeName];
81+
UIFont* font;
82+
if(self.font) {
83+
font = [self.font fontWithSize:self.textSize];
84+
} else {
85+
font = [UIFont systemFontOfSize:self.textSize];
86+
}
87+
UIColor* color = [UIColor whiteColor];
88+
if(self.textColor) {
89+
color = self.textColor;
90+
}
91+
[attr setObject:color forKey:NSForegroundColorAttributeName];
92+
[attr setObject:font forKey:NSFontAttributeName];
93+
94+
CGSize textSize = [styleKey sizeWithFont:font
95+
constrainedToSize:size
96+
lineBreakMode:(NSLineBreakByWordWrapping)];
97+
98+
CGRect rect = CGRectMake(0, size.height/2 - textSize.height/2, size.width, size.height);
8099
[styleKey drawInRect:CGRectIntegral(rect) withAttributes:attr];
81100

82101
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
@@ -92,7 +111,7 @@ -(NTVectorElement*)buildClusterElement:(NTMapPos *)mapPos elements:(NTVectorElem
92111
[styleBuilder setSize:self.markerSize];
93112

94113
if (self.markerColor != nil) {
95-
[styleBuilder setColor:[CartoAdditionsUtils toNTColor:self.markerColor]];
114+
[styleBuilder setColor:self.markerColor];
96115
}
97116
markerStyle = [styleBuilder buildStyle];
98117
} else {
@@ -104,7 +123,7 @@ -(NTVectorElement*)buildClusterElement:(NTMapPos *)mapPos elements:(NTVectorElem
104123
[styleBuilder setPlacementPriority:(int)[elements size]];
105124

106125
if (self.markerColor != nil) {
107-
[styleBuilder setColor:[CartoAdditionsUtils toNTColor:self.markerColor]];
126+
[styleBuilder setColor:self.markerColor];
108127
}
109128
markerStyle = [styleBuilder buildStyle];
110129
}

plugin/platforms/ios/src/CartoAdditions.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@
33
#import <UIKit/UIKit.h>
44
#import <Foundation/Foundation.h>
55

6-
#import "AkMarkerClusterElementBuilder.h"
6+
#import "AkClusterElementBuilder.h"
77
#import "Utils.h"

src/index.android.ts

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
/* eslint-disable no-redeclare */
2-
import { Color } from '@nativescript/core';
2+
import { Color, Font } from '@nativescript/core';
33
import { NativePropertyOptions } from '.';
44
import { DefaultLatLonKeys, GenericMapPos, MapPos, MapPosVector, MapPosVectorVector, fromNativeMapVec, toNativeMapPos, toNativeMapVec } from './core';
55
import { Geometry } from './geometry';
66
import { FeatureCollection } from './geometry/feature';
77
import { BaseNative, _createImageSourceFromSrc, nativeProperty } from './index.common';
8+
import { BaseVectorElementStyleBuilder } from './vectorelements';
89
export { BaseNative, nativeProperty };
910

1011
export function nativeColorProperty(target: any, k?, desc?: PropertyDescriptor): any;
@@ -28,6 +29,42 @@ export function nativeColorProperty(...args) {
2829
...args
2930
);
3031
}
32+
export function nativeNColorProperty(target: any, k?, desc?: PropertyDescriptor): any;
33+
export function nativeNColorProperty(options: NativePropertyOptions): (target: any, k?, desc?: PropertyDescriptor) => any;
34+
export function nativeNColorProperty(...args) {
35+
return nativeProperty(
36+
{
37+
converter: {
38+
fromNative(value: android.graphics.Color) {
39+
return new Color(value as any);
40+
},
41+
toNative(value): android.graphics.Color {
42+
const theColor = value instanceof Color ? value : value._argb ? new Color(value._argb) : new Color(value);
43+
return theColor.android as any;
44+
},
45+
},
46+
},
47+
...args
48+
);
49+
}
50+
export function nativeFontProperty(target: any, k?, desc?: PropertyDescriptor): any;
51+
export function nativeFontProperty(options: NativePropertyOptions): (target: any, k?, desc?: PropertyDescriptor) => any;
52+
export function nativeFontProperty(...args) {
53+
return nativeProperty(
54+
{
55+
converter: {
56+
fromNative(value) {
57+
// no easy from typeface to Font
58+
return value;
59+
},
60+
toNative(value: Font) {
61+
return value?.getAndroidTypeface();
62+
},
63+
},
64+
},
65+
...args
66+
);
67+
}
3168
export function nativeEnumProperty(target: any, k?, desc?: PropertyDescriptor): any;
3269
export function nativeEnumProperty(options: NativePropertyOptions): (target: any, k?, desc?: PropertyDescriptor) => any;
3370
export function nativeEnumProperty(...args) {
@@ -96,6 +133,17 @@ export function featureCollectionFromArgs<T = DefaultLatLonKeys>(collection: Fea
96133
}
97134
return nativeCollection;
98135
}
136+
export function styleFromArgs(style: BaseVectorElementStyleBuilder<any, any>) {
137+
if (!style) {
138+
return null;
139+
}
140+
let nativeStyle: com.carto.styles.Style = style as any;
141+
142+
if (typeof (style as any).buildStyle === 'function') {
143+
nativeStyle = style.buildStyle();
144+
}
145+
return nativeStyle;
146+
}
99147

100148
export function geometryFromArgs<T = DefaultLatLonKeys>(geometry: Geometry<T>) {
101149
if (!geometry) {

src/index.common.ts

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { RESOURCE_PREFIX, isDataURI, isFileOrResourcePath } from '@nativescript/
66
import { isAndroid } from '@nativescript/core/platform';
77
import { knownFolders, path } from '@nativescript/core/file-system';
88
import { NativePropertyOptions } from '.';
9+
import { fromNativeMapRange, toNativeMapRange } from './core';
910

1011
function createGetter(key: string, options: NativePropertyOptions) {
1112
const nativeGetterName = ((isAndroid ? options.android : options.ios) || options).nativeGetterName || 'get' + key.charAt(0).toUpperCase() + key.slice(1);
@@ -61,6 +62,40 @@ export function nativeProperty(...args) {
6162
return nativePropertyGenerator(args[startIndex], args[startIndex + 1], options || {});
6263
}
6364
}
65+
66+
export function nativeMapRangeProperty(target: any, k?, desc?: PropertyDescriptor): any;
67+
export function nativeMapRangeProperty(options: NativePropertyOptions): (target: any, k?, desc?: PropertyDescriptor) => any;
68+
export function nativeMapRangeProperty(...args) {
69+
return nativeProperty(
70+
{
71+
converter: {
72+
fromNative: fromNativeMapRange,
73+
toNative: toNativeMapRange,
74+
},
75+
},
76+
...args
77+
);
78+
}
79+
80+
export function nonenumerable(target: any, name: string): void;
81+
export function nonenumerable(target: any, name: string, desc: PropertyDescriptor): PropertyDescriptor;
82+
export function nonenumerable(target: any, name: string, desc?: any) {
83+
if (desc) {
84+
desc.enumerable = false;
85+
return desc;
86+
}
87+
Object.defineProperty(target, name, {
88+
set(value) {
89+
Object.defineProperty(this, name, {
90+
value,
91+
writable: true,
92+
configurable: true,
93+
});
94+
},
95+
configurable: true,
96+
});
97+
}
98+
6499
export abstract class BaseNative<T, U extends {}> extends Observable {
65100
constructor(public options: U = {} as any, native?: T) {
66101
super();
@@ -85,10 +120,6 @@ export abstract class BaseNative<T, U extends {}> extends Observable {
85120
return this.native;
86121
}
87122
abstract createNative(options: U): T;
88-
89-
log(...args) {
90-
console.log(`[${this.constructor.name}]`, ...args);
91-
}
92123
}
93124

94125
export function _createImageSourceFromSrc(value: string | ImageSource | ImageAsset): ImageSource {

src/index.d.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ export abstract class BaseNative<T, U extends {}> extends Observable {
1111
constructor(options?: U, native?: T);
1212
initNativeView(native: T, options: U): void;
1313
getNative(): T;
14-
log(...args);
1514
}
1615
export interface NativePropertyOptions {
1716
converter?: {
@@ -38,12 +37,23 @@ export declare function nativeProperty(...args);
3837

3938
export declare function mapPosVectorFromArgs<T = DefaultLatLonKeys>(positions: MapPosVector<T> | GenericMapPos<T>[], ignoreAltitude?: boolean): any;
4039
export declare function featureCollectionFromArgs<T = DefaultLatLonKeys>(positions: FeatureCollection<T>): any;
40+
export function styleFromArgs(style: BaseVectorElementStyleBuilder<any, any>): any;
4141
export declare function geometryFromArgs<T = DefaultLatLonKeys>(geometry: Geometry<T>): any;
4242
export declare function mapPosVectorVectorFromArgs<T = DefaultLatLonKeys>(positions: MapPosVectorVector<T> | GenericMapPos<T>[][], ignoreAltitude?: boolean): any;
4343

4444
export declare function nativeColorProperty(target: any, k?, desc?: PropertyDescriptor): any;
4545
export declare function nativeColorProperty(options: NativePropertyOptions): (target: any, k?, desc?: PropertyDescriptor) => any;
4646
export declare function nativeColorProperty(...args);
47+
48+
49+
export declare function nativeNColorProperty(target: any, k?, desc?: PropertyDescriptor): any;
50+
export declare function nativeNColorProperty(options: NativePropertyOptions): (target: any, k?, desc?: PropertyDescriptor) => any;
51+
export declare function nativeNColorProperty(...args);
52+
53+
export declare function nativeFontProperty(target: any, k?, desc?: PropertyDescriptor): any;
54+
export declare function nativeFontProperty(options: NativePropertyOptions): (target: any, k?, desc?: PropertyDescriptor) => any;
55+
export declare function nativeFontProperty(...args);
56+
4757
export declare function nativeEnumProperty(target: any, k?, desc?: PropertyDescriptor): any;
4858
export declare function nativeEnumProperty(options: NativePropertyOptions): (target: any, k?, desc?: PropertyDescriptor) => any;
4959
export declare function nativeEnumProperty(...args);

0 commit comments

Comments
 (0)