void EndElement(const xmlChar *name) { if (strcmp((const char*)name,"node")==0) { callback.ProcessNode(id, lon, lat, tags); tags.clear(); context=contextUnknown; } else if (strcmp((const char*)name,"way")==0) { callback.ProcessWay(id, nodes, tags); nodes.clear(); tags.clear(); context=contextUnknown; } else if (strcmp((const char*)name,"relation")==0) { callback.ProcessRelation(id, members, tags); members.clear(); tags.clear(); context=contextUnknown; } }
std::vector<Stage *> PipelineReaderJSON::extractInputs(Json::Value& node, TagMap& tags) { std::vector<Stage *> inputs; std::string filename; if (node.isMember("inputs")) { Json::Value& val = node["filename"]; if (!val.isNull()) { for (const Json::Value& input : node["inputs"]) { if (input.isString()) { std::string tag = input.asString(); auto ii = tags.find(tag); if (ii == tags.end()) throw pdal_error("JSON pipeline: Invalid pipeline: " "undefined stage tag '" + tag + "'."); else inputs.push_back(ii->second); } else throw pdal_error("JSON pipeline: 'inputs' tag must " " be specified as a string."); } } node.removeMember("inputs"); if (node.isMember("inputs")) throw pdal_error("JSON pipeline: found duplicate 'inputs' " "entry in stage definition."); } return inputs; }
std::string PipelineReaderJSON::extractTag(Json::Value& node, TagMap& tags) { std::string tag; if (node.isMember("tag")) { Json::Value& val = node["tag"]; if (!val.isNull()) { if (val.isString()) { tag = val.asString(); if (tags.find(tag) != tags.end()) throw pdal_error("JSON pipeline: duplicate tag '" + tag + "'."); } else throw pdal_error("JSON pipeline: tag must be " "specified as a string."); } node.removeMember("tag"); if (node.isMember("tag")) throw pdal_error("JSON pipeline: found duplicate 'tag' " "entry in stage definition."); std::string::size_type pos = 0; if (!Stage::parseTagName(tag, pos) || pos != tag.size()) throw pdal_error("JSON pipeline: Invalid tag name '" + tag + "'. " "Must start with letter. Remainder can be letters, " "digits or underscores."); } return tag; }
void PrintTagMap(const TagMap &tagMap) { for(TagMap::const_iterator it = tagMap.begin(); it != tagMap.end(); it++) { std::cout << it->first << "=" << it->second << std::endl; } }
std::string PipelineReaderJSON::extractTag(Json::Value& node, TagMap& tags) { std::string tag; if (node.isMember("tag")) { Json::Value& val = node["tag"]; if (!val.isNull()) { if (val.isString()) { tag = val.asString(); if (tags.find(tag) != tags.end()) throw pdal_error("JSON pipeline: duplicate tag '" + tag + "'."); } else throw pdal_error("JSON pipeline: 'tag' must be " "specified as a string."); } node.removeMember("tag"); if (node.isMember("tag")) throw pdal_error("JSON pipeline: found duplicate 'tag' " "entry in stage definition."); } return tag; }
void O5mEncodeBase::StoreNode(int64_t objId, const class MetaData &metaData, const TagMap &tags, double latIn, double lonIn) { this->write("\x10",1); //Object ID std::stringstream tmpStream; int64_t deltaId = objId - this->lastObjId; tmpStream << EncodeZigzag(deltaId); this->lastObjId = objId; this->EncodeMetaData(metaData, tmpStream); //Position int64_t lon = round(lonIn * 1e7); int64_t deltaLon = lon - this->lastLon; tmpStream << EncodeZigzag(deltaLon); this->lastLon = lon; int64_t lat = round(latIn * 1e7); int64_t deltaLat = lat - this->lastLat; tmpStream << EncodeZigzag(deltaLat); this->lastLat = lat; for (TagMap::const_iterator it=tags.begin(); it != tags.end(); it++) this->WriteStringPair(it->first, it->second, tmpStream); std::string binData = tmpStream.str(); std::string len = EncodeVarint(binData.size()); *this << len; *this << binData; }
void OsmXmlEncodeBase::StoreRelation(int64_t objId, const class MetaData &metaData, const TagMap &tags, const std::vector<std::string> &refTypeStrs, const std::vector<int64_t> &refIds, const std::vector<std::string> &refRoles) { if(refTypeStrs.size() != refIds.size() || refTypeStrs.size() != refRoles.size()) throw std::invalid_argument("Length of ref vectors must be equal"); stringstream ss; ss << " <relation id=\""<<objId<<"\""; this->EncodeMetaData(metaData, ss); if(tags.size() == 0 && refTypeStrs.size() == 0) ss <<" />" << endl; else { ss <<">" << endl; //Write node IDs for(size_t i=0; i<refTypeStrs.size(); i++) ss << " <member type=\""<<escapexml(refTypeStrs[i])<<"\" ref=\""<<refIds[i]<<"\" role=\""<<escapexml(refRoles[i])<<"\" />" << endl; //Write tags for(TagMap::const_iterator it=tags.begin(); it!=tags.end(); it++) ss << " <tag k=\""<<escapexml(it->first)<<"\" v=\""<<escapexml(it->second)<<"\" />" << endl; ss << " </relation>" << endl; } *this << ss.str(); }
void PipelineReaderJSON::handleInputTag(const std::string& tag, const TagMap& tags, std::vector<Stage *>& inputs) { auto ii = tags.find(tag); if (ii == tags.end()) throw pdal_error("JSON pipeline: Invalid pipeline: " "undefined stage tag '" + tag + "'."); else inputs.push_back(ii->second); }
bool TagIsInCondition::Evaluate(const TagMap& tagMap) const { auto t=tagMap.find(tag); if (t==tagMap.end()) { return false; } return tagValues.find(t->second)!=tagValues.end(); }
size_t GenericHeader::read(IDataReader &reader) { size_t bufLen = 1024 * 32; DataBuffer buf(bufLen, ALIGNMENT); size_t numBytesRead = reader.getData(buf.getFree(), bufLen); buf.moveFreeToData(numBytesRead); if (numBytesRead < 4 /* magic */ + 4 /* size */) { throw IllegalHeaderException("Failed to read header info."); } uint32_t magic = buf.readInt32(); if (magic != MAGIC) { throw IllegalHeaderException("Failed to verify magic bits."); } uint32_t numBytesTotal = buf.readInt32(); if (numBytesTotal == 0) { throw IllegalHeaderException("Failed to read header size."); } if (numBytesTotal < getMinSize()) { throw IllegalHeaderException("Failed to verify header size."); } if (numBytesRead < numBytesTotal) { LOG(debug, "Read %d of %d header bytes, performing backfill.", (uint32_t)numBytesRead, numBytesTotal); uint32_t numBytesRemain = numBytesTotal - numBytesRead; buf.ensureFree(numBytesRemain); LOG(debug, "Reading remaining %d bytes of header.", numBytesRemain); numBytesRead += reader.getData(buf.getFree(), numBytesRemain); if (numBytesRead != numBytesTotal) { throw IllegalHeaderException("Failed to read full header."); } buf.moveFreeToData(numBytesRemain); } else { buf.moveDataToFree(numBytesRead - numBytesTotal); } uint32_t version = buf.readInt32(); if (version != VERSION) { throw IllegalHeaderException("Failed to verify header version."); } uint32_t numTags = buf.readInt32(); TagMap tags; for (uint32_t i = 0; i < numTags; ++i) { Tag tag; tag.read(buf); tags.insert(TagMap::value_type(tag.getName(), tag)); } _tags.swap(tags); return numBytesTotal; }
std::string ImportErrorReporter::GetName(const ObjectOSMRef& object, const TagMap& tags) const { std::stringstream buffer; buffer << object.GetName(); if (nameTagId!=tagIgnore) { const auto entry=tags.find(nameTagId); if (entry!=tags.end()) { buffer << " \"" << entry->second << "\""; } } return buffer.str(); }
bool Preprocess::Callback::IsMultipolygon(const TagMap& tags, TypeInfoRef& type) { type=typeConfig->GetRelationType(tags); if (type!=typeConfig->typeInfoIgnore && type->GetIgnore()) { return false; } bool isArea=type!=typeConfig->typeInfoIgnore && type->GetMultipolygon(); if (!isArea) { auto typeTag=tags.find(typeConfig->tagType); isArea=typeTag!=tags.end() && typeTag->second=="multipolygon"; } return isArea; }
void QFieldDefinitionData::init(TagMap &tagMap, FieldMap &fieldMap, ActionMap &actionMap, QTranslatableSettings &config) { QList<QFieldDefinition> fields; QMap<QString, QFieldAction> actions; fields = QFieldDefinitionData::readFields(config); actions = QFieldDefinitionData::readActions(config); foreach(QFieldDefinition def, fields) { if (!fieldMap.contains(def.id())) { fieldMap.insert(def.id(), def); QStringList tags = def.tags(); foreach(QString tag, tags) { QSet<QString> taggedFields; if (tagMap.contains(tag)) taggedFields = tagMap.value(tag); taggedFields.insert(def.id()); tagMap.insert(tag, taggedFields); } }
// --------------------------------------------------------------------------- // EnvelopeReader Find // --------------------------------------------------------------------------- // May return NULL if no reader with the specified owner and index // is found. // const EnvelopeReader * EnvelopeReader::Find( INSDS * owner, int idx ) { TagMap & readers = Tags(); TagMap::iterator it = readers.find( Tag( owner, idx ) ); if ( it != readers.end() ) { #ifdef DEBUG_LORISGENS std::cerr << "** found EnvelopeReader with owner " << owner << " and index " << idx; std::cerr << " having " << it->second->size() << " envelopes." << std::endl; #endif return it->second; } else { #ifdef DEBUG_LORISGENS std::cerr << "** could not find EnvelopeReader with owner " << owner << " and index " << idx << std::endl; #endif return NULL; } }
bool Preprocess::Callback::IsTurnRestriction(const TagMap& tags, TurnRestriction::Type& type) const { auto typeValue=tags.find(typeConfig->tagType); if (typeValue==tags.end()) { return false; } if (typeValue->second!="restriction") { return false; } auto restrictionValue=tags.find(typeConfig->tagRestriction); if (restrictionValue==tags.end()) { return false; } type=TurnRestriction::Allow; if (restrictionValue->second=="only_left_turn" || restrictionValue->second=="only_right_turn" || restrictionValue->second=="only_straight_on") { type=TurnRestriction::Allow; return true; } else if (restrictionValue->second=="no_left_turn" || restrictionValue->second=="no_right_turn" || restrictionValue->second=="no_straight_on" || restrictionValue->second=="no_u_turn") { type=TurnRestriction::Forbit; return true; } return false; }
void OsmXmlEncodeBase::StoreNode(int64_t objId, const class MetaData &metaData, const TagMap &tags, double lat, double lon) { stringstream ss; ss.precision(9); ss << " <node id=\""<<objId<<"\""; this->EncodeMetaData(metaData, ss); ss << fixed << " lat=\""<<lat<<"\" lon=\""<<lon<<"\""; if(tags.size() == 0) ss <<" />" << endl; else { ss <<">" << endl; //Write tags for(TagMap::const_iterator it=tags.begin(); it!=tags.end(); it++) { ss << " <tag k=\""<<escapexml(it->first)<<"\" v=\""<<escapexml(it->second)<<"\" />" << endl; } ss << " </node>" << endl; } *this << ss.str(); }
void OsmXmlEncodeBase::StoreWay(int64_t objId, const class MetaData &metaData, const TagMap &tags, const std::vector<int64_t> &refs) { stringstream ss; ss << " <way id=\""<<objId<<"\""; this->EncodeMetaData(metaData, ss); if(tags.size() == 0 && refs.size() == 0) ss <<" />" << endl; else { ss <<">" << endl; //Write node IDs for(size_t i=0; i<refs.size(); i++) ss << " <nd ref=\""<<refs[i]<<"\" />" << endl; //Write tags for(TagMap::const_iterator it=tags.begin(); it!=tags.end(); it++) ss << " <tag k=\""<<escapexml(it->first)<<"\" v=\""<<escapexml(it->second)<<"\" />" << endl; ss << " </way>" << endl; } *this << ss.str(); }
void O5mEncodeBase::StoreWay(int64_t objId, const class MetaData &metaData, const TagMap &tags, const std::vector<int64_t> &refs) { this->write("\x11", 1); //Object ID std::stringstream tmpStream; int64_t deltaId = objId - this->lastObjId; tmpStream << EncodeZigzag(deltaId); this->lastObjId = objId; //Store meta data this->EncodeMetaData(metaData, tmpStream); //Store nodes std::stringstream refStream; for(size_t i=0; i< refs.size(); i++) { int64_t ref = refs[i]; int64_t deltaRef = ref - this->lastRefNode; refStream << EncodeZigzag(deltaRef); this->lastRefNode = ref; } std::string encRefs = refStream.str(); tmpStream << EncodeVarint(encRefs.size()); tmpStream << encRefs; //Write tags for (TagMap::const_iterator it=tags.begin(); it != tags.end(); it++) this->WriteStringPair(it->first, it->second, tmpStream); std::string binData = tmpStream.str(); *this << EncodeVarint(binData.size()); *this << binData; }
void OsmXmlEncodeBase::WriteStart(const TagMap &customAttribs) { *this << "<?xml version='1.0' encoding='UTF-8'?>\n"; *this << "<osm"; TagMap::const_iterator it = customAttribs.find("version"); if(it != customAttribs.end()) { *this << " version=\""; *this << escapexml(it->second); *this << "\""; } else *this << " version=\"0.6\""; it = customAttribs.find("generator"); if(it != customAttribs.end()) { *this << " generator=\""; *this << escapexml(it->second); *this << "\""; } else *this << " generator=\"cppo5m\""; for(it = customAttribs.begin(); it != customAttribs.end(); it++) { if(it->first == "version" || it->first == "generator") continue; if(it->second.length() == 0) continue; *this << " "; *this << escapexml(it->first); *this <<"=\""; *this << escapexml(it->second); *this <<"\""; } *this << ">\n"; }
void StartElement(const xmlChar *name, const xmlChar **atts) { if (strcmp((const char*)name,"node")==0) { const xmlChar *idValue=NULL; const xmlChar *latValue=NULL; const xmlChar *lonValue=NULL; context=contextNode; tags.clear(); for (size_t i=0; atts[i]!=NULL && atts[i+1]!=NULL; i+=2) { if (strcmp((const char*)atts[i],"id")==0) { idValue=atts[i+1]; } else if (strcmp((const char*)atts[i],"lat")==0) { latValue=atts[i+1]; } else if (strcmp((const char*)atts[i],"lon")==0) { lonValue=atts[i+1]; } } if (idValue==NULL || lonValue==NULL || latValue==NULL) { std::cerr << "Not all required attributes found" << std::endl; } if (!StringToNumber((const char*)idValue,id)) { std::cerr << "Cannot parse id: '" << idValue << "'" << std::endl; return; } if (!StringToNumber((const char*)latValue,lat)) { std::cerr << "Cannot parse latitude: '" << latValue << "'" << std::endl; return; } if (!StringToNumber((const char*)lonValue,lon)) { std::cerr << "Cannot parse longitude: '" << lonValue << "'" << std::endl; return; } } else if (strcmp((const char*)name,"way")==0) { const xmlChar *idValue=NULL; context=contextWay; nodes.clear(); members.clear(); tags.clear(); for (size_t i=0; atts[i]!=NULL && atts[i+1]!=NULL; i+=2) { if (strcmp((const char*)atts[i],"id")==0) { idValue=atts[i+1]; } } if (!StringToNumber((const char*)idValue,id)) { std::cerr << "Cannot parse id: '" << idValue << "'" << std::endl; return; } } if (strcmp((const char*)name,"relation")==0) { const xmlChar *idValue=NULL; context=contextRelation; tags.clear(); nodes.clear(); members.clear(); for (size_t i=0; atts[i]!=NULL && atts[i+1]!=NULL; i+=2) { if (strcmp((const char*)atts[i],"id")==0) { idValue=atts[i+1]; } } if (!StringToNumber((const char*)idValue,id)) { std::cerr << "Cannot parse id: '" << idValue << "'" << std::endl; return; } } else if (strcmp((const char*)name,"tag")==0) { if (context!=contextWay && context!=contextNode && context!=contextRelation) { return; } const xmlChar *keyValue=NULL; const xmlChar *valueValue=NULL; for (size_t i=0; atts[i]!=NULL && atts[i+1]!=NULL; i+=2) { if (strcmp((const char*)atts[i],"k")==0) { keyValue=atts[i+1]; } else if (strcmp((const char*)atts[i],"v")==0) { valueValue=atts[i+1]; } } if (keyValue==NULL || valueValue==NULL) { std::cerr << "Cannot parse tag, skipping..." << std::endl; return; } TagId id=typeConfig.GetTagId((const char*)keyValue); if (id!=tagIgnore) { tags[id]=(const char*)valueValue; } } else if (strcmp((const char*)name,"nd")==0) { if (context!=contextWay) { return; } OSMId node; const xmlChar *idValue=NULL; for (size_t i=0; atts[i]!=NULL && atts[i+1]!=NULL; i+=2) { if (strcmp((const char*)atts[i],"ref")==0) { idValue=atts[i+1]; } } if (!StringToNumber((const char*)idValue,node)) { std::cerr << "Cannot parse id: '" << idValue << "'" << std::endl; return; } nodes.push_back(node); } else if (strcmp((const char*)name,"member")==0) { if (context!=contextRelation) { return; } RawRelation::Member member; const xmlChar *typeValue=NULL; const xmlChar *refValue=NULL; const xmlChar *roleValue=NULL; for (size_t i=0; atts[i]!=NULL && atts[i+1]!=NULL; i+=2) { if (strcmp((const char*)atts[i],"type")==0) { typeValue=atts[i+1]; } else if (strcmp((const char*)atts[i],"ref")==0) { refValue=atts[i+1]; } else if (strcmp((const char*)atts[i],"role")==0) { roleValue=atts[i+1]; } } if (typeValue==NULL) { std::cerr << "Member of relation " << id << " does not have a type" << std::endl; return; } if (refValue==NULL) { std::cerr << "Member of relation " << id << " does not have a valid reference" << std::endl; return; } if (roleValue==NULL) { std::cerr << "Member of relation " << id << " does not have a valid role" << std::endl; return; } if (strcmp((const char*)typeValue,"node")==0) { member.type=RawRelation::memberNode; } else if (strcmp((const char*)typeValue,"way")==0) { member.type=RawRelation::memberWay; } else if (strcmp((const char*)typeValue,"relation")==0) { member.type=RawRelation::memberRelation; } else { std::cerr << "Cannot parse member type: '" << typeValue << "'" << std::endl; return; } if (!StringToNumber((const char*)refValue,member.id)) { std::cerr << "Cannot parse ref '" << refValue << "' for relation " << id << std::endl; } if (roleValue!=NULL) { member.role=(const char*)roleValue; } members.push_back(member); } }
bool TagsEditor::TransferDataToWindow() { size_t i; TagMap popTagMap; // Disable redrawing until we're done mGrid->BeginBatch(); // Delete all rows if (mGrid->GetNumberRows()) { mGrid->DeleteRows(0, mGrid->GetNumberRows()); } // Populate the static rows for (i = 0; i < STATICCNT; i++) { mGrid->AppendRows(); mGrid->SetReadOnly(i, 0); // The special tag name that's displayed and translated may not match // the key string used for internal lookup. mGrid->SetCellValue(i, 0, wxGetTranslation( labelmap[i].label ) ); mGrid->SetCellValue(i, 1, mLocal.GetTag(labelmap[i].name)); if (!mEditTitle && mGrid->GetCellValue(i, 0).CmpNoCase(wxGetTranslation(LABEL_TITLE)) == 0) { mGrid->SetReadOnly(i, 1); } if (!mEditTrack && mGrid->GetCellValue(i, 0).CmpNoCase(wxGetTranslation(LABEL_TRACK)) == 0) { mGrid->SetReadOnly(i, 1); } popTagMap[ labelmap[i].name ] = mGrid->GetCellValue(i, 1); } // Populate the rest for (const auto &pair : mLocal.GetRange()) { const auto &n = pair.first; const auto &v = pair.second; if (popTagMap.find(n) == popTagMap.end()) { mGrid->AppendRows(); mGrid->SetCellValue(i, 0, n); mGrid->SetCellValue(i, 1, v); i++; } } // Add an extra one to help with initial sizing and to show it can be done mGrid->AppendRows(1); // We're done, so allow the grid to redraw mGrid->EndBatch(); // Set the editors SetEditors(); Layout(); Fit(); return true; }
bool TagExistsCondition::Evaluate(const TagMap& tagMap) const { return tagMap.find(tag)!=tagMap.end(); }
void O5mEncodeBase::StoreRelation(int64_t objId, const class MetaData &metaData, const TagMap &tags, const std::vector<std::string> &refTypeStrs, const std::vector<int64_t> &refIds, const std::vector<std::string> &refRoles) { if(refTypeStrs.size() != refIds.size() || refTypeStrs.size() != refRoles.size()) throw std::invalid_argument("Length of ref vectors must be equal"); this->write("\x12", 1); //Object ID std::stringstream tmpStream; int64_t deltaId = objId - this->lastObjId; tmpStream << EncodeZigzag(deltaId); this->lastObjId = objId; //Store meta data this->EncodeMetaData(metaData, tmpStream); //Store referenced children std::stringstream refStream; for(size_t i=0; i<refTypeStrs.size(); i++) { const std::string &typeStr = refTypeStrs[i]; int64_t refId = refIds[i]; const std::string &role = refRoles[i]; char typeCode[2] = "0"; int64_t deltaRef = 0; if(typeStr == "node") { typeCode[0] = '0'; deltaRef = refId - this->lastRefNode; this->lastRefNode = refId; } if(typeStr == "way") { typeCode[0] = '1'; deltaRef = refId - this->lastRefWay; this->lastRefWay = refId; } if(typeStr == "relation") { typeCode[0] = '2'; deltaRef = refId - this->lastRefRelation; this->lastRefRelation = refId; } refStream << EncodeZigzag(deltaRef); std::string typeCodeAndRole(typeCode); typeCodeAndRole.append(role); bool indexFound = false; size_t refIndex = this->FindStringPairsIndex(typeCodeAndRole, indexFound); if(indexFound) { refStream << EncodeVarint(refIndex); } else { refStream.write("\x00", 1); //String start byte refStream << typeCodeAndRole; refStream.write("\x00", 1); //String end byte if(typeCodeAndRole.size() <= this->refTableLengthThreshold) this->AddToRefTable(typeCodeAndRole); } } std::string encRefs = refStream.str(); tmpStream << EncodeVarint(encRefs.size()); tmpStream << encRefs; //Write tags for (TagMap::const_iterator it=tags.begin(); it != tags.end(); it++) this->WriteStringPair(it->first, it->second, tmpStream); std::string binData = tmpStream.str(); *this << EncodeVarint(binData.size()); *this << binData; }
bool TagBinaryCondition::Evaluate(const TagMap& tagMap) const { auto t=tagMap.find(tag); if (t==tagMap.end()) { return false; } if (valueType==string) { switch (binaryOperator) { case operatorLess: return t->second<tagStringValue; case operatorLessEqual: return t->second<=tagStringValue; case operatorEqual: return t->second==tagStringValue; case operatorNotEqual: return t->second!=tagStringValue; case operatorGreaterEqual: return t->second>=tagStringValue; case operatorGreater: return t->second>tagStringValue; default: assert(false); return false; } } else if (valueType==sizet) { size_t value; if (!StringToNumber(t->second, value)) { return false; } switch (binaryOperator) { case operatorLess: return value<tagSizeValue; case operatorLessEqual: return value<=tagSizeValue; case operatorEqual: return value==tagSizeValue; case operatorNotEqual: return value!=tagSizeValue; case operatorGreaterEqual: return value>=tagSizeValue; case operatorGreater: return value>tagSizeValue; default: assert(false); return false; } } else { assert(false); return false; } }
void Preprocess::Callback::ProcessWay(const OSMId& id, std::vector<OSMId>& nodes, const TagMap& tagMap) { TypeInfoRef areaType; TypeInfoRef wayType; int isArea=0; // 0==unknown, 1==true, -1==false bool isCoastlineArea=false; RawWay way; bool isCoastline=false; if (nodes.size()<2) { progress.Warning("Way "+ NumberToString(id)+ " has less than two nodes!"); return; } if (id<lastWayId) { waySortingError=true; } way.SetId(id); auto areaTag=tagMap.find(typeConfig->tagArea); if (areaTag==tagMap.end()) { isArea=0; } else if (areaTag->second=="no" || areaTag->second=="false" || areaTag->second=="0") { isArea=-1; } else { isArea=1; } auto naturalTag=tagMap.find(typeConfig->tagNatural); if (naturalTag!=tagMap.end() && naturalTag->second=="coastline") { isCoastline=true; } if (isCoastline) { isCoastlineArea=nodes.size()>3 && (nodes.front()==nodes.back() || isArea==1); } typeConfig->GetWayAreaType(tagMap, wayType, areaType); if (isArea==1 && areaType==typeConfig->typeInfoIgnore) { isArea=0; } else if (isArea==-1 && wayType==typeConfig->typeInfoIgnore) { isArea=0; } if (isArea==0) { if (wayType!=typeConfig->typeInfoIgnore && areaType==typeConfig->typeInfoIgnore) { isArea=-1; } else if (wayType==typeConfig->typeInfoIgnore && areaType!=typeConfig->typeInfoIgnore) { isArea=1; } else if (wayType!=typeConfig->typeInfoIgnore && areaType!=typeConfig->typeInfoIgnore) { if (nodes.size()>3 && nodes.front()==nodes.back()) { if (wayType->GetPinWay()) { isArea=-1; } else { isArea=1; } } else { isArea=-1; } } } switch (isArea) { case 1: areaStat[areaType->GetIndex()]++; if (areaType->GetIgnore()) { way.SetType(typeConfig->typeInfoIgnore, true); } else { way.SetType(areaType,true); } if (nodes.size()>3 && nodes.front()==nodes.back()) { nodes.pop_back(); } areaCount++; break; case -1: wayStat[wayType->GetIndex()]++; if (wayType->GetIgnore()) { way.SetType(typeConfig->typeInfoIgnore,false); } else { way.SetType(wayType,false); } wayCount++; break; default: if (nodes.size()>3 && nodes.front()==nodes.back()) { areaStat[typeIgnore]++; way.SetType(typeConfig->typeInfoIgnore, true); nodes.pop_back(); areaCount++; } else { wayStat[typeIgnore]++; way.SetType(typeConfig->typeInfoIgnore, false); wayCount++; } } way.SetNodes(nodes); way.Parse(progress, *typeConfig, tagMap); way.Write(*typeConfig, wayWriter); lastWayId=id; if (isCoastline) { RawCoastline coastline; coastline.SetId(way.GetId()); coastline.SetType(isCoastlineArea); coastline.SetNodes(way.GetNodes()); coastline.Write(coastlineWriter); coastlineCount++; } }