MCPcopy Create free account
hub / github.com/comaps/comaps / WithPostcodes

Method WithPostcodes

libs/search/geocoder.cpp:1114–1185  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1112
1113template <typename Fn>
1114void Geocoder::WithPostcodes(BaseContext & ctx, Fn && fn)
1115{
1116 TRACE(WithPostcodes);
1117
1118 size_t const maxPostcodeTokens = GetMaxNumTokensInPostcode();
1119 auto worldContext = GetWorldContext(m_dataSource);
1120
1121 size_t const numTokens = ctx.NumTokens();
1122 for (size_t startToken = 0; startToken != numTokens; ++startToken)
1123 {
1124 size_t endToken = startToken;
1125 for (size_t n = 1; startToken + n <= numTokens && n <= maxPostcodeTokens; ++n)
1126 {
1127 if (ctx.IsTokenUsed(startToken + n - 1))
1128 break;
1129
1130 TokenSlice slice(m_params, TokenRange(startToken, startToken + n));
1131 auto const isPrefix = startToken + n == numTokens;
1132 if (LooksLikePostcode(QuerySlice(slice), isPrefix))
1133 endToken = startToken + n;
1134 }
1135 if (startToken == endToken)
1136 continue;
1137
1138 TokenRange const tokenRange(startToken, endToken);
1139
1140 // Find features by exact postcode match from OSM data.
1141 auto postcodes = RetrievePostcodeFeatures(*m_context, TokenSlice(m_params, tokenRange));
1142
1143 // Get _around postcode_ features from additional _external postcodes_ section.
1144 // Do not emit _around postcode_ only features if we don't have some other tokens to match (avoid lags).
1145 if (tokenRange.Size() < numTokens && m_context->m_value.m_cont.IsExist(POSTCODE_POINTS_FILE_TAG))
1146 {
1147 auto & postcodePoints = m_postcodePointsCache.Get(*m_context);
1148 UniString postcodeQuery;
1149 JoinQueryTokens(m_params, tokenRange, UniString::kSpace /* sep */, postcodeQuery);
1150 vector<m2::PointD> points;
1151 postcodePoints.Get(postcodeQuery, points);
1152
1153 // PostcodePoints::Get returns many points for "BN1" or one point for "BN1 3LJ".
1154 // Do aggregate rects for a _wide_ postcode prefix match.
1155 m2::RectD rect;
1156 for (auto const & p : points)
1157 rect.Add(mercator::RectByCenterXYAndOffset(p, postcodePoints.GetRadius()));
1158
1159 postcodes = postcodes.Union(RetrieveGeometryFeatures(*m_context, rect, RectId::Postcode));
1160 }
1161
1162 SCOPE_GUARD(cleanup, [&]() { m_postcodes.Clear(); });
1163
1164 if (!postcodes.IsEmpty())
1165 {
1166 ScopedMarkTokens mark(ctx.m_tokens, BaseContext::TOKEN_TYPE_POSTCODE, tokenRange);
1167
1168 m_postcodes.Clear();
1169
1170 if (worldContext)
1171 m_postcodes.m_worldFeatures = RetrievePostcodeFeatures(*worldContext, TokenSlice(m_params, tokenRange));

Callers

nothing calls this directly

Calls 15

GetWorldContextFunction · 0.85
LooksLikePostcodeFunction · 0.85
QuerySliceClass · 0.85
JoinQueryTokensFunction · 0.85
RectByCenterXYAndOffsetFunction · 0.85
NumTokensMethod · 0.80
IsTokenUsedMethod · 0.80
IsExistMethod · 0.80
AllTokensUsedMethod · 0.80
TokenRangeClass · 0.70
TokenSliceClass · 0.70

Tested by

no test coverage detected