always use OSM tags when listed

Signed-off-by: map-per <map-per@gmx.de>
This commit is contained in:
map-per
2025-12-12 12:28:44 +01:00
parent b3fd89d411
commit 16d20f61e4
4 changed files with 51 additions and 27 deletions

View File

@@ -86,7 +86,8 @@ UNIT_TEST(loadConfigFile)
size_t size = translator.GetStorage().size();
LOG(LINFO, ("Size of feature type storage:", size));
ASSERT(size > 1000, ());
ASSERT(size > 1300, ());
ASSERT(size < 1700, ());
}
UNIT_TEST(OsmTagsFromType)
@@ -110,5 +111,5 @@ UNIT_TEST(OsmTagsFromType)
UNIT_TEST(testToFail)
{
ASSERT_FAIL("Don't run further tests-------------------");
ASSERT_FAIL("------------------- Don't run further tests -------------------");
}

View File

@@ -18,8 +18,6 @@ TypeToOSMTranslator::TypeToOSMTranslator(bool initialize)
void TypeToOSMTranslator::LoadConfigFile()
{
LOG(LINFO, ("Loading 'mapcss-mapping.csv' file for TypeToOSMTranslator"));
Platform &p = GetPlatform();
std::unique_ptr<ModelReader> reader = p.GetReader("mapcss-mapping.csv");
ReaderStreamBuf buffer(std::move(reader));
@@ -33,29 +31,31 @@ void TypeToOSMTranslator::LoadFromStream(std::istream & s)
m_storage.clear();
std::string line;
int lineNumber = 0;
while (s.good())
{
++lineNumber;
getline(s, line);
strings::Trim(line);
// skip empty lines, comments and deprecated types
if (line.empty() || line[0] == '#' || line.starts_with("deprecated"))
// skip empty lines, comments, deprecated and moved types
if (line.empty() || line.front() == '#' || line.starts_with("deprecated") ||
line.starts_with("moved") || line.back() != ';')
continue;
std::vector<std::string_view> tokens = strings::Tokenize(line, ";");
ASSERT(tokens.size() >= 2, ("Invalid type definition:", line));
if (tokens.size() < 2)
{
ASSERT(false, ("Invalid feature type definition:", line));
continue;
}
// Get internal feature type
std::vector<std::string_view> typeTokens = strings::Tokenize(tokens[0], "|");
uint32_t type = classif().GetTypeByPathSafe(typeTokens);
if (typeTokens.size() <= 2)
if (tokens.size() == 2)
{
// simple feature type: OSM tags can be derived from type name
ASSERT(!typeTokens.empty(), ("No type name found"));
// Derive OSM tags from type name
ASSERT(typeTokens.size() <= 2, ("OSM tags can not be inferred from name:", line));
OSMTag osmTag;
@@ -74,11 +74,8 @@ void TypeToOSMTranslator::LoadFromStream(std::istream & s)
}
else
{
// complex feature type: OSM tags are listed in the entry
ASSERT(tokens.size() > 2, ("OSM tags not listed for complex feature type: ", line));
// OSM tags are listed in the feature type entry
std::vector<std::string_view> osmTagTokens = strings::Tokenize(tokens[1], ",");
ASSERT(!osmTagTokens.empty(), ("No OSM tag tokens found"));
// First entry is the best practice way to tag a feature
std::string_view osmTagList = osmTagTokens[0];
@@ -87,36 +84,62 @@ void TypeToOSMTranslator::LoadFromStream(std::istream & s)
std::vector<OSMTag> osmTags;
size_t pos = 0;
while ((pos = osmTagList.find('[', pos)) != std::string::npos) {
while ((pos = osmTagList.find('[', pos)) != std::string::npos)
{
size_t end = osmTagList.find(']', pos);
ASSERT(end != std::string::npos, ("Bracket not closed in OSM tag: ", line));
if (end == std::string::npos)
{
ASSERT(false, ("Bracket not closed in OSM tag:", line));
break;
}
std::string_view keyValuePair = osmTagList.substr(pos + 1, end - pos - 1);
size_t equalSign = keyValuePair.find('=');
if (keyValuePair.empty()) {
ASSERT(false, ("Key value pair is empty:", line));
break;
}
// Skip entries that are not in key=value format
if (equalSign != std::string::npos) {
size_t equalSign = keyValuePair.find('=');
if (equalSign != std::string::npos)
{
OSMTag osmTag;
osmTag.key = keyValuePair.substr(0, equalSign);
osmTag.value = keyValuePair.substr(equalSign + 1);
osmTags.push_back(osmTag);
}
else if (keyValuePair.front() == '!')
{
// Tags with "forbidden" selector '!' are skipped
}
else
{
// Tags with optional "mandatory" selector '?'
if (keyValuePair.back() == '?')
keyValuePair.remove_suffix(1);
OSMTag osmTag;
osmTag.key = keyValuePair;
osmTag.value = "yes";
osmTags.push_back(osmTag);
}
pos = end + 1;
}
ASSERT(!osmTags.empty(), ("No OSM tags found for feature:", line));
m_storage.insert({type, osmTags});
}
}
}
std::vector<OSMTag> TypeToOSMTranslator::OsmTagsFromType(uint32_t type) const
std::vector<OSMTag> const & TypeToOSMTranslator::OsmTagsFromType(uint32_t type) const
{
LOG(LINFO, ("Computing OsmTagsFromType for Type: ", type, "/ " , classif().GetReadableObjectName(type)));
auto it = m_storage.find(type);
if (it == m_storage.end())

View File

@@ -21,7 +21,7 @@ public:
void LoadConfigFile();
void LoadFromStream(std::istream & s);
std::vector<OSMTag> OsmTagsFromType(uint32_t type) const;
std::vector<OSMTag> const & OsmTagsFromType(uint32_t type) const;
std::map<uint32_t, std::vector<OSMTag>> const & GetStorage() const { return m_storage; }

View File

@@ -648,7 +648,7 @@ void XMLFeature::SetOSMTagsForType(uint32_t type)
return;
}
std::vector<OSMTag> osmTags = GetOSMTranslator().OsmTagsFromType(type);
std::vector<OSMTag> const & osmTags = GetOSMTranslator().OsmTagsFromType(type);
for(auto const & osmTag : osmTags)
SetTagValue(osmTag.key, osmTag.value);