Skip to content

Commit c5cf557

Browse files
author
Clément Le Provost
committed
Support a union of polygons in the insidePolygon query parameter
WARNING: Breaking change (for this parameter only).
1 parent 0631e53 commit c5cf557

File tree

3 files changed

+38
-28
lines changed

3 files changed

+38
-28
lines changed

Source/Query.swift

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -676,35 +676,40 @@ open class Query : AbstractQuery {
676676
}
677677
}
678678

679-
/// Search entries inside a given area defined by a set of points (defined by a minimum of 3 points).
680-
/// You can pass several time the insidePolygon parameter to your query, the behavior will be a OR between all those polygons.
681-
@objc public var insidePolygon: [LatLng]? {
682-
// FIXME: Union cannot work with this implementation, as at most one occurrence per parameter is supported.
679+
/// Search entries inside a given area defined by a union of polygons.
680+
/// Each polygon must be defined by a minimum of 3 points.
681+
@objc public var insidePolygon: [[LatLng]]? {
683682
get {
684-
if let fields = self["insidePolygon"]?.components(separatedBy: ",") {
685-
if fields.count % 2 == 0 && fields.count / 2 >= 3 {
686-
var result = [LatLng]()
687-
for i in 0..<(fields.count / 2) {
688-
if let lat = Double(fields[2 * i + 0]), let lng = Double(fields[2 * i + 1]) {
689-
result.append(LatLng(lat: lat, lng: lng))
690-
}
683+
if let data = self["insidePolygon"]?.data(using: .utf8, allowLossyConversion: false),
684+
let srcPolygons = (try? JSONSerialization.jsonObject(with: data, options: [])) as? [[Double]] {
685+
var dstPolygons = [[LatLng]]()
686+
for srcPolygon in srcPolygons {
687+
var dstPolygon = [LatLng]()
688+
if srcPolygon.count % 2 != 0 { continue }
689+
for i in 0 ..< srcPolygon.count / 2 {
690+
let point = LatLng(lat: srcPolygon[2 * i], lng: srcPolygon[2 * i + 1])
691+
dstPolygon.append(point)
691692
}
692-
return result
693+
dstPolygons.append(dstPolygon)
693694
}
695+
return dstPolygons
694696
}
695697
return nil
696698
}
697699
set {
698-
if newValue == nil {
699-
self["insidePolygon"] = nil
700-
} else {
701-
assert(newValue!.count >= 3)
702-
var components = [String]()
703-
for point in newValue! {
704-
components.append(String(point.lat))
705-
components.append(String(point.lng))
700+
if let srcPolygons = newValue {
701+
var dstPolygons = [[Double]]()
702+
for srcPolygon in srcPolygons {
703+
var dstPolygon = [Double]()
704+
for point in srcPolygon {
705+
dstPolygon.append(point.lat)
706+
dstPolygon.append(point.lng)
707+
}
708+
dstPolygons.append(dstPolygon)
706709
}
707-
self["insidePolygon"] = components.joined(separator: ",")
710+
self["insidePolygon"] = AbstractQuery.buildJSONArray(dstPolygons)
711+
} else {
712+
self["insidePolygon"] = nil
708713
}
709714
}
710715
}

Tests/ObjectiveCBridging.m

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,9 @@ - (void)testQuery {
117117
query.aroundPrecision = [NSNumber numberWithInt:66];
118118
query.minimumAroundRadius = [NSNumber numberWithInt:666];
119119
query.insideBoundingBox = @[ [[GeoRect alloc] initWithP1:[[LatLng alloc] initWithLat:123.45 lng:67.89] p2:[[LatLng alloc] initWithLat:129.99 lng:69.99]] ];
120-
query.insidePolygon = @[ [[LatLng alloc] initWithLat:123.45 lng:67.89], [[LatLng alloc] initWithLat:129.99 lng:69.99], [[LatLng alloc] initWithLat:0.0 lng:0.0] ];
120+
query.insidePolygon = @[
121+
@[ [[LatLng alloc] initWithLat:123.45 lng:67.89], [[LatLng alloc] initWithLat:129.99 lng:69.99], [[LatLng alloc] initWithLat:0.0 lng:0.0] ]
122+
];
121123
}
122124

123125
- (void)testClient {

Tests/QueryTests.swift

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -523,12 +523,15 @@ class QueryTests: XCTestCase {
523523
func test_insidePolygon() {
524524
let query1 = Query()
525525
XCTAssertNil(query1.insidePolygon)
526-
let box = [LatLng(lat: 11.111111, lng: 22.222222), LatLng(lat: 33.333333, lng: 44.444444), LatLng(lat: -55.555555, lng: -66.666666)]
527-
query1.insidePolygon = box
528-
XCTAssertEqual(query1.insidePolygon!, box)
529-
XCTAssertEqual(query1["insidePolygon"], "11.111111,22.222222,33.333333,44.444444,-55.555555,-66.666666")
530-
let query2 = Query.parse(query1.build())
531-
XCTAssertEqual(query2.insidePolygon!, box)
526+
let POLYGONS: [[LatLng]] = [
527+
[LatLng(lat: 11.111111, lng: 22.222222), LatLng(lat: 33.333333, lng: 44.444444), LatLng(lat: -55.555555, lng: -66.666667)],
528+
[LatLng(lat: -77.777777, lng: -88.888887), LatLng(lat: 11.111111, lng: 22.222222), LatLng(lat: 0, lng: 0)]
529+
]
530+
query1.insidePolygon = POLYGONS
531+
XCTAssertEqual(query1.insidePolygon! as NSObject, POLYGONS as NSObject)
532+
XCTAssertEqual(query1["insidePolygon"], "[[11.111111,22.222222,33.333333,44.444444,-55.555555,-66.666667],[-77.777777,-88.888887,11.111111,22.222222,0,0]]")
533+
let query2 = Query.parse(query1.build())
534+
XCTAssertEqual(query2.insidePolygon! as NSObject, POLYGONS as NSObject)
532535
}
533536

534537
func test_tagFilters() {

0 commit comments

Comments
 (0)