| 1870 | } |
| 1871 | |
| 1872 | FeatureID Framework::GetFeatureAtPoint(m2::PointD const & mercator, FeatureMatcher && matcher /* = nullptr */) const |
| 1873 | { |
| 1874 | FeatureID fullMatch, poi, line, area; |
| 1875 | auto haveBuilding = false; |
| 1876 | auto closestDistanceToCenter = numeric_limits<double>::max(); |
| 1877 | auto currentDistance = numeric_limits<double>::max(); |
| 1878 | |
| 1879 | indexer::ForEachFeatureAtPoint(m_featuresFetcher.GetDataSource(), [&](FeatureType & ft) |
| 1880 | { |
| 1881 | if (fullMatch.IsValid()) |
| 1882 | return; |
| 1883 | |
| 1884 | if (matcher && matcher(ft)) |
| 1885 | { |
| 1886 | fullMatch = ft.GetID(); |
| 1887 | return; |
| 1888 | } |
| 1889 | |
| 1890 | switch (ft.GetGeomType()) |
| 1891 | { |
| 1892 | case feature::GeomType::Point: poi = ft.GetID(); break; |
| 1893 | case feature::GeomType::Line: |
| 1894 | // Skip/ignore isolines. |
| 1895 | if (ftypes::IsIsolineChecker::Instance()(ft)) |
| 1896 | return; |
| 1897 | line = ft.GetID(); |
| 1898 | break; |
| 1899 | case feature::GeomType::Area: |
| 1900 | { |
| 1901 | // Buildings have higher priority over other types. |
| 1902 | if (haveBuilding) |
| 1903 | return; |
| 1904 | |
| 1905 | // Skip/ignore coastlines. |
| 1906 | feature::TypesHolder types(ft); |
| 1907 | if (ftypes::IsCoastlineChecker::Instance()(types)) |
| 1908 | return; |
| 1909 | |
| 1910 | haveBuilding = ftypes::IsBuildingChecker::Instance()(types); |
| 1911 | currentDistance = mercator::DistanceOnEarth(mercator, feature::GetCenter(ft)); |
| 1912 | // Choose the first matching building or, if no buildings are matched, |
| 1913 | // the first among the closest matching non-buildings. |
| 1914 | if (!haveBuilding && currentDistance >= closestDistanceToCenter) |
| 1915 | return; |
| 1916 | |
| 1917 | area = ft.GetID(); |
| 1918 | closestDistanceToCenter = currentDistance; |
| 1919 | break; |
| 1920 | } |
| 1921 | case feature::GeomType::Undefined: ASSERT(false, ("case feature::Undefined")); break; |
| 1922 | } |
| 1923 | }, mercator); |
| 1924 | |
| 1925 | return fullMatch.IsValid() ? fullMatch : (poi.IsValid() ? poi : (line.IsValid() ? line : area)); |
| 1926 | } |
| 1927 | |
| 1928 | osm::MapObject Framework::GetMapObjectByID(FeatureID const & fid) const |
| 1929 | { |