bool OsmAnd::MapStyle_P::registerRule( MapStyleRulesetType type, const std::shared_ptr<MapStyleRule>& rule ) { MapStyleValue tagData; if(!rule->getAttribute(_builtinValueDefs->INPUT_TAG, tagData)) { OsmAnd::LogPrintf(OsmAnd::LogSeverityLevel::Error, "Attribute tag should be specified for root filter"); return false; } MapStyleValue valueData; if(!rule->getAttribute(_builtinValueDefs->INPUT_VALUE, valueData)) { OsmAnd::LogPrintf(OsmAnd::LogSeverityLevel::Error, "Attribute tag should be specified for root filter"); return false; } uint64_t id = encodeRuleId(tagData.asSimple.asUInt, valueData.asSimple.asUInt); auto insertedRule = rule; auto& ruleset = obtainRulesRef(type); auto itPrevious = ruleset.constFind(id); if(itPrevious != ruleset.cend()) { // all root rules should have at least tag/value insertedRule = createTagValueRootWrapperRule(id, *itPrevious); insertedRule->_d->_ifElseChildren.push_back(rule); } ruleset.insert(id, qMove(insertedRule)); return true; }
void RenderingRulesStorage::parseRulesFromXmlInputStream(const char* filename, RenderingRulesStorageResolver* resolver) { XML_Parser parser = XML_ParserCreate(NULL); RenderingRulesHandler* handler = new RenderingRulesHandler(resolver, this); XML_SetUserData(parser, handler); XML_SetElementHandler(parser, RenderingRulesHandler::startElementHandler, RenderingRulesHandler::endElementHandler); FILE *file = fopen(filename, "r"); if (file == NULL) { osmand_log_print(LOG_ERROR, "File can not be open %s", filename); return; } char buffer[512]; bool done = false; while (!done) { fgets(buffer, sizeof(buffer), file); int len = strlen(buffer); if (feof(file) != 0) { done = true; } if (XML_Parse(parser, buffer, len, done) == XML_STATUS_ERROR) { return; } } RenderingRulesStorage* depends = handler->getDependsStorage(); if (depends != NULL) { // merge results // dictionary and props are already merged map<std::string, RenderingRule*>::iterator it = depends->renderingAttributes.begin(); for(;it != depends->renderingAttributes.end(); it++) { map<std::string, RenderingRule*>::iterator o = renderingAttributes.find(it->first); if (o != renderingAttributes.end()) { std::vector<RenderingRule*>::iterator list = it->second->ifElseChildren.begin(); for (;list != it->second->ifElseChildren.end(); list++) { o->second->ifElseChildren.push_back(*list); } } else { renderingAttributes[it->first] = it->second; } } for (int i = 0; i < SIZE_STATES; i++) { if (depends->tagValueGlobalRules[i].empty()) { continue; } HMAP::hash_map<int, RenderingRule*>::iterator it = depends->tagValueGlobalRules[i].begin(); for (; it != depends->tagValueGlobalRules[i].end(); it++) { HMAP::hash_map<int, RenderingRule*>::iterator o = tagValueGlobalRules[i].find(it->first); RenderingRule* toInsert = it->second; if (o != tagValueGlobalRules[i].end()) { toInsert = createTagValueRootWrapperRule(it->first, o->second); toInsert->ifElseChildren.push_back(it->second); } tagValueGlobalRules[i][it->first] = toInsert; } } } }
void RenderingRulesStorage::registerGlobalRule(RenderingRule* rr, int state) { int tag = rr->getIntPropertyValue(this->PROPS.R_TAG->attrName); if (tag == -1) { osmand_log_print(LOG_ERROR, "Attribute tag should be specified for root filter "); } int value = rr->getIntPropertyValue(this->PROPS.R_VALUE->attrName); if (value == -1) { // attrsMap.toString() osmand_log_print(LOG_ERROR, "Attribute tag should be specified for root filter "); } int key = (tag << SHIFT_TAG_VAL) + value; RenderingRule* toInsert = rr; RenderingRule* previous = tagValueGlobalRules[state][key]; if (previous != NULL) { // all root rules should have at least tag/value toInsert = createTagValueRootWrapperRule(key, previous); toInsert->ifElseChildren.push_back(rr); } tagValueGlobalRules[state][key] = toInsert; }
bool OsmAnd::MapStyle_P::mergeInheritedRules( MapStyleRulesetType type ) { if(!_parent) return true; const auto& parentRules = _parent->_d->obtainRulesRef(type); auto& rules = obtainRulesRef(type); for(auto itParentRule = parentRules.cbegin(); itParentRule != parentRules.cend(); ++itParentRule) { auto itLocalRule = rules.constFind(itParentRule.key()); auto toInsert = itParentRule.value(); if(itLocalRule != rules.cend()) { toInsert = createTagValueRootWrapperRule(itParentRule.key(), *itLocalRule); toInsert->_d->_ifElseChildren.push_back(itParentRule.value()); } rules.insert(itParentRule.key(), toInsert); } return true; }