bool OptimizeAreasLowZoomGenerator::GetAreas(const TypeConfig& typeConfig,
                                               const ImportParameter& parameter,
                                               Progress& progress,
                                               FileScanner& scanner,
                                               const TypeInfoSet& types,
                                               std::vector<std::list<AreaRef> >& areas,
                                               TypeInfoSet& loadedTypes)
  {
    uint32_t    areaCount=0;
    size_t      collectedAreasCount=0;

    loadedTypes=types;

    progress.SetAction("Collecting area data to optimize");

    scanner.GotoBegin();

    scanner.Read(areaCount);

    for (uint32_t a=1; a<=areaCount; a++) {
      AreaRef area=std::make_shared<Area>();

      progress.SetProgress(a,areaCount);

      area->Read(typeConfig,
                 scanner);

      if (loadedTypes.IsSet(area->GetType())) {
        areas[area->GetType()->GetIndex()].push_back(area);

        collectedAreasCount++;

        while (collectedAreasCount>parameter.GetOptimizationMaxWayCount() &&
               loadedTypes.Size()>1) {
          TypeInfoRef victimType;

          for (auto &type : loadedTypes) {
            if (areas[type->GetIndex()].size()>0 &&
                (!victimType ||
                 areas[type->GetIndex()].size()<areas[victimType->GetIndex()].size())) {
              victimType=type;
            }
          }

          assert(victimType);

          collectedAreasCount-=areas[victimType->GetIndex()].size();
          areas[victimType->GetIndex()].clear();
          loadedTypes.Remove(victimType);
        }
      }
    }

    progress.Info("Collected "+NumberToString(collectedAreasCount)+" areas for "+NumberToString(loadedTypes.Size())+" types");

    return !scanner.HasError();
  }
Example #2
0
  void Preprocess::Callback::ProcessMultipolygon(const TagMap& tags,
                                                 const std::vector<RawRelation::Member>& members,
                                                 OSMId id,
                                                 const TypeInfoRef& type)
  {
    RawRelation relation;

    areaStat[type->GetIndex()]++;

    relation.SetId(id);

    if (type->GetIgnore()) {
      relation.SetType(typeConfig->typeInfoIgnore);
    }
    else {
      relation.SetType(type);
    }

    relation.members=members;

    relation.Parse(progress,
                   *typeConfig,
                   tags);
    relation.Write(*typeConfig,
                   multipolygonWriter);

    multipolygonCount++;
  }
Example #3
0
  void AbstractRoutingProfile::AddType(const TypeInfoRef& type,
                                       double speed)
  {
    if (speeds.empty()) {
      minSpeed=speed;
      maxSpeed=speed;
    }
    else {
      minSpeed=std::min(minSpeed,speed);
      maxSpeed=std::max(maxSpeed,speed);
    }

    if (type->GetIndex()>=speeds.size()) {
      speeds.resize(type->GetIndex()+1,0.0);
    }

    speeds[type->GetIndex()]=speed;
  }
Example #4
0
  /**
   * Load areas which has a one for the types given by types. If at leats one node
   * in one of the outer rings of the areas is marked in nodeUseMap as "used at least twice",
   * index it into the areas map.
   *
   * If the number of indexed areas is bigger than parameter.GetRawWayBlockSize() types are
   * dropped form areas until the number is again below the lmit.
   */
  bool MergeAreasGenerator::GetAreas(const ImportParameter& parameter,
                                     Progress& progress,
                                     const TypeConfig& typeConfig,
                                     const TypeInfoSet& candidateTypes,
                                     TypeInfoSet& loadedTypes,
                                     const std::unordered_set<Id>& nodeUseMap,
                                     FileScanner& scanner,
                                     FileWriter& writer,
                                     std::vector<AreaMergeData>& mergeJob,
                                     uint32_t& areasWritten)
  {
    bool        firstCall=areasWritten==0; // We are called for the first time
    uint32_t    areaCount=0;
    size_t      collectedAreasCount=0;
    size_t      typesWithAreas=0;

    for (auto& data : mergeJob) {
      data.areaCount=0;
    }

    loadedTypes=candidateTypes;

    scanner.GotoBegin();

    scanner.Read(areaCount);

    for (uint32_t a=1; a<=areaCount; a++) {
      uint8_t type;
      Id      id;
      AreaRef area=std::make_shared<Area>();

      progress.SetProgress(a,areaCount);

      scanner.Read(type);
      scanner.Read(id);

      area->ReadImport(typeConfig,
                       scanner);

      mergeJob[area->GetType()->GetIndex()].areaCount++;

      // This is an area of a type that does not get merged,
      // we directly store it in the target file.
      if (!loadedTypes.IsSet(area->GetType())) {
        if (firstCall) {
          writer.Write(type);
          writer.Write(id);

          area->WriteImport(typeConfig,
                            writer);

          areasWritten++;
        }

        continue;
      }

      bool isMergeCandidate=false;

      for (const auto& ring: area->rings) {
        if (!ring.IsOuterRing()) {
          continue;
        }

        for (const auto node : ring.nodes) {
          if (nodeUseMap.find(node.GetId())!=nodeUseMap.end()) {
            isMergeCandidate=true;
            break;
          }
        }

        if (isMergeCandidate) {
          break;
        }
      }

      if (!isMergeCandidate) {
        continue;
      }

      if (mergeJob[area->GetType()->GetIndex()].areas.empty()) {
        typesWithAreas++;
      }

      mergeJob[area->GetType()->GetIndex()].areas.push_back(area);

      collectedAreasCount++;

      while (collectedAreasCount>parameter.GetRawWayBlockSize() &&
             typesWithAreas>1) {
        TypeInfoRef victimType;

        // Find the type with the smallest amount of ways loaded
        for (auto &type : loadedTypes) {
          if (!mergeJob[type->GetIndex()].areas.empty() &&
              (!victimType ||
               mergeJob[type->GetIndex()].areas.size()<mergeJob[victimType->GetIndex()].areas.size())) {
            victimType=type;
          }
        }

        // If there is more then one type of way, we always must find a "victim" type.
        assert(victimType);

        // Correct the statistics
        collectedAreasCount-=mergeJob[victimType->GetIndex()].areas.size();
        // Clear already loaded data of th victim type
        mergeJob[victimType->GetIndex()].areas.clear();

        typesWithAreas--;
        loadedTypes.Remove(victimType);
      }
    }

    progress.SetAction("Collected "+NumberToString(collectedAreasCount)+" areas for "+NumberToString(loadedTypes.Size())+" types");

    return true;
  }
Example #5
0
  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++;
    }
  }