| 1360 | } |
| 1361 | |
| 1362 | void Geocoder::MatchPOIsAndBuildings(BaseContext & ctx, size_t curToken, CBV const & filter) |
| 1363 | { |
| 1364 | TRACE(MatchPOIsAndBuildings); |
| 1365 | |
| 1366 | BailIfCancelled(); |
| 1367 | |
| 1368 | auto & layers = ctx.m_layers; |
| 1369 | |
| 1370 | size_t const numTokens = ctx.NumTokens(); |
| 1371 | curToken = ctx.SkipUsedTokens(curToken); |
| 1372 | if (curToken == numTokens) |
| 1373 | { |
| 1374 | // All tokens were consumed, find paths through layers, emit features. |
| 1375 | if (m_postcodes.IsEmpty() || CityHasPostcode(ctx)) |
| 1376 | return FindPaths(ctx); |
| 1377 | |
| 1378 | // When there are no layers but user entered a postcode, we have |
| 1379 | // to emit all features matching to the postcode. |
| 1380 | if (layers.size() == 0) |
| 1381 | { |
| 1382 | CBV filtered = m_postcodes.m_countryFeatures; |
| 1383 | if (m_filter->NeedToFilter(m_postcodes.m_countryFeatures)) |
| 1384 | filtered = m_filter->Filter(m_postcodes.m_countryFeatures); |
| 1385 | filtered.ForEach([&](uint64_t bit) |
| 1386 | { |
| 1387 | auto const featureId = base::asserted_cast<uint32_t>(bit); |
| 1388 | Model::Type type; |
| 1389 | if (GetTypeInGeocoding(ctx, featureId, type)) |
| 1390 | { |
| 1391 | EmitResult(ctx, {m_context->GetId(), featureId}, type, m_postcodes.m_tokenRange, nullptr /* geoParts */, |
| 1392 | true /* allTokensUsed */, true /* exactMatch */); |
| 1393 | } |
| 1394 | }); |
| 1395 | return; |
| 1396 | } |
| 1397 | |
| 1398 | if (!(layers.size() == 1 && layers[0].m_type == Model::TYPE_STREET)) |
| 1399 | return FindPaths(ctx); |
| 1400 | |
| 1401 | // If there's only one street layer but user also entered a |
| 1402 | // postcode, we need to emit all features matching to postcode on |
| 1403 | // the given street, including the street itself. |
| 1404 | |
| 1405 | // Following code emits streets matched by postcodes, because |
| 1406 | // GreedilyMatchStreets() doesn't (and shouldn't) perform |
| 1407 | // postcodes matching. |
| 1408 | { |
| 1409 | for (auto const & id : *layers.back().m_sortedFeatures) |
| 1410 | { |
| 1411 | if (!m_postcodes.Has(id)) |
| 1412 | continue; |
| 1413 | EmitResult(ctx, {m_context->GetId(), id}, Model::TYPE_STREET, layers.back().m_tokenRange, |
| 1414 | nullptr /* geoParts */, true /* allTokensUsed */, true /* exactMatch */); |
| 1415 | } |
| 1416 | } |
| 1417 | |
| 1418 | // Following code creates a fake TYPE_BUILDING layer and intersects it with the streets layer. |
| 1419 | // Controversial: we can emit streets like buildings here. Filtered in IsFakeBuildingButStreet(). |
nothing calls this directly
no test coverage detected