File indexing completed on 2024-04-21 03:54:30
0001 /* 0002 SPDX-FileCopyrightText: 2021 Volker Krause <vkrause@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "data/spatial_index_data.cpp" 0008 #include "data/spatial_index_parameters_p.h" 0009 #include "data/spatial_index_properties.cpp" 0010 #include "spatial_index_p.h" 0011 0012 #include <cmath> 0013 #include <cstdint> 0014 0015 constexpr const float XEnd = XStart + XRange; 0016 constexpr const float YEnd = YStart + YRange; 0017 0018 // verify the null entry is first in the property table 0019 static_assert(spatial_index_properties[0].m_tz == Tz::Undefined); 0020 static_assert(spatial_index_properties[0].m_subdiv == 0); 0021 0022 // z index conversions 0023 constexpr uint32_t latlonToZ(float lat, float lon) 0024 { 0025 const uint32_t x = ((lon - XStart) / XRange) * (1 << ZDepth); 0026 const uint32_t y = ((lat - YStart) / YRange) * (1 << ZDepth); 0027 uint32_t z = 0; 0028 for (int i = ZDepth - 1; i >= 0; --i) { 0029 z <<= 1; 0030 z += (y & (1 << i)) ? 1 : 0; 0031 z <<= 1; 0032 z += (x & (1 << i)) ? 1 : 0; 0033 } 0034 return z; 0035 } 0036 0037 // "unit tests" for the z index conversion 0038 static_assert(latlonToZ(YStart, XStart) == 0); 0039 static_assert(latlonToZ(YEnd - 1.0f / (1 << ZDepth), XEnd - 1.0f / (1 << ZDepth)) == (1 << (2 * ZDepth)) - 1); 0040 static_assert(latlonToZ(YStart + YRange / 2.0f, 0.0f) == ((1 << (2 * ZDepth - 1)) | (1 << (2 * ZDepth - 2)))); 0041 0042 SpatialIndexProperty SpatialIndex::lookup(float lat, float lon) 0043 { 0044 if (std::isnan(lat) || std::isnan(lon) || lon < XStart || lon >= XEnd || lat < YStart || lat >= YEnd) { 0045 return spatial_index_properties[0]; 0046 } 0047 0048 const auto z = latlonToZ(lat, lon); 0049 const auto it = std::upper_bound(std::begin(spatial_index), std::end(spatial_index), z); 0050 if (it == std::begin(spatial_index)) { 0051 return spatial_index_properties[0]; 0052 } 0053 0054 return spatial_index_properties[(*std::prev(it)).propertyIndex()]; 0055 }