Skip to content

Commit dafa3cd

Browse files
authored
Implement booleanWithin (#167)
* document feature booleanWithin * implement boolean within * implement boolean within * add boolean within tests * export boolean features * remove duplicate code * refactor tests * rename import * remove warnings * add source link to readme * add library declaration for turf_boolean * Code review suggestions * . * . * fix typos * fix analyzer warning due to recent dart 3.3.0 release
1 parent f377e46 commit dafa3cd

File tree

10 files changed

+496
-132
lines changed

10 files changed

+496
-132
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ Any new benchmarks must be named `*_benchmark.dart` and reside in the
237237
- [x] [booleanParallel](https://github.com/dartclub/turf_dart/blob/main/lib/src/booleans/boolean_parallel.dart)
238238
- [x] [booleanPointInPolygon](https://github.com/dartclub/turf_dart/blob/main/lib/src/booleans/boolean_point_in_polygon.dart)
239239
- [x] [booleanPointOnLine](https://github.com/dartclub/turf_dart/blob/main/lib/src/booleans/boolean_point_on_line.dart)
240-
- [ ] booleanWithin
240+
- [x] [booleanWithin](https://github.com/dartclub/turf_dart/blob/main/lib/src/booleans/boolean_within.dart)
241241

242242
### Unit Conversion
243243

@@ -250,4 +250,4 @@ Any new benchmarks must be named `*_benchmark.dart` and reside in the
250250
- [x] [radiansToLength](https://github.com/dartclub/turf_dart/blob/main/lib/src/helpers.dart)
251251
- [x] [radiansToDegrees](https://github.com/dartclub/turf_dart/blob/main/lib/src/helpers.dart)
252252
- [ ] toMercator
253-
- [ ] toWgs84
253+
- [ ] toWgs84

lib/boolean.dart

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
library turf_boolean;
2+
3+
export 'src/booleans/boolean_clockwise.dart';
4+
export 'src/booleans/boolean_concave.dart';
5+
export 'src/booleans/boolean_contains.dart';
6+
export 'src/booleans/boolean_crosses.dart';
7+
export 'src/booleans/boolean_disjoint.dart';
8+
export 'src/booleans/boolean_equal.dart';
9+
export 'src/booleans/boolean_intersects.dart';
10+
// export 'src/booleans/boolean_overlap.dart';
11+
export 'src/booleans/boolean_parallel.dart';
12+
export 'src/booleans/boolean_point_in_polygon.dart';
13+
export 'src/booleans/boolean_point_on_line.dart';
14+
export 'src/booleans/boolean_touches.dart';
15+
export 'src/booleans/boolean_valid.dart';
16+
export 'src/booleans/boolean_within.dart';

lib/src/booleans/boolean_contains.dart

Lines changed: 22 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import 'package:turf/turf.dart';
33

44
import 'boolean_point_in_polygon.dart';
55
import 'boolean_point_on_line.dart';
6+
import 'boolean_helper.dart';
67

78
/// [booleanContains] returns [true] if the second geometry is completely contained
89
/// by the first geometry.
@@ -11,162 +12,75 @@ import 'boolean_point_on_line.dart';
1112
/// [booleanContains] returns the exact opposite result of the [booleanWithin].
1213
/// example:
1314
/// ```dart
14-
/// var line = LineString(coordinates: [
15+
/// final line = LineString(coordinates: [
1516
/// Position.of([1, 1]),
1617
/// Position.of([1, 2]),
1718
/// Position.of([1, 3]),
1819
/// Position.of([1, 4])
1920
/// ]);
20-
/// var point = Point(coordinates: Position.of([1, 2]));
21+
/// final point = Point(coordinates: Position.of([1, 2]));
2122
/// booleanContains(line, point);
2223
/// //=true
2324
/// ```
2425
bool booleanContains(GeoJSONObject feature1, GeoJSONObject feature2) {
25-
var geom1 = getGeom(feature1);
26-
var geom2 = getGeom(feature2);
26+
final geom1 = getGeom(feature1);
27+
final geom2 = getGeom(feature2);
2728

28-
var coords1 = (geom1 as GeometryType).coordinates;
29-
var coords2 = (geom2 as GeometryType).coordinates;
30-
final exception = Exception("{feature2 $geom2 geometry not supported}");
29+
final coords1 = (geom1 as GeometryType).coordinates;
30+
final coords2 = (geom2 as GeometryType).coordinates;
3131
if (geom1 is Point) {
3232
if (geom2 is Point) {
3333
return coords1 == coords2;
3434
} else {
35-
throw exception;
35+
throw FeatureNotSupported(geom1, geom2);
3636
}
3737
} else if (geom1 is MultiPoint) {
3838
if (geom2 is Point) {
39-
return _isPointInMultiPoint(geom1, geom2);
39+
return isPointInMultiPoint(geom2, geom1);
4040
} else if (geom2 is MultiPoint) {
41-
return _isMultiPointInMultiPoint(geom1, geom2);
41+
return isMultiPointInMultiPoint(geom2, geom1);
4242
} else {
43-
throw exception;
43+
throw FeatureNotSupported(geom1, geom2);
4444
}
4545
} else if (geom1 is LineString) {
4646
if (geom2 is Point) {
4747
return booleanPointOnLine(geom2, geom1, ignoreEndVertices: true);
4848
} else if (geom2 is LineString) {
49-
return _isLineOnLine(geom1, geom2);
49+
return isLineOnLine(geom2, geom1);
5050
} else if (geom2 is MultiPoint) {
51-
return _isMultiPointOnLine(geom1, geom2);
51+
return isMultiPointOnLine(geom2, geom1);
5252
} else {
53-
throw exception;
53+
throw FeatureNotSupported(geom1, geom2);
5454
}
5555
} else if (geom1 is Polygon) {
5656
if (geom2 is Point) {
5757
return booleanPointInPolygon((geom2).coordinates, geom1,
5858
ignoreBoundary: true);
5959
} else if (geom2 is LineString) {
60-
return _isLineInPoly(geom1, geom2);
60+
return isLineInPolygon(geom2, geom1);
6161
} else if (geom2 is Polygon) {
6262
return _isPolyInPoly(geom1, geom2);
6363
} else if (geom2 is MultiPoint) {
64-
return _isMultiPointInPoly(geom1, geom2);
64+
return isMultiPointInPolygon(geom2, geom1);
6565
} else {
66-
throw exception;
66+
throw FeatureNotSupported(geom1, geom2);
6767
}
6868
} else {
69-
throw exception;
69+
throw FeatureNotSupported(geom1, geom2);
7070
}
7171
}
7272

73-
bool _isPointInMultiPoint(MultiPoint multiPoint, Point pt) {
74-
for (int i = 0; i < multiPoint.coordinates.length; i++) {
75-
if ((multiPoint.coordinates[i] == pt.coordinates)) {
76-
return true;
77-
}
78-
}
79-
return false;
80-
}
81-
82-
bool _isMultiPointInMultiPoint(MultiPoint multiPoint1, MultiPoint multiPoint2) {
83-
for (Position coord2 in multiPoint2.coordinates) {
84-
bool match = false;
85-
for (Position coord1 in multiPoint1.coordinates) {
86-
if (coord2 == coord1) {
87-
match = true;
88-
}
89-
}
90-
if (!match) return false;
91-
}
92-
return true;
93-
}
94-
95-
bool _isMultiPointOnLine(LineString lineString, MultiPoint multiPoint) {
96-
var haveFoundInteriorPoint = false;
97-
for (var coord in multiPoint.coordinates) {
98-
if (booleanPointOnLine(Point(coordinates: coord), lineString,
99-
ignoreEndVertices: true)) {
100-
haveFoundInteriorPoint = true;
101-
}
102-
if (!booleanPointOnLine(Point(coordinates: coord), lineString)) {
103-
return false;
104-
}
105-
}
106-
return haveFoundInteriorPoint;
107-
}
108-
109-
bool _isMultiPointInPoly(Polygon polygon, MultiPoint multiPoint) {
110-
for (var coord in multiPoint.coordinates) {
111-
if (!booleanPointInPolygon(coord, polygon, ignoreBoundary: true)) {
112-
return false;
113-
}
114-
}
115-
return true;
116-
}
117-
118-
bool _isLineOnLine(LineString lineString1, LineString lineString2) {
119-
var haveFoundInteriorPoint = false;
120-
for (Position coord in lineString2.coordinates) {
121-
if (booleanPointOnLine(
122-
Point(coordinates: coord),
123-
lineString1,
124-
ignoreEndVertices: true,
125-
)) {
126-
haveFoundInteriorPoint = true;
127-
}
128-
if (!booleanPointOnLine(
129-
Point(coordinates: coord),
130-
lineString1,
131-
ignoreEndVertices: false,
132-
)) {
133-
return false;
134-
}
135-
}
136-
return haveFoundInteriorPoint;
137-
}
138-
139-
bool _isLineInPoly(Polygon polygon, LineString linestring) {
140-
var polyBbox = bbox(polygon);
141-
var lineBbox = bbox(linestring);
142-
if (!_doBBoxesOverlap(polyBbox, lineBbox)) {
143-
return false;
144-
}
145-
for (var i = 0; i < linestring.coordinates.length - 1; i++) {
146-
var midPoint =
147-
midpointRaw(linestring.coordinates[i], linestring.coordinates[i + 1]);
148-
if (booleanPointInPolygon(
149-
midPoint,
150-
polygon,
151-
ignoreBoundary: true,
152-
)) {
153-
return true;
154-
}
155-
}
156-
return false;
157-
}
158-
15973
/// Is Polygon2 in Polygon1
16074
/// Only takes into account outer rings
16175
bool _isPolyInPoly(GeoJSONObject geom1, GeoJSONObject geom2) {
162-
var poly1Bbox = bbox(geom1);
163-
var poly2Bbox = bbox(geom2);
76+
final poly1Bbox = bbox(geom1);
77+
final poly2Bbox = bbox(geom2);
16478
if (!_doBBoxesOverlap(poly1Bbox, poly2Bbox)) {
16579
return false;
16680
}
16781

168-
for (var ring in (geom2 as GeometryType).coordinates) {
169-
for (var coord in ring) {
82+
for (final ring in (geom2 as GeometryType).coordinates) {
83+
for (final coord in ring) {
17084
if (!booleanPointInPolygon(coord, geom1)) {
17185
return false;
17286
}

0 commit comments

Comments
 (0)