Skip to content

Commit

Permalink
fixes [Feature] Support optional rotation for non line labels like ci…
Browse files Browse the repository at this point in the history
…ty, area, country etc. greensopinion#76
  • Loading branch information
Skandar Munir Ahmed committed Mar 30, 2023
1 parent c42c0ee commit 428e009
Show file tree
Hide file tree
Showing 8 changed files with 35 additions and 21 deletions.
21 changes: 10 additions & 11 deletions lib/src/features/feature_renderer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,20 @@ import 'symbol_line_renderer.dart';
import 'symbol_point_renderer.dart';

abstract class FeatureRenderer {
void render(
Context context,
ThemeLayerType layerType,
Style style,
TileLayer layer,
TileFeature feature,
);
void render(Context context, ThemeLayerType layerType, Style style,
TileLayer layer, TileFeature feature, double rotation);
}

class FeatureDispatcher extends FeatureRenderer {
final Logger logger;
final Map<ThemeLayerType, FeatureRenderer> typeToRenderer;
final Map<TileFeatureType, FeatureRenderer> symbolTypeToRenderer;
final double rotation;

FeatureDispatcher(this.logger)
FeatureDispatcher(this.logger, {this.rotation = 0})
: typeToRenderer = createDispatchMapping(logger),
symbolTypeToRenderer = createSymbolDispatchMapping(logger);
symbolTypeToRenderer =
createSymbolDispatchMapping(logger, rotation: rotation);

@override
void render(
Expand All @@ -34,6 +31,7 @@ class FeatureDispatcher extends FeatureRenderer {
Style style,
TileLayer layer,
TileFeature feature,
double rotation,
) {
FeatureRenderer? delegate;
if (layerType == ThemeLayerType.symbol) {
Expand All @@ -46,7 +44,7 @@ class FeatureDispatcher extends FeatureRenderer {
logger.warn(() =>
'layer type $layerType feature ${feature.type} is not implemented');
} else {
delegate.render(context, layerType, style, layer, feature);
delegate.render(context, layerType, style, layer, feature, rotation);
}
}

Expand All @@ -60,7 +58,8 @@ class FeatureDispatcher extends FeatureRenderer {
}

static Map<TileFeatureType, FeatureRenderer> createSymbolDispatchMapping(
Logger logger) {
Logger logger,
{double rotation = 0}) {
return {
TileFeatureType.point: SymbolPointRenderer(logger),
TileFeatureType.linestring: SymbolLineRenderer(logger),
Expand Down
1 change: 1 addition & 0 deletions lib/src/features/fill_renderer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class FillRenderer extends FeatureRenderer {
Style style,
TileLayer layer,
TileFeature feature,
double rotation,
) {
if (!feature.hasPaths) {
return;
Expand Down
1 change: 1 addition & 0 deletions lib/src/features/line_renderer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class LineRenderer extends FeatureRenderer {
Style style,
TileLayer layer,
TileFeature feature,
double rotation,
) {
if (!feature.hasPaths) {
return;
Expand Down
1 change: 1 addition & 0 deletions lib/src/features/symbol_line_renderer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class SymbolLineRenderer extends FeatureRenderer {
Style style,
TileLayer layer,
TileFeature feature,
double rotation,
) {
final textPaint = style.textPaint;
final textLayout = style.textLayout;
Expand Down
8 changes: 8 additions & 0 deletions lib/src/features/symbol_point_renderer.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'dart:math';
import 'dart:ui';

import '../../vector_tile_renderer.dart';
Expand All @@ -12,6 +13,7 @@ import 'text_wrapper.dart';
class SymbolPointRenderer extends FeatureRenderer {
final Logger logger;
SymbolPointRenderer(this.logger);
double degrees2Radians = pi / 180.0;

@override
void render(
Expand All @@ -20,6 +22,7 @@ class SymbolPointRenderer extends FeatureRenderer {
Style style,
TileLayer layer,
TileFeature feature,
double rotation,
) {
final textPaint = style.textPaint;
final textLayout = style.textLayout;
Expand Down Expand Up @@ -58,8 +61,13 @@ class SymbolPointRenderer extends FeatureRenderer {
}

context.tileSpaceMapper.drawInPixelSpace(() {
context.canvas.translate(offset.dx, offset.dy);
context.canvas.rotate(-degrees2Radians * rotation);
context.canvas.translate(-offset.dx, -offset.dy);
textApproximation.renderer.render(offset);
});

context.canvas.restore();
}
}

Expand Down
17 changes: 10 additions & 7 deletions lib/src/renderer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,15 @@ class Renderer {
final Logger logger;
final FeatureDispatcher featureRenderer;
final TextPainterProvider painterProvider;
Renderer(
{required this.theme,
this.painterProvider = const DefaultTextPainterProvider(),
Logger? logger})
: logger = logger ?? const Logger.noop(),
featureRenderer = FeatureDispatcher(logger ?? const Logger.noop());
final double rotation;
Renderer({
required this.theme,
this.painterProvider = const DefaultTextPainterProvider(),
Logger? logger,
this.rotation = 0,
}) : logger = logger ?? const Logger.noop(),
featureRenderer = FeatureDispatcher(logger ?? const Logger.noop(),
rotation: rotation);

/// renders the given tile to the canvas
///
Expand Down Expand Up @@ -58,7 +61,7 @@ class Renderer {
final effectiveTheme = theme.atZoom(zoom);
for (final themeLayer in effectiveTheme.layers) {
logger.log(() => 'rendering theme layer ${themeLayer.id}');
themeLayer.render(context);
themeLayer.render(context, rotation: rotation);
}
canvas.restore();
});
Expand Down
2 changes: 1 addition & 1 deletion lib/src/themes/theme.dart
Original file line number Diff line number Diff line change
Expand Up @@ -58,5 +58,5 @@ abstract class ThemeLayer {

String? get tileSource;

void render(Context context);
void render(Context context, {double rotation = 0});
}
5 changes: 3 additions & 2 deletions lib/src/themes/theme_layers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class DefaultLayer extends ThemeLayer {
: super(id, type, minzoom: minzoom, maxzoom: maxzoom, metadata: metadata);

@override
void render(Context context) {
void render(Context context, {double rotation = 0}) {
final layers = selector.select(context.tileset, context.zoom.truncate());
if (layers.isEmpty) {
return;
Expand Down Expand Up @@ -52,6 +52,7 @@ class DefaultLayer extends ThemeLayer {
style,
feature.layer,
feature.feature,
rotation,
);
}
});
Expand All @@ -70,7 +71,7 @@ class BackgroundLayer extends ThemeLayer {
minzoom: 0, maxzoom: 24, metadata: metadata);

@override
void render(Context context) {
void render(Context context, {double rotation = 0}) {
context.logger.log(() => 'rendering $id');
final color = fillColor.evaluate(EvaluationContext(
() => {}, TileFeatureType.background, context.logger,
Expand Down

0 comments on commit 428e009

Please sign in to comment.