code: public MapReadResult readPoiData(Tile upperLeft, Tile lowerRight) {
          if (upperLeft.tileX > lowerRight.tileX || upperLeft.tileY > lowerRight.tileY) {
              new IllegalArgumentException("upperLeft tile must be above and left of lowerRight tile");
          }
          MapReadResult result = new MapReadResult();
          for (int x = upperLeft.tileX; x <= lowerRight.tileX; x++) {
              for (int y = upperLeft.tileY; y <= lowerRight.tileY; y++) {
                  Tile current = new Tile(x, y, upperLeft.zoomLevel, upperLeft.tileSize);
                  result.add(readPoiData(current), false);
              }
          }
          return result;
      }
docs: Reads POI data for an area defined by the tile in the upper left and the tile in
  the lower right corner. The default implementation combines the results from
  all tiles, a possibly inefficient solution.
  Precondition: upperLeft.tileX <= lowerRight.tileX && upperLeft.tileY <= lowerRight.tileY
  
  @param upperLeft  tile that defines the upper left corner of the requested area.
  @param lowerRight tile that defines the lower right corner of the requested area.
  @return map data for the tile.