public String getFullName() {
   if (parent == null) {
     return name;
   } else {
     return parent.getFullName() + "_" + name;
   }
 }
  private void createFile(
      CountryRegion global,
      Map<String, Set<TranslateEntity>> translates,
      Map<String, File> polygonFiles,
      String targetObf,
      String targetOsmXml)
      throws IOException, SQLException, InterruptedException, XmlPullParserException {
    File osm = new File(targetOsmXml);
    XmlSerializer serializer = new org.kxml2.io.KXmlSerializer();
    FileOutputStream fous = new FileOutputStream(osm);
    serializer.setOutput(fous, "UTF-8");
    serializer.startDocument("UTF-8", true);
    serializer.startTag(null, "osm");
    serializer.attribute(null, "version", "0.6");
    serializer.attribute(null, "generator", "OsmAnd");
    serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
    for (CountryRegion r : global.children) {
      r.parent = null;
      processRegion(r, translates, polygonFiles, targetObf, targetOsmXml, "", serializer);
    }
    serializer.endDocument();
    serializer.flush();
    fous.close();

    IndexCreator creator = new IndexCreator(new File(targetObf).getParentFile()); // $NON-NLS-1$
    creator.setMapFileName(new File(targetObf).getName());
    creator.setIndexMap(true);
    creator.setIndexAddress(false);
    creator.setIndexPOI(false);
    creator.setIndexTransport(false);
    creator.setIndexRouting(false);
    MapZooms zooms = MapZooms.parseZooms("5-6");
    creator.generateIndexes(
        osm,
        new ConsoleProgressImplementation(1),
        null,
        zooms,
        new MapRenderingTypesEncoder("regions"),
        log);
  }
  private CountryRegion createRegion(CountryRegion parent, Map<String, String> attrs) {
    CountryRegion reg = new CountryRegion();
    reg.parent = parent;
    if (parent != null) {
      parent.children.add(reg);
    }
    String type = attrs.get("type");
    reg.name = attrs.get("name");
    reg.setDownloadSuffix(attrs.get("download_suffix"));
    reg.setDownloadPrefix(attrs.get("download_prefix"));
    reg.setInnerDownloadSuffix(attrs.get("inner_download_suffix"));
    reg.setInnerDownloadPrefix(attrs.get("inner_download_prefix"));
    for (String tg : CountryRegion.tagsPropagate) {
      reg.additionalTags.put(tg, attrs.get(tg));
    }
    if (attrs.containsKey("hillshade")) {
      reg.hillshade = parseBoolean(attrs.get("hillshade"));
    } else {
      reg.hillshade = type == null || type.equals("hillshade");
    }
    if (attrs.containsKey("srtm")) {
      reg.srtm = parseBoolean(attrs.get("srtm"));
    } else {
      reg.srtm = type == null || type.equals("srtm");
    }
    if (attrs.containsKey("map")) {
      reg.map = parseBoolean(attrs.get("map"));
    } else {
      reg.map = type == null || type.equals("map");
    }

    if (attrs.containsKey("roads")) {
      reg.roads = parseBoolean(attrs.get("roads"));
    } else {
      reg.roads = reg.map;
    }
    if (attrs.containsKey("wiki")) {
      reg.wiki = parseBoolean(attrs.get("wiki"));
    } else {
      reg.wiki = reg.map;
    }
    if (attrs.containsKey("poly_extract")) {
      reg.polyExtract = attrs.get("poly_extract");
    }
    if (attrs.containsKey("translate")) {
      reg.translate = attrs.get("translate").toLowerCase();
      if (reg.translate.equals("no")) {
        reg.translate = null;
      }
    } else {
      reg.translate = "entity=node;" + reg.name.toLowerCase();
    }
    if (attrs.containsKey("boundary")) {
      reg.boundary = attrs.get("boundary");
      if (reg.boundary.equals("no")) {
        reg.boundary = null;
      }
    } else {
      reg.boundary = reg.name;
    }
    return reg;
  }
  private void processRegion(
      CountryRegion r,
      Map<String, Set<TranslateEntity>> translates,
      Map<String, File> polygonFiles,
      String targetObf,
      String targetOsmXml,
      String indent,
      XmlSerializer serializer)
      throws IOException {
    String line = "key=" + r.name;
    File boundary = null;
    if (r.boundary != null) {
      boundary = polygonFiles.get(r.boundary);
      if (boundary == null) {
        System.out.println("!!! Missing boundary " + r.boundary);
      } else {
        line += " boundary=" + boundary.getName();
      }
    }
    List<List<String>> boundaryPoints = Collections.emptyList();
    if (boundary != null) {
      boundaryPoints = readBoundaryPoints(boundary, serializer);
    }
    if (boundaryPoints.size() > 0) {
      // find the biggest with points
      List<String> ls = boundaryPoints.get(0);
      for (int i = 0; i < boundaryPoints.size(); i++) {
        if (ls.size() < boundaryPoints.get(i).size()) {
          ls = boundaryPoints.get(i);
        }
      }
      for (int i = 0; i < boundaryPoints.size(); i++) {
        if (boundaryPoints.get(i) == ls) {
          continue;
        }
        writeWay(serializer, boundaryPoints.get(i));
        addTag(serializer, "osmand_region", "boundary");
        addTag(serializer, "key_name", r.name);
        addTag(serializer, "download_name", r.getDownloadName());
        addTag(serializer, "region_full_name", r.getFullName());
        serializer.endTag(null, "way");
      }
      writeWay(serializer, ls);
    } else {
      serializer.startTag(null, "node");
      serializer.attribute(null, "id", OSM_ID-- + "");
      serializer.attribute(null, "visible", "true");
      serializer.attribute(null, "lat", "0");
      serializer.attribute(null, "lon", "0");
    }
    addTag(serializer, "osmand_region", "yes");
    addTag(serializer, "key_name", r.name);
    addTag(serializer, "region_full_name", r.getFullName());
    if (r.parent != null) {
      addTag(serializer, "region_parent_name", r.parent.getFullName());
    }
    for (String tg : CountryRegion.tagsPropagate) {
      if (!Algorithms.isEmpty(r.getAdditionalTag(tg))) {
        addTag(serializer, "region_" + tg, r.getAdditionalTag(tg));
      }
    }
    if (r.map || r.roads || r.wiki || r.srtm || r.hillshade) {
      line += " download=" + r.getDownloadName();
      addTag(serializer, "download_name", r.getDownloadName());
      addTag(serializer, "region_prefix", r.getDownloadPrefix());
      addTag(
          serializer, "region_suffix", r.getDownloadSuffix()); // add exception for Russia for BW?
      if (r.map) {
        line += " map=yes";
        addTag(serializer, "region_map", "yes");
      }
      if (r.wiki) {
        line += " wiki=yes";
        addTag(serializer, "region_wiki", "yes");
      }
      if (r.roads) {
        line += " roads=yes";
        addTag(serializer, "region_roads", "yes");
      }
      if (r.srtm) {
        line += " srtm=yes";
        addTag(serializer, "region_srtm", "yes");
      }
      if (r.hillshade) {
        line += " hillshade=yes";
        addTag(serializer, "region_hillshade", "yes");
      }
    }
    if (r.translate == null) {
      line += " translate-no=" + Algorithms.capitalizeFirstLetterAndLowercase(r.name);
    } else if (r.translate.startsWith("=")) {
      line += " translate-assign=" + r.translate.substring(1);
    } else {
      String[] tags = r.translate.split(";");
      Set<TranslateEntity> set = null;
      for (String t : tags) {
        if (!t.contains("=")) {
          if (translates.containsKey("name=" + t)) {
            t = "name=" + t;
          } else if (translates.containsKey("name:en=" + t)) {
            t = "name:en=" + t;
          }
        }
        if (set == null) {
          set = translates.get(t);
          if (set == null) {
            break;
          }
        } else {
          Set<TranslateEntity> st2 = translates.get(t);
          if (st2 != null) {
            set = new HashSet<TranslateEntity>(set);
            set.retainAll(st2);
          } else {
            set = null;
            break;
          }
        }
      }
      if (set == null || set.size() == 0) {
        System.out.println("!!! Couldn't find translation name " + r.translate);
      } else if (set.size() > 1) {
        System.out.println("!!! More than 1 translation " + r.translate);
      } else {
        TranslateEntity nt = set.iterator().next();
        line += " translate-" + nt.tm.size() + "=" + nt.tm.get("name");
        Iterator<Entry<String, String>> it = nt.tm.entrySet().iterator();
        while (it.hasNext()) {
          Entry<String, String> e = it.next();
          addTag(serializer, e.getKey(), e.getValue());
        }
      }
    }

    // COMMENT TO SEE ONLY WARNINGS
    System.out.println(indent + line);

    if (boundaryPoints.size() > 0) {
      serializer.endTag(null, "way");
    } else {
      serializer.endTag(null, "node");
    }

    for (CountryRegion c : r.children) {
      processRegion(
          c, translates, polygonFiles, targetObf, targetOsmXml, indent + "  ", serializer);
    }
  }
 public String getDownloadSuffix() {
   if (downloadSuffix == null && parent != null) {
     return parent.getInnerDownloadSuffix();
   }
   return downloadSuffix == null ? "" : downloadSuffix;
 }
 public String getAdditionalTag(String tg) {
   if (!Algorithms.isEmpty(additionalTags.get(tg)) || parent == null) {
     return additionalTags.get(tg);
   }
   return parent.getAdditionalTag(tg);
 }
 public String getPolyExtract() {
   if (!Algorithms.isEmpty(polyExtract) || parent == null) {
     return polyExtract;
   }
   return parent.getPolyExtract();
 }