Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
This repository was archived by the owner on May 17, 2021. It is now read-only.

Commit a3731d9

Browse files
feat: Add support for $near and $nearSphere geo operators. Add additional grammar helpers.
- Add number_positive grammar - Add number_longitude grammar - Add number_latitude grammar - Add array_number grammar - Add legacy_coordinates grammar - Add $near/$nearSphere operator - Add $minDistance/$maxDistance operator - Updated unit test cases
1 parent 7df2798 commit a3731d9

File tree

2 files changed

+390
-23
lines changed

2 files changed

+390
-23
lines changed

‎src/grammar.pegjs‎

Lines changed: 88 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,16 @@ operator
115115
// geo-intersects-operator
116116
/ quotation_mark "$geoIntersects" quotation_mark name_separator geometry:geometry
117117
{ return { pos: "geo-intersects-operator", operator: "$geoIntersects", geometry: geometry }; }
118-
118+
// near-operator
119+
/ quotation_mark near_operator:("$nearSphere" / "$near") quotation_mark name_separator value:(geometry_point / legacy_coordinates)
120+
{ return { pos: "near-operator", operator: near_operator, value: value }; }
121+
// min-distance-operator
122+
/ quotation_mark operator:distance_operator quotation_mark name_separator value:number_positive
123+
{ return { pos: "distance-operator", operator: operator, value: value }; }
119124

120125
/* --- Geo Operators --- */
126+
distance_operator
127+
= "$minDistance" / "$maxDistance"
121128

122129
shape
123130
= geometry
@@ -144,15 +151,41 @@ geometry
144151
end_object
145152
{ return { "$geometry": members }; }
146153

154+
geometry_point
155+
= begin_object
156+
quotation_mark "$geometry" quotation_mark name_separator
157+
begin_object
158+
geometry:(
159+
type:(
160+
quotation_mark "type" quotation_mark
161+
name_separator quotation_mark type:"Point" quotation_mark
162+
{ return type; }
163+
)
164+
coordinates:(
165+
value_separator quotation_mark "coordinates" quotation_mark
166+
name_separator coordinates:legacy_coordinates
167+
{ return coordinates; }
168+
)
169+
{ return { "type": type, "coordinates": coordinates }; }
170+
)
171+
end_object
172+
distance:(
173+
value_separator quotation_mark operator:distance_operator quotation_mark
174+
name_separator value:number_positive
175+
{ return { [operator]: value }; }
176+
)*
177+
end_object
178+
{
179+
return {
180+
"$geometry": geometry,
181+
...(distance ? distance : {})
182+
};
183+
}
184+
147185
geometry_type
148-
= "Point"
149-
/ "LineString"
150-
/ "Polygon"
151-
/ "MultiPoint"
152-
/ "MultiLineString"
186+
= "Polygon"
153187
/ "MultiPolygon"
154188

155-
156189
geometry_coordinates
157190
= begin_array
158191
values:(
@@ -162,6 +195,12 @@ geometry_coordinates
162195
)?
163196
end_array
164197

198+
legacy_coordinates
199+
= begin_array
200+
number_longitude value_separator
201+
number_latitude
202+
end_array
203+
165204
legacy_shape
166205
= center_shape
167206
/ polygon_shape
@@ -171,8 +210,8 @@ center_shape
171210
= begin_object
172211
quotation_mark center_operator:("$centerSphere" / "$center") quotation_mark name_separator
173212
parameters:$(begin_array
174-
begin_array
175-
number value_separator number
213+
begin_array
214+
number value_separator number
176215
end_array
177216
value_separator
178217
number
@@ -188,13 +227,13 @@ box_shape
188227
= begin_object
189228
quotation_mark "$box" quotation_mark name_separator
190229
parameters:$(begin_array
191-
begin_array
192-
number value_separator number
230+
begin_array
231+
number value_separator number
193232
end_array
194233
value_separator
195234
begin_array
196235
number value_separator number
197-
end_array
236+
end_array
198237
end_array)
199238
end_object
200239
{ return {"$box": JSON.parse(parameters)}; }
@@ -204,19 +243,18 @@ polygon_shape
204243
= begin_object
205244
quotation_mark "$polygon" quotation_mark name_separator
206245
parameters:$(begin_array
207-
head:(begin_array
208-
number value_separator number
246+
head:(begin_array
247+
number value_separator number
209248
end_array)
210249
tail:(value_separator
211250
begin_array
212251
number value_separator number
213-
end_array)*
252+
end_array)*
214253
end_array
215254
{ return [head].concat(tail); })
216255
end_object
217256
{ return {"$polygon": JSON.parse(parameters)}; }
218257

219-
220258
where_operator = "$where"
221259

222260
text_operator = "$text"
@@ -369,9 +407,9 @@ ejson_undefined
369407

370408
ejson_dbref
371409
= begin_object
372-
members:(
410+
members:(
373411
ref:(
374-
quotation_mark "$ref" quotation_mark
412+
quotation_mark "$ref" quotation_mark
375413
name_separator string:string
376414
{ return string; }
377415
)
@@ -388,17 +426,17 @@ ejson_dbref
388426
{
389427
var result = {"$ref": ref, "$id": id};
390428
if (db !== null) result["$db"] = db;
391-
return result;
429+
return result;
392430
}
393431
)
394432
end_object
395433
{ return members; }
396434

397435
ejson_regex
398436
= begin_object
399-
members:(
437+
members:(
400438
regex:(
401-
quotation_mark "$regex" quotation_mark
439+
quotation_mark "$regex" quotation_mark
402440
name_separator string:string
403441
{ return string; }
404442
)
@@ -414,9 +452,9 @@ ejson_regex
414452

415453
ejson_binary
416454
= begin_object
417-
members:(
455+
members:(
418456
binary:(
419-
quotation_mark "$binary" quotation_mark
457+
quotation_mark "$binary" quotation_mark
420458
name_separator string:string
421459
{ return string; }
422460
)
@@ -489,6 +527,33 @@ array_number
489527
number "number"
490528
= minus? int frac? exp? { return parseFloat(text()); }
491529

530+
number_positive
531+
= int frac? exp? { return parseFloat(text()); }
532+
533+
// A numeric value that represents a longitude coordinate (to any precision between -180.0 and 180.0, inclusive)
534+
// Converted to PEG syntax from this regex: ^-?(180(\.0)?|(1[0-7]\d|[1-9]?\d)(\.(0|\d*[1-9]))?)$
535+
// Taking into account PEG's greedy behaviour and lack of backtracking.
536+
number_longitude
537+
= minus? (
538+
"180"(decimal_point zero)?
539+
/ (
540+
(("1" [0-7] DIGIT / digit1_9 DIGIT / DIGIT) decimal_point int*)
541+
/ (("1" [0-7] DIGIT / digit1_9 DIGIT / DIGIT))
542+
)
543+
)
544+
545+
// A numeric value that represents a latitude coordinate (to any precision between -90.0 and 90.0, inclusive)
546+
// Converted to PEG syntax from regex: ^-?(90(\.0)?|([1-8]?\d)(\.(0|\d*[1-9]))?)$
547+
// Taking into account PEG's greedy behaviour and lack of backtracking.
548+
number_latitude
549+
= minus? (
550+
"90"(decimal_point zero)?
551+
/ (
552+
((digit1_9 DIGIT / DIGIT) decimal_point int*)
553+
/ ((digit1_9 DIGIT / DIGIT))
554+
)
555+
)
556+
492557
decimal_point = "."
493558
digit1_9 = [1-9]
494559
e = [eE]

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /