Repo created
This commit is contained in:
parent
4af19165ec
commit
68073add76
12458 changed files with 12350765 additions and 2 deletions
123
generator/address_parser/tiger_parser.cpp
Normal file
123
generator/address_parser/tiger_parser.cpp
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
#include "tiger_parser.hpp"
|
||||
|
||||
#include "geometry/distance_on_sphere.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace tiger
|
||||
{
|
||||
using namespace strings;
|
||||
|
||||
void ParseGeometry(std::string_view s, std::vector<ms::LatLon> & geom)
|
||||
{
|
||||
std::string_view constexpr prefix = "LINESTRING(";
|
||||
if (!s.ends_with(')') || !s.starts_with(prefix))
|
||||
return;
|
||||
|
||||
s.remove_prefix(prefix.size());
|
||||
s.remove_suffix(1);
|
||||
|
||||
ms::LatLon last;
|
||||
auto const skipPoint = [&last, &geom]()
|
||||
{
|
||||
// Check simple distance (meters) threshold.
|
||||
return !geom.empty() && ms::DistanceOnEarth(geom.back(), last) < 10.0;
|
||||
};
|
||||
|
||||
Tokenize(s, ",", [&](std::string_view s)
|
||||
{
|
||||
auto i = s.find(' ');
|
||||
CHECK(i != std::string_view::npos, (s));
|
||||
|
||||
CHECK(to_double(s.substr(0, i), last.m_lon), (s));
|
||||
CHECK(to_double(s.substr(i + 1), last.m_lat), (s));
|
||||
|
||||
if (!skipPoint())
|
||||
geom.push_back(last);
|
||||
});
|
||||
|
||||
if (skipPoint())
|
||||
{
|
||||
auto & back = geom.back();
|
||||
if (geom.size() == 1)
|
||||
{
|
||||
// Set one middle point address.
|
||||
back = ms::LatLon{(back.m_lat + last.m_lat) / 2.0, (back.m_lon + last.m_lon) / 2.0};
|
||||
}
|
||||
else
|
||||
{
|
||||
// Replace last point.
|
||||
back = last;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
feature::InterpolType ParseInterpolation(std::string_view s)
|
||||
{
|
||||
if (s == "all")
|
||||
return feature::InterpolType::Any;
|
||||
if (s == "odd")
|
||||
return feature::InterpolType::Odd;
|
||||
if (s == "even")
|
||||
return feature::InterpolType::Even;
|
||||
return feature::InterpolType::None;
|
||||
}
|
||||
|
||||
bool ParseLine(std::string_view line, AddressEntry & e)
|
||||
{
|
||||
// from;to;interpolation;street;city;state;postcode;geometry
|
||||
|
||||
// Basic check.
|
||||
if (std::count(line.begin(), line.end(), ';') != 7)
|
||||
return false;
|
||||
|
||||
TokenizeIterator<SimpleDelimiter, std::string_view::const_iterator, true /* KeepEmptyTokens */> it(line.begin(),
|
||||
line.end(), ";");
|
||||
|
||||
e.m_from = *it;
|
||||
++it;
|
||||
e.m_to = *it;
|
||||
++it;
|
||||
e.m_interpol = ParseInterpolation(*it);
|
||||
++it;
|
||||
e.m_street = *it;
|
||||
++it;
|
||||
++it;
|
||||
++it;
|
||||
e.m_postcode = *it;
|
||||
++it;
|
||||
ParseGeometry(*it, e.m_geom);
|
||||
|
||||
if (e.m_interpol == feature::InterpolType::None || e.m_geom.empty())
|
||||
return false;
|
||||
|
||||
// Check and order house numbers.
|
||||
auto const range = e.GetHNRange();
|
||||
if (range == AddressEntry::kInvalidRange)
|
||||
return false;
|
||||
|
||||
if (range.second < range.first)
|
||||
{
|
||||
std::swap(e.m_from, e.m_to);
|
||||
std::reverse(e.m_geom.begin(), e.m_geom.end());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace tiger
|
||||
|
||||
namespace feature
|
||||
{
|
||||
std::string DebugPrint(InterpolType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case InterpolType::None: return "Interpol::None";
|
||||
case InterpolType::Any: return "Interpol::Any";
|
||||
case InterpolType::Odd: return "Interpol::Odd";
|
||||
case InterpolType::Even: return "Interpol::Even";
|
||||
}
|
||||
UNREACHABLE();
|
||||
}
|
||||
} // namespace feature
|
||||
Loading…
Add table
Add a link
Reference in a new issue