Skip to content

Commit

Permalink
Add polygon label placement options (#1225)
Browse files Browse the repository at this point in the history
* Add polygon label placement options

* Changed default `labelPlacement` mode to `polylabel`

Co-authored-by: Luka S <github@jaffaketchup.dev>
  • Loading branch information
beroso and JaffaKetchup authored May 8, 2022
1 parent f2b9271 commit bf782ba
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 17 deletions.
62 changes: 45 additions & 17 deletions lib/src/layer/label.dart
Original file line number Diff line number Diff line change
@@ -1,26 +1,30 @@
import 'dart:math';
import 'dart:math' as math;

import 'package:collection/collection.dart';
import 'package:flutter/material.dart';
import 'package:flutter_map/plugin_api.dart';
import 'package:polylabel/polylabel.dart';

class Label {
static void paintText(
Canvas canvas,
List<Offset> points,
String? labelText,
TextStyle? labelStyle,
) {
var maxDx = 0.0;
var minDx = double.infinity;
var dx = points.map((e) => e.dx).toList().fold<double>(0.0,
(previousValue, element) {
maxDx = max(maxDx, element);
minDx = min(minDx, element);
return previousValue + element;
}) /
points.length;
var dy = points.map((e) => e.dy).toList().fold<double>(
0.0, (previousValue, element) => previousValue + element) /
points.length;
TextStyle? labelStyle, {
PolygonLabelPlacement labelPlacement = PolygonLabelPlacement.polylabel,
}) {
late Offset placementPoint;
switch (labelPlacement) {
case PolygonLabelPlacement.centroid:
placementPoint = _computeCentroid(points);
break;
case PolygonLabelPlacement.polylabel:
placementPoint = _computePolylabel(points);
break;
}

var dx = placementPoint.dx;
var dy = placementPoint.dy;

final textSpan = TextSpan(text: labelText, style: labelStyle);
final textPainter = TextPainter(
Expand All @@ -31,8 +35,15 @@ class Label {
);
if (dx > 0) {
textPainter.layout(minWidth: 0, maxWidth: double.infinity);
dx = dx - textPainter.width / 2;
dy = dy - textPainter.height / 2;
dx -= textPainter.width / 2;
dy -= textPainter.height / 2;

var maxDx = 0.0;
var minDx = double.infinity;
for (final point in points) {
maxDx = math.max(maxDx, point.dx);
minDx = math.min(minDx, point.dx);
}

if (maxDx - minDx > textPainter.width) {
textPainter.paint(
Expand All @@ -42,4 +53,21 @@ class Label {
}
}
}

static Offset _computeCentroid(List<Offset> points) {
return Offset(
points.map((e) => e.dx).toList().average,
points.map((e) => e.dy).toList().average,
);
}

static Offset _computePolylabel(List<Offset> points) {
final labelPosition = polylabel([
points.map((p) => math.Point(p.dx, p.dy)).toList(),
]);
return Offset(
labelPosition.point.x.toDouble(),
labelPosition.point.y.toDouble(),
);
}
}
8 changes: 8 additions & 0 deletions lib/src/layer/polygon_layer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ class PolygonLayerOptions extends LayerOptions {
}
}

enum PolygonLabelPlacement {
centroid,
polylabel,
}

class Polygon {
final List<LatLng> points;
final List<Offset> offsets = [];
Expand All @@ -40,6 +45,7 @@ class Polygon {
late final LatLngBounds boundingBox;
final String? label;
final TextStyle labelStyle;
final PolygonLabelPlacement labelPlacement;

Polygon({
required this.points,
Expand All @@ -52,6 +58,7 @@ class Polygon {
this.isFilled = false,
this.label,
this.labelStyle = const TextStyle(),
this.labelPlacement = PolygonLabelPlacement.centroid,
}) : holeOffsetsList = null == holePointsList || holePointsList.isEmpty
? null
: List.generate(holePointsList.length, (_) => []);
Expand Down Expand Up @@ -268,6 +275,7 @@ class PolygonPainter extends CustomPainter {
polygonOpt.offsets,
polygonOpt.label,
polygonOpt.labelStyle,
labelPlacement: polygonOpt.labelPlacement,
);
}
}
Expand Down
1 change: 1 addition & 0 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ dependencies:
intl: ^0.17.0
latlong2: ^0.8.0
meta: ^1.3.0
polylabel: ^1.0.1
positioned_tap_detector_2: ^1.0.4
proj4dart: ^2.0.0
transparent_image: ^2.0.0
Expand Down

0 comments on commit bf782ba

Please sign in to comment.