protected void downloadTile(final Tile tile, DownloadPostProcessor postProcessor) {
    if (!this.isNetworkRetrievalEnabled()) return;

    if (!WorldWind.getRetrievalService().isAvailable()) return;

    java.net.URL url;
    try {
      url = tile.getRequestURL();
      if (WorldWind.getNetworkStatus().isHostUnavailable(url)) return;
    } catch (java.net.MalformedURLException e) {
      Logging.logger()
          .log(
              java.util.logging.Level.SEVERE,
              Logging.getMessage("layers.PlaceNameLayer.ExceptionCreatingUrl", tile),
              e);
      return;
    }

    Retriever retriever;

    if ("http".equalsIgnoreCase(url.getProtocol()) || "https".equalsIgnoreCase(url.getProtocol())) {
      if (postProcessor == null) postProcessor = new DownloadPostProcessor(this, tile);
      retriever = new HTTPRetriever(url, postProcessor);
    } else {
      Logging.logger()
          .severe(
              Logging.getMessage("layers.PlaceNameLayer.UnknownRetrievalProtocol", url.toString()));
      return;
    }

    // Apply any overridden timeouts.
    Integer cto = AVListImpl.getIntegerValue(this, AVKey.URL_CONNECT_TIMEOUT);
    if (cto != null && cto > 0) retriever.setConnectTimeout(cto);
    Integer cro = AVListImpl.getIntegerValue(this, AVKey.URL_READ_TIMEOUT);
    if (cro != null && cro > 0) retriever.setReadTimeout(cro);
    Integer srl = AVListImpl.getIntegerValue(this, AVKey.RETRIEVAL_QUEUE_STALE_REQUEST_LIMIT);
    if (srl != null && srl > 0) retriever.setStaleRequestLimit(srl);

    WorldWind.getRetrievalService().runRetriever(retriever, tile.getPriority());
  }
  protected static PlaceNameChunk readTileData(Tile tile, java.net.URL url) {
    java.io.InputStream is = null;

    try {
      String path = url.getFile();
      path =
          path.replaceAll(
              "%20", " "); // TODO: find a better way to get a path usable by FileInputStream

      java.io.FileInputStream fis = new java.io.FileInputStream(path);
      java.io.BufferedInputStream buf = new java.io.BufferedInputStream(fis);
      is = new java.util.zip.GZIPInputStream(buf);

      GMLPlaceNameSAXHandler handler = new GMLPlaceNameSAXHandler();
      javax.xml.parsers.SAXParserFactory.newInstance().newSAXParser().parse(is, handler);
      return handler.createPlaceNameChunk(tile.getPlaceNameService());
    } catch (Exception e) {
      // todo log actual error
      Logging.logger()
          .log(
              Level.FINE,
              Logging.getMessage(
                  "layers.PlaceNameLayer.ExceptionAttemptingToReadFile", url.toString()),
              e);
    } finally {
      try {
        if (is != null) is.close();
      } catch (java.io.IOException e) {
        Logging.logger()
            .log(
                Level.FINE,
                Logging.getMessage(
                    "layers.PlaceNameLayer.ExceptionAttemptingToReadFile", url.toString()),
                e);
      }
    }

    return null;
  }