Skip to content
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

(Reverse) Geocoding: Filter out unwanted types #769

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion include/motis/endpoints/adr/suggestions_to_response.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ api::geocode_response suggestions_to_response(
platform_matches_t const* matches,
std::basic_string<adr::language_idx_t> const& lang_indices,
std::vector<adr::token> const& token_pos,
std::vector<adr::suggestion> const&);
std::vector<adr::suggestion> const&,
std::optional<api::LocationTypeEnum> const& ty);

} // namespace motis
35 changes: 29 additions & 6 deletions openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,16 @@ paths:
description: latitude, longitude in degrees
schema:
type: string
- name: filterType
in: query
required: false
description: |
Optional. Default is all types.

Only return results of the given types.
For example, this can be used to allow only `ADDRESS` and `STOP` results.
schema:
$ref: '#/components/schemas/LocationType'
responses:
200:
description: A list of guesses to resolve the coordinates to a location
Expand Down Expand Up @@ -121,6 +131,16 @@ paths:
(usually ISO 639-1, or ISO 639-2 if there's no ISO 639-1)
schema:
type: string
- name: filterType
in: query
required: false
description: |
Optional. Default is all types.

Only return results of the given types.
For example, this can be used to allow only `ADDRESS` and `STOP` results.
schema:
$ref: '#/components/schemas/LocationType'

responses:
200:
Expand Down Expand Up @@ -1097,6 +1117,14 @@ components:
items:
type: number

LocationType:
description: location type
type: string
enum:
- ADDRESS
- PLACE
- STOP

Match:
description: GeoCoding match
type: object
Expand All @@ -1111,12 +1139,7 @@ components:
- score
properties:
type:
description: location type
type: string
enum:
- ADDRESS
- PLACE
- STOP
$ref: '#/components/schemas/LocationType'
tokens:
description: list of non-overlapping tokens that were matched
type: array
Expand Down
21 changes: 17 additions & 4 deletions src/endpoints/adr/geocode.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@ a::guess_context& get_guess_context(a::typeahead const& t, a::cache& cache) {
return *ctx;
}

api::geocode_response geocode::operator()(
boost::urls::url_view const& url) const {
api::geocode_response geocode::operator()(boost::urls::url_view const& url) const {
auto const params = api::geocode_params{url.params()};

auto& ctx = get_guess_context(t_, cache_);
Expand All @@ -41,12 +40,26 @@ api::geocode_response geocode::operator()(
lang_indices.push_back(l_idx);
}
}
auto filter = a::filter_type::kNone;
if (params.filterType_.has_value()) {
switch (*params.filterType_) {
case api::LocationTypeEnum::ADDRESS:
filter = a::filter_type::kAddress;
break;
case api::LocationTypeEnum::PLACE:
filter = a::filter_type::kPlace;
break;
case api::LocationTypeEnum::STOP:
filter = a::filter_type::kExtra;
break;
}
}

auto const token_pos = a::get_suggestions<false>(
t_, geo::latlng{0, 0}, params.text_, 10U, lang_indices, ctx);
t_, geo::latlng{0, 0}, params.text_, 10U, lang_indices, ctx, filter);

return suggestions_to_response(t_, tt_, tags_, w_, pl_, matches_,
lang_indices, token_pos, ctx.suggestions_);
lang_indices, token_pos, ctx.suggestions_, params.filterType_);
}

} // namespace motis::ep
18 changes: 17 additions & 1 deletion src/endpoints/adr/reverse_geocode.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,30 @@
#include "motis/endpoints/adr/suggestions_to_response.h"
#include "motis/parse_location.h"

namespace a = adr;

namespace motis::ep {

api::reverseGeocode_response reverse_geocode::operator()(
boost::urls::url_view const& url) const {
auto const params = api::reverseGeocode_params{url.params()};
auto filter = a::filter_type::kNone;
if (params.filterType_.has_value()) {
switch (*params.filterType_) {
case api::LocationTypeEnum::ADDRESS:
filter = a::filter_type::kAddress;
break;
case api::LocationTypeEnum::PLACE:
filter = a::filter_type::kPlace;
break;
case api::LocationTypeEnum::STOP:
filter = a::filter_type::kExtra;
break;
}
}
return suggestions_to_response(
t_, tt_, tags_, w_, pl_, matches_, {}, {},
r_.lookup(t_, parse_location((params.place_))->pos_, 5U));
r_.lookup(t_, parse_location((params.place_))->pos_, 5U, filter), {});
}

} // namespace motis::ep
31 changes: 24 additions & 7 deletions src/endpoints/adr/suggestions_to_response.cc
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,25 @@ api::geocode_response suggestions_to_response(
platform_matches_t const* matches,
std::basic_string<a::language_idx_t> const& lang_indices,
std::vector<adr::token> const& token_pos,
std::vector<adr::suggestion> const& suggestions) {
return utl::to_vec(suggestions, [&](a::suggestion const& s) {
std::vector<adr::suggestion> const& suggestions,
std::optional<api::LocationTypeEnum> const& ty) {
auto s_ = suggestions;
if (ty != std::nullopt) {
s_.erase(
std::remove_if(s_.begin(), s_.end(), [&](const a::suggestion& s) {
return ty != std::visit(utl::overloaded{
[&](a::place_idx_t const p) {
return t.place_type_[p] == a::place_type::kExtra
? api::LocationTypeEnum::STOP
: api::LocationTypeEnum::PLACE;
},
[&](a::address const) { return api::LocationTypeEnum::ADDRESS; },
}, s.location_);
}),
s_.end());
}

return utl::to_vec(s_, [&](a::suggestion const& s) {
auto const areas = t.area_sets_[s.area_set_];

auto const zip_it = utl::find_if(
Expand All @@ -63,7 +80,7 @@ api::geocode_response suggestions_to_response(
auto const city_idx = static_cast<std::size_t>(
city_it == end(areas) ? -1 : std::distance(begin(areas), city_it));

auto type = api::typeEnum{};
auto type = api::LocationTypeEnum{};
auto street = std::optional<std::string>{};
auto house_number = std::optional<std::string>{};
auto id = std::string{};
Expand All @@ -72,9 +89,9 @@ api::geocode_response suggestions_to_response(
utl::overloaded{
[&](a::place_idx_t const p) {
type = t.place_type_[p] == a::place_type::kExtra
? api::typeEnum::STOP
: api::typeEnum::PLACE;
if (type == api::typeEnum::STOP) {
? api::LocationTypeEnum::STOP
: api::LocationTypeEnum::PLACE;
if (type == api::LocationTypeEnum::STOP) {
if (tt != nullptr && tags != nullptr) {
auto const l = n::location_idx_t{t.place_osm_ids_[p]};
level = get_level(w, pl, matches, l);
Expand All @@ -90,7 +107,7 @@ api::geocode_response suggestions_to_response(
return std::string{t.strings_[s.str_].view()};
},
[&](a::address const addr) {
type = api::typeEnum::ADDRESS;
type = api::LocationTypeEnum::ADDRESS;
if (addr.house_number_ != a::address::kNoHouseNumber) {
street = t.strings_[s.str_].view();
house_number = t.strings_[t.house_numbers_[addr.street_]
Expand Down