-
Notifications
You must be signed in to change notification settings - Fork 98
geometry relation support for data search #1205
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -58,11 +58,6 @@ def data(ctx, base_url): | |||||
| ctx.obj['BASE_URL'] = base_url | ||||||
|
|
||||||
|
|
||||||
| # TODO: filter(). | ||||||
| def geom_to_filter(ctx, param, value: Optional[dict]) -> Optional[dict]: | ||||||
| return data_filter.geometry_filter(value) if value else None | ||||||
|
|
||||||
|
|
||||||
| def assets_to_filter(ctx, param, assets: List[str]) -> Optional[dict]: | ||||||
| # TODO: validate and normalize | ||||||
| return data_filter.asset_filter(assets) if assets else None | ||||||
|
|
@@ -172,9 +167,14 @@ def _func(obj): | |||||
| DATETIME can be an RFC3339 or ISO 8601 string.""") | ||||||
| @click.option('--geom', | ||||||
| type=types.JSON(), | ||||||
| callback=geom_to_filter, | ||||||
| help="""Filter to items that overlap a given geometry. Can be a | ||||||
| help="""Filter to items with a given geometry. Can be a | ||||||
| json string, filename, or '-' for stdin.""") | ||||||
| @click.option( | ||||||
| "--geom-relation", | ||||||
| type=click.Choice(["intersects", "contains", "within", "disjoint"]), | ||||||
| help="""Optional geometry search refinement, defaults to intersects. | ||||||
| May also be contains, within, or disjoint.""", | ||||||
| ) | ||||||
| @click.option('--number-in', | ||||||
| type=click.Tuple([types.Field(), types.CommaSeparatedFloat()]), | ||||||
| multiple=True, | ||||||
|
|
@@ -224,6 +224,7 @@ def filter(ctx, | |||||
| asset, | ||||||
| date_range, | ||||||
| geom, | ||||||
| geom_relation, | ||||||
| number_in, | ||||||
| nrange, | ||||||
| string_in, | ||||||
|
|
@@ -245,9 +246,11 @@ def filter(ctx, | |||||
| permission = data_filter.permission_filter() if permission else None | ||||||
| std_quality = data_filter.std_quality_filter() if std_quality else None | ||||||
|
|
||||||
| geometry = data_filter.geometry_filter(geom, geom_relation) | ||||||
|
||||||
| geometry = data_filter.geometry_filter(geom, geom_relation) | |
| geometry = data_filter.geometry_filter(geom, geom_relation) if geom else None |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -218,7 +218,7 @@ def update_filter(field_name: str, | |||||
| callback=_datetime_to_rfc3339) | ||||||
|
|
||||||
|
|
||||||
| def geometry_filter(geom: dict) -> dict: | ||||||
| def geometry_filter(geom: dict, relation: str = None) -> dict: | ||||||
|
||||||
| def geometry_filter(geom: dict, relation: str = None) -> dict: | |
| def geometry_filter(geom: dict, relation: Optional[str] = None) -> dict: |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -173,7 +173,6 @@ def _func(filter1, filter2): | |
| return _func | ||
|
|
||
|
|
||
| @respx.mock | ||
| def test_data_filter_defaults(invoke, assert_and_filters_equal): | ||
|
|
||
| result = invoke(["filter"]) | ||
|
|
@@ -183,7 +182,6 @@ def test_data_filter_defaults(invoke, assert_and_filters_equal): | |
| assert_and_filters_equal(json.loads(result.output), empty_filter) | ||
|
|
||
|
|
||
| @respx.mock | ||
| def test_data_filter_permission(invoke, assert_and_filters_equal): | ||
| result = invoke(["filter", "--permission"]) | ||
| assert result.exit_code == 0 | ||
|
|
@@ -197,7 +195,6 @@ def test_data_filter_permission(invoke, assert_and_filters_equal): | |
| assert_and_filters_equal(json.loads(result.output), expected_filt) | ||
|
|
||
|
|
||
| @respx.mock | ||
| def test_data_filter_std_quality(invoke, assert_and_filters_equal): | ||
| result = invoke(["filter", '--std-quality']) | ||
| assert result.exit_code == 0 | ||
|
|
@@ -230,7 +227,6 @@ def test_data_filter_asset(asset, expected, invoke, assert_and_filters_equal): | |
| assert_and_filters_equal(json.loads(result.output), expected_filt) | ||
|
|
||
|
|
||
| @respx.mock | ||
| def test_data_filter_date_range_success(invoke, assert_and_filters_equal): | ||
| """Check filter is created correctly and that multiple options results in | ||
| multiple filters""" | ||
|
|
@@ -262,13 +258,11 @@ def test_data_filter_date_range_success(invoke, assert_and_filters_equal): | |
| assert_and_filters_equal(json.loads(result.output), expected_filt) | ||
|
|
||
|
|
||
| @respx.mock | ||
| def test_data_filter_date_range_invalid(invoke): | ||
| result = invoke(["filter"] + '--date-range field gt 2021'.split()) | ||
| assert result.exit_code == 2 | ||
|
|
||
|
|
||
| @respx.mock | ||
| @pytest.mark.parametrize("geom_fixture", | ||
| [('geom_geojson'), ('feature_geojson'), | ||
| ('featurecollection_geojson')]) | ||
|
|
@@ -296,7 +290,16 @@ def test_data_filter_geom(geom_fixture, | |
| assert_and_filters_equal(json.loads(result.output), expected_filt) | ||
|
|
||
|
|
||
| @respx.mock | ||
| def test_data_filter_geom_relation(request, invoke): | ||
| geom = request.getfixturevalue("geom_geojson") | ||
| geom_str = json.dumps(geom) | ||
| result = invoke(["filter", f'--geom={geom_str}', '--geom-relation=disjoint']) | ||
| assert result.exit_code == 0 | ||
|
|
||
| and_filter = json.loads(result.output) | ||
| assert and_filter["config"][0]["relation"] == "disjoint" | ||
|
|
||
|
Comment on lines
+293
to
+301
|
||
|
|
||
| def test_data_filter_number_in_success(invoke, assert_and_filters_equal): | ||
|
|
||
| result = invoke(["filter"] + '--number-in field 1'.split() + | ||
|
|
@@ -317,14 +320,12 @@ def test_data_filter_number_in_success(invoke, assert_and_filters_equal): | |
| assert_and_filters_equal(json.loads(result.output), expected_filt) | ||
|
|
||
|
|
||
| @respx.mock | ||
| def test_data_filter_number_in_badparam(invoke, assert_and_filters_equal): | ||
|
|
||
| result = invoke(["filter"] + '--number-in field 1,str'.split()) | ||
| assert result.exit_code == 2 | ||
|
|
||
|
|
||
| @respx.mock | ||
| def test_data_filter_range(invoke, assert_and_filters_equal): | ||
| """Check filter is created correctly, that multiple options results in | ||
| multiple filters, and that floats are processed correctly.""" | ||
|
|
@@ -352,7 +353,6 @@ def test_data_filter_range(invoke, assert_and_filters_equal): | |
| assert_and_filters_equal(json.loads(result.output), expected_filt) | ||
|
|
||
|
|
||
| @respx.mock | ||
| def test_data_filter_string_in(invoke, assert_and_filters_equal): | ||
|
|
||
| result = invoke(["filter"] + '--string-in field foo'.split() + | ||
|
|
@@ -375,7 +375,6 @@ def test_data_filter_string_in(invoke, assert_and_filters_equal): | |
| assert_and_filters_equal(json.loads(result.output), expected_filt) | ||
|
|
||
|
|
||
| @respx.mock | ||
| def test_data_filter_update(invoke, assert_and_filters_equal): | ||
| """Check filter is created correctly and that multiple options results in | ||
| multiple filters""" | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The help text contains redundant information. It states "defaults to intersects" and then repeats "May also be contains, within, or disjoint" which doesn't include intersects in the list. The help text should clarify that intersects is one of the four options and is the default, for example: "Geometry search relation. Options are intersects (default), contains, within, or disjoint."